completion: add tests showing subpar DWIM logic for switch/checkout

When provided with a single argument that is the name of a remote branch
that does not yet exist locally, both git switch and git checkout can
interpret this as a request to create a local branch that tracks that
remote branch. We call this behavior "Do What I Mean", or DWIM for
short.

To aid in using this DWIM, it makes sense for completion to list these
unique remote branch names when completing possible arguments for git
switch and git checkout. Indeed, both _git_checkout and _git_switch
implement support for completing such DWIM branch names.

In other words, in addition to the usual completions provided for git
switch, this "DWIM" logic means completion will include the names of
branches on remotes that are unique and thus there can be no ambiguity
of which remote to track when creating the local branch.

However, the DWIM logic is not always active. Many options, such as
--no-guess, --no-track, and --track disable this DWIM logic, as they
cause git switch and git checkout to behave in different modes.

Additionally, some completion users do not wish to have tab completion
include these remote names by default, and thus introduced
GIT_COMPLETION_CHECKOUT_NO_GUESS as an optional way to configure the
completion support to disable this feature of completion support.

For this reason, _git_checkout and _git_switch have many rules about
when to enable or disable completing of these remote refs. The two
commands follow similar but not identical rules.

Set aside the question of command modes that do not accept this DWIM
logic (--track, -c, --orphan, --detach) for now. Thinking just about the
main mode of git checkout and git switch, the following guidelines will
help explain the basic rules we ought to support when deciding whether
to list the remote branches for DWIM in completion.

1.  if --guess is enabled, we should list DWIM remote branch names, even
    if something else would disable it
2.  if --no-guess, --no-track or GIT_COMPLETION_CHECKOUT_NO_GUESS=1,
    then we should disable listing DWIM remote branch names.
3.  Since the '--guess' option is a boolean option, a later --guess
    should override --no-guess, and a later --no-guess should override
    --guess.

Putting all of these together, add some tests that highlight the
expected behavior of this DWIM logic.

Signed-off-by: Jacob Keller <jacob.keller@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jacob Keller 2020-05-28 11:10:34 -07:00 коммит произвёл Junio C Hamano
Родитель fab466f91d
Коммит ab58e90f8b
1 изменённых файлов: 105 добавлений и 0 удалений

Просмотреть файл

@ -1263,6 +1263,111 @@ test_expect_success 'git checkout - completes refs and unique remote branches fo
EOF
'
test_expect_success 'git switch - with --no-guess, complete only local branches' '
test_completion "git switch --no-guess " <<-\EOF
master Z
matching-branch Z
EOF
'
test_expect_success 'git switch - with GIT_COMPLETION_CHECKOUT_NO_GUESS=1, complete only local branches' '
GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git switch " <<-\EOF
master Z
matching-branch Z
EOF
'
#TODO: --guess/--no-guess ordering is not taken into account
#TODO: git switch completion includes unexpected references
test_expect_failure 'git switch - --guess overrides GIT_COMPLETION_CHECKOUT_NO_GUESS=1, complete local branches and unique remote names for DWIM logic' '
GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git switch --guess " <<-\EOF
branch-in-other Z
master Z
master-in-other Z
matching-branch Z
EOF
'
#TODO: --guess/--no-guess ordering is not taken into account
#TODO: git switch completion includes unexpected references
test_expect_failure 'git switch - a later --guess overrides previous --no-guess, complete local and remote unique branches for DWIM' '
test_completion "git switch --no-guess --guess " <<-\EOF
branch-in-other Z
master Z
master-in-other Z
matching-branch Z
EOF
'
#TODO: --guess/--no-guess ordering is not taken into account
test_expect_failure 'git switch - a later --no-guess overrides previous --guess, complete only local branches' '
test_completion "git switch --guess --no-guess " <<-\EOF
master Z
matching-branch Z
EOF
'
test_expect_success 'git checkout - with GIT_COMPLETION_NO_GUESS=1 only completes refs' '
GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git checkout " <<-\EOF
HEAD Z
master Z
matching-branch Z
matching-tag Z
other/branch-in-other Z
other/master-in-other Z
EOF
'
#TODO: git checkout does not override variable when --guess is provided
test_expect_failure 'git checkout - --guess overrides GIT_COMPLETION_NO_GUESS=1, complete refs and unique remote branches for DWIM' '
GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git checkout --guess " <<-\EOF
HEAD Z
branch-in-other Z
master Z
master-in-other Z
matching-branch Z
matching-tag Z
other/branch-in-other Z
other/master-in-other Z
EOF
'
test_expect_success 'git checkout - with --no-guess, only completes refs' '
test_completion "git checkout --no-guess " <<-\EOF
HEAD Z
master Z
matching-branch Z
matching-tag Z
other/branch-in-other Z
other/master-in-other Z
EOF
'
#TODO: --guess/--no-guess ordering is not taken into account
test_expect_failure 'git checkout - a later --guess overrides previous --no-guess, complete refs and unique remote branches for DWIM' '
test_completion "git checkout --no-guess --guess " <<-\EOF
HEAD Z
branch-in-other Z
master Z
master-in-other Z
matching-branch Z
matching-tag Z
other/branch-in-other Z
other/master-in-other Z
EOF
'
test_expect_success 'git checkout - a later --no-guess overrides previous --guess, complete only refs' '
test_completion "git checkout --guess --no-guess " <<-\EOF
HEAD Z
master Z
matching-branch Z
matching-tag Z
other/branch-in-other Z
other/master-in-other Z
EOF
'
test_expect_success 'teardown after ref completion' '
git branch -d matching-branch &&
git tag -d matching-tag &&