]> git.ipfire.org Git - thirdparty/git.git/commitdiff
completion: improve handling of --track in switch/checkout
authorJacob Keller <jacob.keller@gmail.com>
Thu, 28 May 2020 18:10:46 +0000 (11:10 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 28 May 2020 19:57:07 +0000 (12:57 -0700)
Current completion for the --track option of git switch and git checkout
is sub par. In addition to the DWIM logic of a bare branch name, --track
has DWIM logic to convert specified remote/branch names into a local
branch tracking that remote. For example

  $git switch --track origin/master

This will create a local branch name master, that tracks the master
branch of the origin remote.

In fact, git switch --track on its own will not accept other forms of
references. These must instead be specified manually via the -c/-C/-b/-B
options.

Introduce __git_remote_heads() and the "remote-heads" mode for
__git_complete_refs. Use this when the --track option is provided while
completing in _git_switch and _git_checkout. Just as in the --detach
case, we never enable DWIM mode for --track, because it doesn't make
sense.

It should be noted that completion support is still a bit sub par when
it comes to handling -c/-C and --orphan. This will be resolved in
a future change.

Signed-off-by: Jacob Keller <jacob.keller@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
contrib/completion/git-completion.bash
t/t9902-completion.sh

index 56480371ffba090ba21fec668c45dbe1672f0778..e520dda35eca5dbfee380093497d39a67fc58369 100644 (file)
@@ -624,6 +624,19 @@ __git_heads ()
                        "refs/heads/$cur_*" "refs/heads/$cur_*/**"
 }
 
+# Lists branches from remote repositories.
+# 1: A prefix to be added to each listed branch (optional).
+# 2: List only branches matching this word (optional; list all branches if
+#    unset or empty).
+# 3: A suffix to be appended to each listed branch (optional).
+__git_remote_heads ()
+{
+       local pfx="${1-}" cur_="${2-}" sfx="${3-}"
+
+       __git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \
+                       "refs/remotes/$cur_*" "refs/remotes/$cur_*/**"
+}
+
 # Lists tags from the local repository.
 # Accepts the same positional parameters as __git_heads() above.
 __git_tags ()
@@ -783,8 +796,9 @@ __git_refs ()
 # --sfx=<suffix>: A suffix to be appended to each ref instead of the default
 #                 space.
 # --mode=<mode>: What set of refs to complete, one of 'refs' (the default) to
-#                complete all refs, 'heads' to complete only branches. Note
-#                that --remote is only compatible with --mode=refs.
+#                complete all refs, 'heads' to complete only branches, or
+#                'remote-heads' to complete only remote branches. Note that
+#                --remote is only compatible with --mode=refs.
 __git_complete_refs ()
 {
        local remote dwim pfx cur_="$cur" sfx=" " mode="refs"
@@ -810,6 +824,8 @@ __git_complete_refs ()
                        __gitcomp_direct "$(__git_refs "$remote" "" "$pfx" "$cur_" "$sfx")" ;;
                heads)
                        __gitcomp_direct "$(__git_heads "$pfx" "$cur_" "$sfx")" ;;
+               remote-heads)
+                       __gitcomp_direct "$(__git_remote_heads "$pfx" "$cur_" "$sfx")" ;;
                *)
                        return 1 ;;
        esac
@@ -1492,6 +1508,8 @@ _git_checkout ()
 
                if [ -n "$(__git_find_on_cmdline "-d --detach")" ]; then
                        __git_complete_refs --mode="refs"
+               elif [ -n "$(__git_find_on_cmdline "--track")" ]; then
+                       __git_complete_refs --mode="remote-heads"
                else
                        __git_complete_refs $dwim_opt --mode="refs"
                fi
@@ -2346,6 +2364,8 @@ _git_switch ()
 
                if [ -n "$(__git_find_on_cmdline "-d --detach")" ]; then
                        __git_complete_refs --mode="refs"
+               elif [ -n "$(__git_find_on_cmdline "--track")" ]; then
+                       __git_complete_refs --mode="remote-heads"
                else
                        __git_complete_refs $dwim_opt --mode="heads"
                fi
index 25d530a8b9c93aaa2c58de6ef3c677be24a0975f..227732688974e517b67e10bf8d2498164077fd3f 100755 (executable)
@@ -1404,16 +1404,14 @@ test_expect_success 'git checkout - with -d, complete only references' '
        EOF
 '
 
-#TODO: --track should only complete fully specified remote branches
-test_expect_failure 'git switch - with --track, complete only remote branches' '
+test_expect_success 'git switch - with --track, complete only remote branches' '
        test_completion "git switch --track " <<-\EOF
        other/branch-in-other Z
        other/master-in-other Z
        EOF
 '
 
-#TODO: --track should only complete fully specified remote branches
-test_expect_failure 'git checkout - with --track, complete only remote branches' '
+test_expect_success 'git checkout - with --track, complete only remote branches' '
        test_completion "git checkout --track " <<-\EOF
        other/branch-in-other Z
        other/master-in-other Z