Skip to content

git-jump: pick a mode automatically when invoked without arguments#2108

Open
wincent wants to merge 1 commit into
gitgitgadget:masterfrom
wincent:auto-jump
Open

git-jump: pick a mode automatically when invoked without arguments#2108
wincent wants to merge 1 commit into
gitgitgadget:masterfrom
wincent:auto-jump

Conversation

@wincent
Copy link
Copy Markdown

@wincent wincent commented May 8, 2026

cc: Jeff King peff@peff.net
cc: "Greg Hurrell" greg@hurrell.net
cc: Erik Cervin Edin erik@cervined.in

When `git jump` is invoked with no positional arguments (and no
arguments after `--stdout`) it currently prints usage and exits with
status 1.

But there are two situations where we can usefully infer the most
valuable and likely mode that a user would want to use, and select it
automatically when they run `git jump` without arguments:

1. When there are unmerged paths in the index, the user likely
   wants `git jump merge`.

2. When the working tree has unstaged changes, the user likely
   wants `git jump diff`.

Detect these two cases and dispatch to the corresponding mode
automatically, falling back to the existing usage-and-exit behavior
when neither holds.

Signed-off-by: Greg Hurrell <greg.hurrell@datadoghq.com>
@wincent
Copy link
Copy Markdown
Author

wincent commented May 8, 2026

/preview

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 8, 2026

Preview email sent as pull.2108.git.1778230925932.gitgitgadget@gmail.com

@wincent
Copy link
Copy Markdown
Author

wincent commented May 8, 2026

/submit

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 8, 2026

Submitted as pull.2108.git.1778231254871.gitgitgadget@gmail.com

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git/ pr-2108/wincent/auto-jump-v1

To fetch this version to local tag pr-2108/wincent/auto-jump-v1:

git fetch --no-tags https://github.com/gitgitgadget/git/ tag pr-2108/wincent/auto-jump-v1

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 8, 2026

Jeff King wrote on the Git mailing list (how to reply to this email):

On Fri, May 08, 2026 at 09:07:34AM +0000, Greg Hurrell via GitGitGadget wrote:

> From: Greg Hurrell <greg.hurrell@datadoghq.com>
> 
> When `git jump` is invoked with no positional arguments (and no
> arguments after `--stdout`) it currently prints usage and exits with
> status 1.
> 
> But there are two situations where we can usefully infer the most
> valuable and likely mode that a user would want to use, and select it
> automatically when they run `git jump` without arguments:
> 
> 1. When there are unmerged paths in the index, the user likely
>    wants `git jump merge`.
> 
> 2. When the working tree has unstaged changes, the user likely
>    wants `git jump diff`.
> 
> Detect these two cases and dispatch to the corresponding mode
> automatically, falling back to the existing usage-and-exit behavior
> when neither holds.

OK, I guess this saves a little bit of typing. I never really thought
about it because I long ago aliased the various invocations in my shell
("git jump diff" in particular is so useful that it is just "d" in my
shell).

I'd be a little worried that it is more confusing to somebody
approaching the command for the first time and just runs "git jump" to
not see usage or other guidance. But that might be overly paranoid.

Would having "git jump auto" work for you? I.e., are you primarily
trying to avoid the mental effort of selecting the command, or the
finger effort of typing it?

>  if test $# -lt 1; then
> -	usage >&2
> -	exit 1
> +	if test "$(git rev-parse --is-inside-work-tree 2>/dev/null)" != "true"; then
> +		usage >&2
> +		exit 1
> +	fi
> +	if test -n "$(git ls-files -u)"; then
> +		set -- merge
> +	elif ! git diff --quiet; then
> +		set -- diff
> +	else
> +		usage >&2
> +		exit 1
> +	fi

The implementation looks reasonable. In theory we could save a diff
invocation by trying diff mode and reporting whether it found anything.
But the --quiet invocation is not too expensive, and avoiding it is
probably not worth the gymnastics required.

-Peff

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 8, 2026

"Greg Hurrell" wrote on the Git mailing list (how to reply to this email):

On Fri, May 8, 2026, at 4:13 PM, Jeff King wrote:
> On Fri, May 08, 2026 at 09:07:34AM +0000, Greg Hurrell via GitGitGadget wrote:
> 
> I'd be a little worried that it is more confusing to somebody
> approaching the command for the first time and just runs "git jump" to
> not see usage or other guidance. But that might be overly paranoid.

Hopefully, they at least read the README before installing it from contrib/
(although Homebrew recently starting installing it for folks automatically,
so may not remain true for much longer on macOS...)
 
> Would having "git jump auto" work for you? I.e., are you primarily
> trying to avoid the mental effort of selecting the command, or the
> finger effort of typing it?

It's mostly the finger effort of typing it because I generally know exactly
which mode I want; eg.

- I'm in the middle of a rebase, and hit a conflict; 100% of the time,
  I want to explore the conflicts, so I want `git jump` to do `git jump
  merge`.

- I have unstaged changes, and I want to make some tweaks before committing;
  so I want `git jump` to do `git jump diff`.

- Otherwise, I'm wanting to search for something (ie. `git jump grep`),
  so by definition I'm going to be doing some extra typing anyway (ie.
  `git jump grep <pattern>`).

This is muscle memory for me at this point, because I've had a `git jump`
alias for this in my dotfiles[^1] for a couple of years. Homebrew
installing `git-jump` by default a few months ago[^2] broke this, because
aliases can't shadow builtin commands.

[^1]: https://github.com/wincent/wincent/commit/99183f86fe35
[^2]: https://github.com/Homebrew/homebrew-core/commit/e9fc066240f2

Best wishes,
Greg

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 8, 2026

User "Greg Hurrell" <greg@hurrell.net> has been added to the cc: list.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 8, 2026

Jeff King wrote on the Git mailing list (how to reply to this email):

On Fri, May 08, 2026 at 04:30:36PM +0200, Greg Hurrell wrote:

> On Fri, May 8, 2026, at 4:13 PM, Jeff King wrote:
> > On Fri, May 08, 2026 at 09:07:34AM +0000, Greg Hurrell via GitGitGadget wrote:
> > 
> > I'd be a little worried that it is more confusing to somebody
> > approaching the command for the first time and just runs "git jump" to
> > not see usage or other guidance. But that might be overly paranoid.
> 
> Hopefully, they at least read the README before installing it from contrib/
> (although Homebrew recently starting installing it for folks automatically,
> so may not remain true for much longer on macOS...)

Yeah, I'd hope so. And even if it might be more discoverable, I'm not
sure that is more important than being convenient for experienced users.

I guess a config option would be possible, but probably not worth it for
something as trivial as git-jump.

> It's mostly the finger effort of typing it because I generally know exactly
> which mode I want; eg.

OK, that makes sense.

> This is muscle memory for me at this point, because I've had a `git jump`
> alias for this in my dotfiles[^1] for a couple of years. Homebrew
> installing `git-jump` by default a few months ago[^2] broke this, because
> aliases can't shadow builtin commands.

Ah, yeah, that is frustrating. We try to avoid aliases overrides to
prevent confusion, but for an add-on tool like git-jump I think it is
overly cautious. It might be reasonable to limit that protection only to
commands in Git's exec-path, but I haven't thought hard about it. And I
think it should be considered separately from this patch anyway.

So yeah, your patch looks good to me. Thanks.

-Peff

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 14, 2026

Erik Cervin Edin wrote on the Git mailing list (how to reply to this email):

On 26/05/08 04:30PM, Greg Hurrell wrote:
> Hopefully, they at least read the README before installing it from contrib/
> (although Homebrew recently starting installing it for folks automatically,
> so may not remain true for much longer on macOS...)

Oh! I didn't know that but looking closer on my homebrew installed Git,
looks like you're right.

I would've assumed that if users had jumped through the hoops of
installing git-jump from contrib/ it stands to reason they would have
some sense of what it does. But if this is landing as a part of regular
brew install git, I'd wager there's a few unsuspecting people running
git-jump that don't know what it does.

> Would having "git jump auto" work for you?

Imo, this sounds ideal -- there's something odd about `git jump` picking
the subcommand heuristically. At least when I invoke git-jump I always
do so with a specific intent of _where_ I want to jump. Then again, I
never do a jump merge or a jump ws.

> Homebrew installing `git-jump` by default a few months ago[^2] broke
> this, because aliases can't shadow builtin commands.

But it looks like this doesn't work in this case. Even if you have
git-jump installed stand-alone (mine is in ~/bin/git-jump, in PATH,
before /opt/homebrew/bin.)

FWIW I alias jump to j, jump diff to jd and jump grep to jg. E.g.

    git jd # git jump diff

On 26/05/08 09:07AM, Greg Hurrell via GitGitGadget wrote:
> -usage: git jump [--stdout] <mode> [<args>]
> +usage: git jump [--stdout] [<mode>] [<args>]

The usage message makes <mode> optional but doesn't explain what
happens when you omit it. Seems worth documenting the auto-detect behavior
there too.

> But there are two situations where we can usefully infer the most
> valuable and likely mode that a user would want to use, and select it
> automatically when they run `git jump` without arguments:
>
> 1. When there are unmerged paths in the index, the user likely
>    wants `git jump merge`.
>
> 2. When the working tree has unstaged changes, the user likely
>    wants `git jump diff`.

I can think of a third situation -- when there are staged changes flagged by
git diff --cached --check.

If we're going to teach git-jump how to be more clever about where to jump,
does it also make sense to bake `git jump ws` into this?

Also, if this is going to grow into a proper auto-detect heuristic, it
might be cleaner as a first-class mode rather than logic spliced into the
argument parser. Something like:

    mode_auto() {
        if test -n "$(git ls-files -u)"; then
            mode_merge "$@"
        elif ! git diff --quiet; then
            mode_diff "$@"
        elif ! git diff --cached --check >/dev/null 2>&1; then
            mode_ws --cached "$@"
        else
            return 0
        fi
    }

That way `git jump auto` works explicitly, bare `git jump` defaults
to it (just `set -- auto` when $# -lt 1), and the usage text can
document the heuristic. It also keeps the detection and dispatch in
one place in case someone wants to tweak the priority later.

All in all, I think an auto jumping mode could be genuinely useful.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 14, 2026

User Erik Cervin Edin <erik@cervined.in> has been added to the cc: list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant