{"thread":{"id":"53562","subject":"[PATCH v2 0/9] refactor completion for switch and checkout","startedAt":"2020-05-27T11:38:37Z","lastAt":"2020-05-28T08:53:29Z","messageCount":13,"participants":["Jacob Keller","Junio C Hamano"],"isPatch":true,"patchVersion":2,"patchTotal":9},"messages":[{"id":"398625","messageId":"20200527113831.3294409-1-jacob.e.keller@intel.com","threadId":"53562","inReplyTo":null,"subject":"[PATCH v2 0/9] refactor completion for switch and checkout","fromName":"Jacob Keller","fromEmail":"jacob.e.keller@intel.com","sentAt":"2020-05-27T11:38:22Z","receivedAt":"2020-05-27T11:38:37Z","isPatch":true,"sender":{"key":"jacob.e.keller@intel.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"From: Jacob Keller <jacob.keller@gmail.com>\n\ncompletion support for git switch is subpar for a number of cases. Most\nnotable is difference in behavior between these two completions:\n\n  $git switch <TAB>\n  Display all 784 possibilities? (y or n)\n  <list of all references and DWIM remotes>\n\n  $git switch --track<TAB>\n  jk-refactor-git-switch-completion master`\n\nIf --track is provided, tab completion becomes almost useless, because we\nwould expect to complete remote references, but instead can only complete\nlocal branches!\n\nThis series was motivated by a desire to fix the completion for the above\ntwo cases, but I noticed several other issues on the way, including some\nissues understanding what the current logic did.\n\nThis series aims to improve the completion support, and comes with many\nadditional test cases that cover the new behavior implemented in the various\npatches.\n\nThis is a rework of a previous series posted, available at the following URL:\nhttps://lore.kernel.org/git/20200425022045.1089291-1-jacob.e.keller@intel.com/\n\nNote that although I've marked this as a v2, I did not find the range-diff\nto be satisfying or useful and have not included it. Besides not being very\nuseful, not many folks seem to have reviewed the original anyways.\n\nThe most notable change in behavior since v1 is how we handle the -c/-C\noptions. It makes sense to complete the argument of -c differently than how\nwe handle the start-point after we already have a completed branch name. The\nexact requirements of *how* we complete branch names is easily modified if\nanyone has a better suggestion.\n\nFinally, I also applied many of the same improvements to checkout where\nappropriate, and have included many more additional tests for both git\nswitch and git checkout.\n\nJacob Keller (9):\n  completion: replace overloaded track term for __git_complete_refs\n  completion: improve handling of DWIM mode for switch/checkout\n  completion: extract function __git_dwim_remote_heads\n  completion: perform DWIM logic directly in __git_complete_refs\n  completion: improve completion for git switch with no options\n  completion: improve handling of --detach in checkout\n  completion: improve handling of --track in switch/checkout\n  completion: improve handling of -c/-C and -b/-B in switch/checkout\n  completion: improve handling of --orphan option of switch/checkout\n\n contrib/completion/git-completion.bash | 252 +++++++++++---\n t/t9902-completion.sh                  | 455 +++++++++++++++++++++++++\n 2 files changed, 668 insertions(+), 39 deletions(-)\n\n-- \n2.25.2\n\n"},{"id":"398626","messageId":"20200527113831.3294409-5-jacob.e.keller@intel.com","threadId":"53562","inReplyTo":"20200527113831.3294409-1-jacob.e.keller@intel.com","subject":"[PATCH v2 4/9] completion: perform DWIM logic directly in __git_complete_refs","fromName":"Jacob Keller","fromEmail":"jacob.e.keller@intel.com","sentAt":"2020-05-27T11:38:26Z","receivedAt":"2020-05-27T11:38:40Z","isPatch":true,"sender":{"key":"jacob.e.keller@intel.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"From: Jacob Keller <jacob.keller@gmail.com>\n\n__git_complete_refs is the main function used for completing references.\nIt is primarily used as a wrapper around __git_refs, and is easier to\nextend since its arguments are option-like.\n\nOne major downside of __git_complete_refs and __git_refs currently, is\nthe lack of ability to complete only a subset of refs such as branches\n(refs/heads) or tags (refs/tags).\n\nNormally, a caller might just decide to use __git_heads() or\n__git_tags(). However, in the case of git-switch, it is useful to\ncomplete both branches *and* DWIM remote branch names.\n\nDue to the complexity and implementation of __git_refs, it is not easy\nto extend it to support listing only a subset of references.\n\nInstead, we can extend __git_complete_refs to do this. For this to be\ndone, we must first ensure that \"--dwim\" support is not tied to calling\n__git_refs.\n\nInstead of passing $dwim into __git_refs, we can implement\na __gitcomp_direct_append function which can append to COMPREPLY after\na call to __gitcomp_direct.\n\nIf --dwim is passed to __git_complete_refs, use __gitcomp_direct_append\nto add the output of __git_dwim_remote_heads to the completion list.\n\nIn this way, --dwim support is now independent of calling __git_refs.\n\nA future change will add an additional option to control what set of\nreferences __git_complete_refs will output.\n\nSigned-off-by: Jacob Keller <jacob.keller@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n contrib/completion/git-completion.bash | 19 ++++++++++++++++++-\n 1 file changed, 18 insertions(+), 1 deletion(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 8854812cb32e..54cd676fdc9d 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -301,6 +301,19 @@ __gitcomp_direct ()\n \tCOMPREPLY=($1)\n }\n \n+# Similar to __gitcomp_direct, but appends to COMPREPLY instead.\n+# Callers must take care of providing only words that match the current word\n+# to be completed and adding any prefix and/or suffix (trailing space!), if\n+# necessary.\n+# 1: List of newline-separated matching completion words, complete with\n+#    prefix and suffix.\n+__gitcomp_direct_append ()\n+{\n+\tlocal IFS=$'\\n'\n+\n+\tCOMPREPLY+=($1)\n+}\n+\n __gitcompappend ()\n {\n \tlocal x i=${#COMPREPLY[@]}\n@@ -787,7 +800,11 @@ __git_complete_refs ()\n \t\tshift\n \tdone\n \n-\t__gitcomp_direct \"$(__git_refs \"$remote\" \"$dwim\" \"$pfx\" \"$cur_\" \"$sfx\")\"\n+\t__gitcomp_direct \"$(__git_refs \"$remote\" \"\" \"$pfx\" \"$cur_\" \"$sfx\")\"\n+\n+\tif [ \"$dwim\" = \"yes\" ]; then\n+\t\t__gitcomp_direct_append \"$(__git_dwim_remote_heads \"$pfx\" \"$cur_\" \"$sfx\")\"\n+\tfi\n }\n \n # __git_refs2 requires 1 argument (to pass to __git_refs)\n-- \n2.25.2\n\n"},{"id":"398627","messageId":"20200527113831.3294409-10-jacob.e.keller@intel.com","threadId":"53562","inReplyTo":"20200527113831.3294409-1-jacob.e.keller@intel.com","subject":"[PATCH v2 9/9] completion: improve handling of --orphan option of switch/checkout","fromName":"Jacob Keller","fromEmail":"jacob.e.keller@intel.com","sentAt":"2020-05-27T11:38:31Z","receivedAt":"2020-05-27T11:38:42Z","isPatch":true,"sender":{"key":"jacob.e.keller@intel.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"From: Jacob Keller <jacob.keller@gmail.com>\n\nThe --orphan option is used to create a local branch which is detached\nfrom the current history. In git switch, it always resets to the empty\ntree, and thus the only completion we can provide is a branch name.\nFollow the same rules for -c/-C (and -b/-B) when completing the argument\nto --orphan.\n\nIn the case of git switch, after we complete the argument, there is\nnothing more we can complete for git switch, so do not even try. Nothing\nelse would be valid.\n\nIn the case of git checkout, --orphan takes a start point which it uses\nto determine the checked out tree, even though it created orphaned\nhistory.\n\nAdd test cases which cover this completion behavior.\n\nSigned-off-by: Jacob Keller <jacob.keller@gmail.com>\n---\n contrib/completion/git-completion.bash | 21 ++++++++++------\n t/t9902-completion.sh                  | 35 ++++++++++++++++++++++++++\n 2 files changed, 49 insertions(+), 7 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 60666429dba4..de85b84f8116 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -1508,7 +1508,7 @@ _git_checkout ()\n \t\tlocal prevword prevword=\"${words[cword-1]}\"\n \n \t\tcase \"$prevword\" in\n-\t\t\t-b|-B)\n+\t\t\t-b|-B|--orphan)\n \t\t\t\t# Complete local branches (and DWIM branch\n \t\t\t\t# remote branch names) for an option argument\n \t\t\t\t# specifying a new branch name. This is for\n@@ -1522,14 +1522,14 @@ _git_checkout ()\n \t\tesac\n \n \t\t# At this point, we've already handled special completion for\n-\t\t# the arguments to -b/-B. There are 3 main things left we can\n-\t\t# possibly complete:\n-\t\t# 1) a start-point for -b/-B or -d/--detach\n+\t\t# the arguments to -b/-B, and --orphan. There are 3 main\n+\t\t# things left we can possibly complete:\n+\t\t# 1) a start-point for -b/-B, -d/--detach, or --orphan\n \t\t# 2) a remote head, for --track\n \t\t# 3) an arbitrary reference, possibly including DWIM names\n \t\t#\n \n-\t\tif [ -n \"$(__git_find_on_cmdline \"-b -B -d --detach\")\" ]; then\n+\t\tif [ -n \"$(__git_find_on_cmdline \"-b -B -d --detach --orphan\")\" ]; then\n \t\t\t__git_complete_refs --mode=\"refs\"\n \t\telif [ -n \"$(__git_find_on_cmdline \"--track\")\" ]; then\n \t\t\t__git_complete_refs --mode=\"remote-heads\"\n@@ -2388,7 +2388,7 @@ _git_switch ()\n \t\tlocal prevword prevword=\"${words[cword-1]}\"\n \n \t\tcase \"$prevword\" in\n-\t\t\t-c|-C)\n+\t\t\t-c|-C|--orphan)\n \t\t\t\t# Complete local branches (and DWIM branch\n \t\t\t\t# remote branch names) for an option argument\n \t\t\t\t# specifying a new branch name. This is for\n@@ -2401,8 +2401,15 @@ _git_switch ()\n \t\t\t\t;;\n \t\tesac\n \n+\t\t# Unlike in git checkout, git switch --orphan does not take\n+\t\t# a start point. Thus we really have nothing to complete after\n+\t\t# the branch name.\n+\t\tif [ -n \"$(__git_find_on_cmdline \"--orphan\")\" ]; then\n+\t\t\treturn\n+\t\tfi\n+\n \t\t# At this point, we've already handled special completion for\n-\t\t# -c/-C. There are 3 main things left to\n+\t\t# -c/-C, and --orphan. There are 3 main things left to\n \t\t# complete:\n \t\t# 1) a start-point for -c/-C or -d/--detach\n \t\t# 2) a remote head, for --track\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 14ebd175dfa5..8f434a0931e5 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1660,6 +1660,41 @@ test_expect_success 'git checkout - for -B with --no-track, complete local branc\n \tEOF\n '\n \n+test_expect_success 'git switch - with --orphan completes local branch names and unique remote branch names' '\n+\ttest_completion \"git switch --orphan \" <<-\\EOF\n+\tbranch-in-other Z\n+\tmaster Z\n+\tmaster-in-other Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - --orphan with branch already provided completes nothing else' '\n+\ttest_completion \"git switch --orphan master \" <<-\\EOF\n+\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with --orphan completes local branch names and unique remote branch names' '\n+\ttest_completion \"git checkout --orphan \" <<-\\EOF\n+\tbranch-in-other Z\n+\tmaster Z\n+\tmaster-in-other Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - --orphan with branch already provided completes local refs for a start-point' '\n+\ttest_completion \"git checkout --orphan master \" <<-\\EOF\n+\tHEAD Z\n+\tmaster Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n test_expect_success 'teardown after ref completion' '\n \tgit branch -d matching-branch &&\n \tgit tag -d matching-tag &&\n-- \n2.25.2\n\n"},{"id":"398628","messageId":"20200527113831.3294409-9-jacob.e.keller@intel.com","threadId":"53562","inReplyTo":"20200527113831.3294409-1-jacob.e.keller@intel.com","subject":"[PATCH v2 8/9] completion: improve handling of -c/-C and -b/-B in switch/checkout","fromName":"Jacob Keller","fromEmail":"jacob.e.keller@intel.com","sentAt":"2020-05-27T11:38:30Z","receivedAt":"2020-05-27T11:38:43Z","isPatch":true,"sender":{"key":"jacob.e.keller@intel.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"From: Jacob Keller <jacob.keller@gmail.com>\n\nCurrently, completion for git switch and git checkout do not take into\naccount the branch creation options, -c/-C and -b/-B respectively.\n\nThe form of git switch with -c or -C is to take a branch name followed\nby a starting point. For this reason, when completing -c or -C, we ought\nto be able to complete the start point as any arbitrary reference.\n\nHowever, we probably do not want to complete the actual argument for\nthese options with any reference, as this would provide too many\nunexpected items.\n\nUse the wordlist to determine the previous word on the command line. If\nit's -c or -C (-b/-B for checkout), then we know that we are completing\nthe argument for the branch name. One possible assumption is that we\nhave no valid completion. But consider that in many cases a user may\nwish to complete a branch by editing the name of a pre-existing branch.\n\nGiven that a user who already knows the branch name they want to\ncomplete will simply not use completion, it makes sense to complete the\nsmall subset of local branches when completing the argument for -c/-C.\n\nIn all other cases, if -c/-C are on the command line but are not the\nmost recent option, then we must be completing a start-point, and should\nallow completing against all references.\n\nAdd many tests to cover various behavior and interaction around enabling\nor disabling DWIM mode.\n\nSigned-off-by: Jacob Keller <jacob.keller@gmail.com>\n---\n contrib/completion/git-completion.bash |  49 +++++-\n t/t9902-completion.sh                  | 224 +++++++++++++++++++++++++\n 2 files changed, 271 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 4cdf09987725..60666429dba4 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -1505,8 +1505,31 @@ _git_checkout ()\n \t\t;;\n \t*)\n \t\tlocal dwim_opt=\"$(__git_checkout_default_dwim_mode)\"\n+\t\tlocal prevword prevword=\"${words[cword-1]}\"\n \n-\t\tif [ -n \"$(__git_find_on_cmdline \"-d --detach\")\" ]; then\n+\t\tcase \"$prevword\" in\n+\t\t\t-b|-B)\n+\t\t\t\t# Complete local branches (and DWIM branch\n+\t\t\t\t# remote branch names) for an option argument\n+\t\t\t\t# specifying a new branch name. This is for\n+\t\t\t\t# convenience, assuming new branches are\n+\t\t\t\t# possibly based on pre-existing branch names.\n+\t\t\t\t__git_complete_refs $dwim_opt --mode=\"heads\"\n+\t\t\t\treturn\n+\t\t\t\t;;\n+\t\t\t*)\n+\t\t\t\t;;\n+\t\tesac\n+\n+\t\t# At this point, we've already handled special completion for\n+\t\t# the arguments to -b/-B. There are 3 main things left we can\n+\t\t# possibly complete:\n+\t\t# 1) a start-point for -b/-B or -d/--detach\n+\t\t# 2) a remote head, for --track\n+\t\t# 3) an arbitrary reference, possibly including DWIM names\n+\t\t#\n+\n+\t\tif [ -n \"$(__git_find_on_cmdline \"-b -B -d --detach\")\" ]; then\n \t\t\t__git_complete_refs --mode=\"refs\"\n \t\telif [ -n \"$(__git_find_on_cmdline \"--track\")\" ]; then\n \t\t\t__git_complete_refs --mode=\"remote-heads\"\n@@ -2362,8 +2385,30 @@ _git_switch ()\n \t\t;;\n \t*)\n \t\tlocal dwim_opt=\"$(__git_checkout_default_dwim_mode)\"\n+\t\tlocal prevword prevword=\"${words[cword-1]}\"\n \n-\t\tif [ -n \"$(__git_find_on_cmdline \"-d --detach\")\" ]; then\n+\t\tcase \"$prevword\" in\n+\t\t\t-c|-C)\n+\t\t\t\t# Complete local branches (and DWIM branch\n+\t\t\t\t# remote branch names) for an option argument\n+\t\t\t\t# specifying a new branch name. This is for\n+\t\t\t\t# convenience, assuming new branches are\n+\t\t\t\t# possibly based on pre-existing branch names.\n+\t\t\t\t__git_complete_refs $dwim_opt --mode=\"heads\"\n+\t\t\t\treturn\n+\t\t\t\t;;\n+\t\t\t*)\n+\t\t\t\t;;\n+\t\tesac\n+\n+\t\t# At this point, we've already handled special completion for\n+\t\t# -c/-C. There are 3 main things left to\n+\t\t# complete:\n+\t\t# 1) a start-point for -c/-C or -d/--detach\n+\t\t# 2) a remote head, for --track\n+\t\t# 3) a branch name, possibly including DWIM remote branches\n+\n+\t\tif [ -n \"$(__git_find_on_cmdline \"-c -C -d --detach\")\" ]; then\n \t\t\t__git_complete_refs --mode=\"refs\"\n \t\telif [ -n \"$(__git_find_on_cmdline \"--track\")\" ]; then\n \t\t\t__git_complete_refs --mode=\"remote-heads\"\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex b09eb498d175..14ebd175dfa5 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1436,6 +1436,230 @@ test_expect_success 'git checkout - with --no-track, complete only local referen\n \tEOF\n '\n \n+test_expect_success 'git switch - with -c, complete all references' '\n+\ttest_completion \"git switch -c new-branch \" <<-\\EOF\n+\tHEAD Z\n+\tmaster Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - with -C, complete all references' '\n+\ttest_completion \"git switch -C new-branch \" <<-\\EOF\n+\tHEAD Z\n+\tmaster Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - with -c and --track, complete all references' '\n+\ttest_completion \"git switch -c new-branch --track \" <<-EOF\n+\tHEAD Z\n+\tmaster Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - with -C and --track, complete all references' '\n+\ttest_completion \"git switch -C new-branch --track \" <<-EOF\n+\tHEAD Z\n+\tmaster Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - with -c and --no-track, complete all references' '\n+\ttest_completion \"git switch -c new-branch --no-track \" <<-\\EOF\n+\tHEAD Z\n+\tmaster Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - with -C and --no-track, complete all references' '\n+\ttest_completion \"git switch -C new-branch --no-track \" <<-\\EOF\n+\tHEAD Z\n+\tmaster Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with -b, complete all references' '\n+\ttest_completion \"git checkout -b new-branch \" <<-\\EOF\n+\tHEAD Z\n+\tmaster Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with -B, complete all references' '\n+\ttest_completion \"git checkout -B new-branch \" <<-\\EOF\n+\tHEAD Z\n+\tmaster Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with -b and --track, complete all references' '\n+\ttest_completion \"git checkout -b new-branch --track \" <<-EOF\n+\tHEAD Z\n+\tmaster Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with -B and --track, complete all references' '\n+\ttest_completion \"git checkout -B new-branch --track \" <<-EOF\n+\tHEAD Z\n+\tmaster Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with -b and --no-track, complete all references' '\n+\ttest_completion \"git checkout -b new-branch --no-track \" <<-\\EOF\n+\tHEAD Z\n+\tmaster Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with -B and --no-track, complete all references' '\n+\ttest_completion \"git checkout -B new-branch --no-track \" <<-\\EOF\n+\tHEAD Z\n+\tmaster Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - for -c, complete local branches and unique remote branches' '\n+\ttest_completion \"git switch -c \" <<-\\EOF\n+\tbranch-in-other Z\n+\tmaster Z\n+\tmaster-in-other Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - for -C, complete local branches and unique remote branches' '\n+\ttest_completion \"git switch -C \" <<-\\EOF\n+\tbranch-in-other Z\n+\tmaster Z\n+\tmaster-in-other Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - for -c with --no-guess, complete local branches only' '\n+\ttest_completion \"git switch --no-guess -c \" <<-\\EOF\n+\tmaster Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - for -C with --no-guess, complete local branches only' '\n+\ttest_completion \"git switch --no-guess -C \" <<-\\EOF\n+\tmaster Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - for -c with --no-track, complete local branches only' '\n+\ttest_completion \"git switch --no-track -c \" <<-\\EOF\n+\tmaster Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - for -C with --no-track, complete local branches only' '\n+\ttest_completion \"git switch --no-track -C \" <<-\\EOF\n+\tmaster Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - for -b, complete local branches and unique remote branches' '\n+\ttest_completion \"git checkout -b \" <<-\\EOF\n+\tbranch-in-other Z\n+\tmaster Z\n+\tmaster-in-other Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - for -B, complete local branches and unique remote branches' '\n+\ttest_completion \"git checkout -B \" <<-\\EOF\n+\tbranch-in-other Z\n+\tmaster Z\n+\tmaster-in-other Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - for -b with --no-guess, complete local branches only' '\n+\ttest_completion \"git checkout --no-guess -b \" <<-\\EOF\n+\tmaster Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - for -B with --no-guess, complete local branches only' '\n+\ttest_completion \"git checkout --no-guess -B \" <<-\\EOF\n+\tmaster Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - for -b with --no-track, complete local branches only' '\n+\ttest_completion \"git checkout --no-track -b \" <<-\\EOF\n+\tmaster Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - for -B with --no-track, complete local branches only' '\n+\ttest_completion \"git checkout --no-track -B \" <<-\\EOF\n+\tmaster Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n test_expect_success 'teardown after ref completion' '\n \tgit branch -d matching-branch &&\n \tgit tag -d matching-tag &&\n-- \n2.25.2\n\n"},{"id":"398629","messageId":"20200527113831.3294409-4-jacob.e.keller@intel.com","threadId":"53562","inReplyTo":"20200527113831.3294409-1-jacob.e.keller@intel.com","subject":"[PATCH v2 3/9] completion: extract function __git_dwim_remote_heads","fromName":"Jacob Keller","fromEmail":"jacob.e.keller@intel.com","sentAt":"2020-05-27T11:38:25Z","receivedAt":"2020-05-27T11:38:44Z","isPatch":true,"sender":{"key":"jacob.e.keller@intel.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"From: Jacob Keller <jacob.keller@gmail.com>\n\n__git_refs() has the ability to report unique remote names for\nsupporting completion of remote branch names for the DWIMery of git\ncheckout and git switch.\n\nFor git checkout, this is fine, because it always supports completing\nall local references.\n\nHowever, git switch by default only supports either switching branches\nor using this DWIMery to create a local branch tracking the remote\nbranch.\n\nFuture work to cleanup and improve completion support for git switch\nwill be aided if the remote branch names can be completed separately\nfrom __git_refs.\n\nExtract this logic to a function __git_dwim_remote_heads(), and use it\nin __git_refs.\n\nSigned-off-by: Jacob Keller <jacob.keller@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n contrib/completion/git-completion.bash | 28 +++++++++++++++++++-------\n 1 file changed, 21 insertions(+), 7 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex ed966f5e2991..8854812cb32e 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -621,6 +621,26 @@ __git_tags ()\n \t\t\t\"refs/tags/$cur_*\" \"refs/tags/$cur_*/**\"\n }\n \n+# List unique branches from refs/remotes used for 'git checkout' and 'git\n+# switch' tracking DWIMery.\n+# 1: A prefix to be added to each listed branch (optional)\n+# 2: List only branches matching this word (optional; list all branches if\n+#    unset or empty).\n+# 3: A suffix to be appended to each listed branch (optional).\n+__git_dwim_remote_heads ()\n+{\n+\tlocal pfx=\"${1-}\" cur_=\"${2-}\" sfx=\"${3-}\"\n+\tlocal fer_pfx=\"${pfx//\\%/%%}\" # \"escape\" for-each-ref format specifiers\n+\n+\t# employ the heuristic used by git checkout and git switch\n+\t# Try to find a remote branch that cur_es the completion word\n+\t# but only output if the branch name is unique\n+\t__git for-each-ref --format=\"$fer_pfx%(refname:strip=3)$sfx\" \\\n+\t\t--sort=\"refname:strip=3\" \\\n+\t\t\"refs/remotes/*/$cur_*\" \"refs/remotes/*/$cur_*/**\" | \\\n+\tuniq -u\n+}\n+\n # Lists refs from the local (by default) or from a remote repository.\n # It accepts 0, 1 or 2 arguments:\n # 1: The remote to list refs from (optional; ignored, if set but empty).\n@@ -696,13 +716,7 @@ __git_refs ()\n \t\t__git_dir=\"$dir\" __git for-each-ref --format=\"$fer_pfx%($format)$sfx\" \\\n \t\t\t\"${refs[@]}\"\n \t\tif [ -n \"$track\" ]; then\n-\t\t\t# employ the heuristic used by git checkout\n-\t\t\t# Try to find a remote branch that matches the completion word\n-\t\t\t# but only output if the branch name is unique\n-\t\t\t__git for-each-ref --format=\"$fer_pfx%(refname:strip=3)$sfx\" \\\n-\t\t\t\t--sort=\"refname:strip=3\" \\\n-\t\t\t\t\"refs/remotes/*/$match*\" \"refs/remotes/*/$match*/**\" | \\\n-\t\t\tuniq -u\n+\t\t\t__git_dwim_remote_heads \"$pfx\" \"$match\" \"$sfx\"\n \t\tfi\n \t\treturn\n \tfi\n-- \n2.25.2\n\n"},{"id":"398630","messageId":"20200527113831.3294409-7-jacob.e.keller@intel.com","threadId":"53562","inReplyTo":"20200527113831.3294409-1-jacob.e.keller@intel.com","subject":"[PATCH v2 6/9] completion: improve handling of --detach in checkout","fromName":"Jacob Keller","fromEmail":"jacob.e.keller@intel.com","sentAt":"2020-05-27T11:38:28Z","receivedAt":"2020-05-27T11:38:48Z","isPatch":true,"sender":{"key":"jacob.e.keller@intel.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"From: Jacob Keller <jacob.keller@gmail.com>\n\nJust like git switch, we should not complete DWIM remote branch names\nif --detach has been specified. To avoid this, refactor _git_checkout in\na similar way to _git_switch.\n\nNote that we don't simply clear dwim_opt when we find -d or --detach, as\nwe will be adding other modes and checks, making this flow easier to\nfollow.\n\nAdd new tests for the expected --detach behavior for both git switch and\ngit checkout.\n\nSigned-off-by: Jacob Keller <jacob.keller@gmail.com>\n---\n contrib/completion/git-completion.bash |  7 +++-\n t/t9902-completion.sh                  | 44 ++++++++++++++++++++++++++\n 2 files changed, 50 insertions(+), 1 deletion(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 53afd72d0e4e..38b5a5a0d874 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -1489,7 +1489,12 @@ _git_checkout ()\n \t\t;;\n \t*)\n \t\tlocal dwim_opt=\"$(__git_checkout_default_dwim_mode)\"\n-\t\t__git_complete_refs $dwim_opt\n+\n+\t\tif [ -n \"$(__git_find_on_cmdline \"-d --detach\")\" ]; then\n+\t\t\t__git_complete_refs --mode=\"refs\"\n+\t\telse\n+\t\t\t__git_complete_refs $dwim_opt --mode=\"refs\"\n+\t\tfi\n \t\t;;\n \tesac\n }\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex ec9437688cd7..5b1868e43632 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1360,6 +1360,50 @@ test_expect_success 'git checkout - a later --no-guess overrides previous --gues\n \tEOF\n '\n \n+test_expect_success 'git switch - with --detach, complete all references' '\n+\ttest_completion \"git switch --detach \" <<-\\EOF\n+\tHEAD Z\n+\tmaster Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with --detach, complete only references' '\n+\ttest_completion \"git checkout --detach \" <<-\\EOF\n+\tHEAD Z\n+\tmaster Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - with -d, complete all references' '\n+\ttest_completion \"git switch -d \" <<-\\EOF\n+\tHEAD Z\n+\tmaster Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with -d, complete only references' '\n+\ttest_completion \"git checkout -d \" <<-\\EOF\n+\tHEAD Z\n+\tmaster Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n test_expect_success 'teardown after ref completion' '\n \tgit branch -d matching-branch &&\n \tgit tag -d matching-tag &&\n-- \n2.25.2\n\n"},{"id":"398631","messageId":"20200527113831.3294409-3-jacob.e.keller@intel.com","threadId":"53562","inReplyTo":"20200527113831.3294409-1-jacob.e.keller@intel.com","subject":"[PATCH v2 2/9] completion: improve handling of DWIM mode for switch/checkout","fromName":"Jacob Keller","fromEmail":"jacob.e.keller@intel.com","sentAt":"2020-05-27T11:38:24Z","receivedAt":"2020-05-27T11:38:49Z","isPatch":true,"sender":{"key":"jacob.e.keller@intel.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"From: Jacob Keller <jacob.keller@gmail.com>\n\nBoth git switch and git checkout can \"Do What I Mean\" by interpreting\na name of unique remote branch as \"please create and switch to a local\nbranch named after and tracking this remote branch\".\n\nCompletion supports this DWIM mode by allowing to complete these unique\nremote branch names. The current logic for when we decide to enable this\nDWIM mode is not consistent between git checkout and git switch.\n\nIn both cases, this logic is enabled by default. Then, if any of\n'--track', '--no-track', or '--no-guess' are provided on the command\nline, then we disable it. Additionally, this logic is disabled when\nGIT_COMPLETION_CHECKOUT_NO_GUESS is set to 1. For _git_switch, we also\nunconditionally enable this logic if \"--guess\" is provided on the\ncommand line.\n\nThe rules for when to enable or disable DWIM have gotten quite\ncomplicated, so its time to refactor these into a function,\n__git_checkout_default_dwim_mode().\n\nFirst, the default is to enable DWIM logic. Then, if '--no-track' is\nprovided or if the GIT_COMPLETION_CHECKOUT_NO_GUESS variable is set, we\nchange to default to disabled.\n\nA new helper, __git_find_last_on_cmdline is introduced, similar to the\nalready existing __git_find_on_cmdline, but which operates in reverse,\nfinding the *last* matching word of the provided wordlist.\n\nThis is then used to find the last --guess or --no-guess. In this way,\nif --guess was last specified (and thus git option parsing will think\n--guess is enabled), we will unconditionally enable DWIM mode. If\n--no-guess is provided last, then we will unconditionally disable DWIM\nmode. Finally, if neither are specified, we use the default.\n\nThis new logic is more robust, as we will correctly identify superseded\noptions, and ensure that both _git_switch and _git_checkout enable DWIM\nin similar ways.\n\nAdd several tests which demonstrate the new expected behavior. Note that\nsome of the git switch tests are marked as failures because the default\ngit switch completion with --guess is sub-par as discussed in a previous\ncommit. This will be fixed in a future change.\n\nSigned-off-by: Jacob Keller <jacob.keller@gmail.com>\n---\n contrib/completion/git-completion.bash | 95 ++++++++++++++++++++-----\n t/t9902-completion.sh                  | 98 ++++++++++++++++++++++++++\n 2 files changed, 174 insertions(+), 19 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 2972df4cb4c9..ed966f5e2991 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -1104,6 +1104,40 @@ __git_find_on_cmdline ()\n \tdone\n }\n \n+# Similar to __git_find_on_cmdline, except that it loops backwards and thus\n+# prints the *last* word found. Useful for finding which of two options that\n+# supersede each other came last, such as \"--guess\" and \"--no-guess\".\n+#\n+# Usage: __git_find_last_on_cmdline [<option>]... \"<wordlist>\"\n+# --show-idx: Optionally show the index of the found word in the $words array.\n+__git_find_last_on_cmdline ()\n+{\n+\tlocal word c=$cword show_idx\n+\n+\twhile test $# -gt 1; do\n+\t\tcase \"$1\" in\n+\t\t--show-idx)\tshow_idx=y ;;\n+\t\t*)\t\treturn 1 ;;\n+\t\tesac\n+\t\tshift\n+\tdone\n+\tlocal wordlist=\"$1\"\n+\n+\twhile [ $c -gt 1 ]; do\n+\t\t((c--))\n+\t\tfor word in $wordlist; do\n+\t\t\tif [ \"$word\" = \"${words[c]}\" ]; then\n+\t\t\t\tif [ -n \"$show_idx\" ]; then\n+\t\t\t\t\techo \"$c $word\"\n+\t\t\t\telse\n+\t\t\t\t\techo \"$word\"\n+\t\t\t\tfi\n+\t\t\t\treturn\n+\t\t\tfi\n+\t\tdone\n+\tdone\n+}\n+\n # Echo the value of an option set on the command line or config\n #\n # $1: short option name\n@@ -1358,6 +1392,46 @@ _git_bundle ()\n \tesac\n }\n \n+# Helper function to decide whether or not we should enable DWIM logic for\n+# git-switch and git-checkout.\n+#\n+# To decide between the following rules in priority order\n+# 1) the last provided of \"--guess\" or \"--no-guess\" explicitly enable or\n+#    disable completion of DWIM logic respectively.\n+# 2) If the --no-track option is provided, take this as a hint to disable the\n+#    DWIM completion logic\n+# 3) If GIT_COMPLETION_CHECKOUT_NO_GUESS is set, disable the DWIM completion\n+#    logic, as requested by the user.\n+# 4) Enable DWIM logic otherwise.\n+#\n+__git_checkout_default_dwim_mode ()\n+{\n+\tlocal last_option dwim_opt=\"--dwim\"\n+\n+\tif [ \"$GIT_COMPLETION_CHECKOUT_NO_GUESS\" = \"1\" ]; then\n+\t\tdwim_opt=\"\"\n+\tfi\n+\n+\t# --no-track disables DWIM, but with lower priority than\n+\t# --guess/--no-guess\n+\tif [ -n \"$(__git_find_on_cmdline \"--no-track\")\" ]; then\n+\t\tdwim_opt=\"\"\n+\tfi\n+\n+\t# Find the last provided --guess or --no-guess\n+\tlast_option=\"$(__git_find_last_on_cmdline \"--guess --no-guess\")\"\n+\tcase \"$last_option\" in\n+\t\t--guess)\n+\t\t\tdwim_opt=\"--dwim\"\n+\t\t\t;;\n+\t\t--no-guess)\n+\t\t\tdwim_opt=\"\"\n+\t\t\t;;\n+\tesac\n+\n+\techo \"$dwim_opt\"\n+}\n+\n _git_checkout ()\n {\n \t__git_has_doubledash && return\n@@ -1370,13 +1444,7 @@ _git_checkout ()\n \t\t__gitcomp_builtin checkout\n \t\t;;\n \t*)\n-\t\t# check if --track, --no-track, or --no-guess was specified\n-\t\t# if so, disable DWIM mode\n-\t\tlocal flags=\"--track --no-track --no-guess\" dwim_opt=\"--dwim\"\n-\t\tif [ \"$GIT_COMPLETION_CHECKOUT_NO_GUESS\" = \"1\" ] ||\n-\t\t   [ -n \"$(__git_find_on_cmdline \"$flags\")\" ]; then\n-\t\t\tdwim_opt=''\n-\t\tfi\n+\t\tlocal dwim_opt=\"$(__git_checkout_default_dwim_mode)\"\n \t\t__git_complete_refs $dwim_opt\n \t\t;;\n \tesac\n@@ -2226,18 +2294,7 @@ _git_switch ()\n \t\t__gitcomp_builtin switch\n \t\t;;\n \t*)\n-\t\t# check if --track, --no-track, or --no-guess was specified\n-\t\t# if so, disable DWIM mode\n-\t\tlocal dwim_opt=\"--dwim\" only_local_ref=n\n-\t\tif [ \"$GIT_COMPLETION_CHECKOUT_NO_GUESS\" = \"1\" ] ||\n-\t\t   [ -n \"$(__git_find_on_cmdline \"--track --no-track --no-guess\")\" ]; then\n-\t\t\tdwim_opt=''\n-\t\tfi\n-\t\t# explicit --guess enables DWIM mode regardless of\n-\t\t# $GIT_COMPLETION_CHECKOUT_NO_GUESS\n-\t\tif [ -n \"$(__git_find_on_cmdline \"--guess\")\" ]; then\n-\t\t\tdwim_opt='--dwim'\n-\t\tfi\n+\t\tlocal dwim_opt=\"$(__git_checkout_default_dwim_mode)\" only_local_ref=n\n \t\tif [ -z \"$(__git_find_on_cmdline \"-d --detach\")\" ]; then\n \t\t\tonly_local_ref=y\n \t\telse\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 3c44af694015..6d90d19d9fe5 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1240,6 +1240,104 @@ test_expect_success '__git_complete_fetch_refspecs - fully qualified & prefix' '\n \ttest_cmp expected out\n '\n \n+test_expect_success 'git switch - with --no-guess, complete only local branches' '\n+\ttest_completion \"git switch --no-guess \" <<-\\EOF\n+\tmaster Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - with GIT_COMPLETION_CHECKOUT_NO_GUESS=1, complete only local branches' '\n+\tGIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion \"git switch \" <<-\\EOF\n+\tmaster Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_failure 'git switch - --guess overrides GIT_COMPLETION_CHECKOUT_NO_GUESS=1, complete local branches and unique remote names for DWIM logic' '\n+\tGIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion \"git switch --guess \" <<-\\EOF\n+\tbranch-in-other Z\n+\tmaster Z\n+\tmaster-in-other Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_failure 'git switch - a later --guess overrides previous --no-guess, complete local and remote unique branches for DWIM' '\n+\ttest_completion \"git switch --no-guess --guess \" <<-\\EOF\n+\tbranch-in-other Z\n+\tmaster Z\n+\tmaster-in-other Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - a later --no-guess overrides previous --guess, complete only local branches' '\n+\ttest_completion \"git switch --guess --no-guess \" <<-\\EOF\n+\tmaster Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with GIT_COMPLETION_NO_GUESS=1 only completes refs' '\n+\tGIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion \"git checkout \" <<-\\EOF\n+\tHEAD Z\n+\tmaster Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - --guess overrides GIT_COMPLETION_NO_GUESS=1, complete refs and unique remote branches for DWIM' '\n+\tGIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion \"git checkout --guess \" <<-\\EOF\n+\tHEAD Z\n+\tbranch-in-other Z\n+\tmaster Z\n+\tmaster-in-other Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with --no-guess, only completes refs' '\n+\ttest_completion \"git checkout --no-guess \" <<-\\EOF\n+\tHEAD Z\n+\tmaster Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - a later --guess overrides previous --no-guess, complete refs and unique remote branches for DWIM' '\n+\ttest_completion \"git checkout --no-guess --guess \" <<-\\EOF\n+\tHEAD Z\n+\tbranch-in-other Z\n+\tmaster Z\n+\tmaster-in-other Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - a later --no-guess overrides previous --guess, complete only refs' '\n+\ttest_completion \"git checkout --guess --no-guess \" <<-\\EOF\n+\tHEAD Z\n+\tmaster Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n test_expect_success 'teardown after ref completion' '\n \tgit branch -d matching-branch &&\n \tgit tag -d matching-tag &&\n-- \n2.25.2\n\n"},{"id":"398632","messageId":"20200527113831.3294409-2-jacob.e.keller@intel.com","threadId":"53562","inReplyTo":"20200527113831.3294409-1-jacob.e.keller@intel.com","subject":"[PATCH v2 1/9] completion: replace overloaded track term for __git_complete_refs","fromName":"Jacob Keller","fromEmail":"jacob.e.keller@intel.com","sentAt":"2020-05-27T11:38:23Z","receivedAt":"2020-05-27T11:38:50Z","isPatch":true,"sender":{"key":"jacob.e.keller@intel.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"From: Jacob Keller <jacob.keller@gmail.com>\n\nThe __git_complete_refs uses the \"--track\" option to specify when to\nenable listing of unique remote branches which are used by the DWIM\nlogic of git checkout and git switch.\n\nUsing the term '--track' here is confusing because the git commands\nthemselves have '--track' as an argument. Additionally, the completion\nlogic for _git_switch also checks for --track. Keeping the meaning of\ntrack_opt and --track for __git_complete_refs straight from the --track\ngit switch and git checkout option is difficult when reading this code.\n\nUse the option '--dwim' instead, indicating this is about enabling or\ndisabling logic related to DWIM mode. Also rename the local variable\ntrack_opt to dwim_opt to further reduce the confusion when reading the\ncompletion code for _git_switch.\n\nBecause it is plausible for users to have developed their own\ncompletions which rely on __git_complete_ref, keep --track as a synonym\nfor --dwim, even though we no longer use it in any of the core git\ncompletion logic. Add a comment explaining why it remains as an\nalternative spelling for --dwim.\n\nSigned-off-by: Jacob Keller <jacob.keller@gmail.com>\n---\n contrib/completion/git-completion.bash | 28 ++++++++++++++------------\n 1 file changed, 15 insertions(+), 13 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 70ad04e1b2a8..2972df4cb4c9 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -749,7 +749,7 @@ __git_refs ()\n # Usage: __git_complete_refs [<option>]...\n # --remote=<remote>: The remote to list refs from, can be the name of a\n #                    configured remote, a path, or a URL.\n-# --track: List unique remote branches for 'git checkout's tracking DWIMery.\n+# --dwim: List unique remote branches for 'git switch's tracking DWIMery.\n # --pfx=<prefix>: A prefix to be added to each ref.\n # --cur=<word>: The current ref to be completed.  Defaults to the current\n #               word to be completed.\n@@ -757,12 +757,14 @@ __git_refs ()\n #                 space.\n __git_complete_refs ()\n {\n-\tlocal remote track pfx cur_=\"$cur\" sfx=\" \"\n+\tlocal remote dwim pfx cur_=\"$cur\" sfx=\" \"\n \n \twhile test $# != 0; do\n \t\tcase \"$1\" in\n \t\t--remote=*)\tremote=\"${1##--remote=}\" ;;\n-\t\t--track)\ttrack=\"yes\" ;;\n+\t\t--dwim)\t\tdwim=\"yes\" ;;\n+\t\t# --track is an old spelling of --dwim\n+\t\t--track)\tdwim=\"yes\" ;;\n \t\t--pfx=*)\tpfx=\"${1##--pfx=}\" ;;\n \t\t--cur=*)\tcur_=\"${1##--cur=}\" ;;\n \t\t--sfx=*)\tsfx=\"${1##--sfx=}\" ;;\n@@ -771,7 +773,7 @@ __git_complete_refs ()\n \t\tshift\n \tdone\n \n-\t__gitcomp_direct \"$(__git_refs \"$remote\" \"$track\" \"$pfx\" \"$cur_\" \"$sfx\")\"\n+\t__gitcomp_direct \"$(__git_refs \"$remote\" \"$dwim\" \"$pfx\" \"$cur_\" \"$sfx\")\"\n }\n \n # __git_refs2 requires 1 argument (to pass to __git_refs)\n@@ -1370,12 +1372,12 @@ _git_checkout ()\n \t*)\n \t\t# check if --track, --no-track, or --no-guess was specified\n \t\t# if so, disable DWIM mode\n-\t\tlocal flags=\"--track --no-track --no-guess\" track_opt=\"--track\"\n+\t\tlocal flags=\"--track --no-track --no-guess\" dwim_opt=\"--dwim\"\n \t\tif [ \"$GIT_COMPLETION_CHECKOUT_NO_GUESS\" = \"1\" ] ||\n \t\t   [ -n \"$(__git_find_on_cmdline \"$flags\")\" ]; then\n-\t\t\ttrack_opt=''\n+\t\t\tdwim_opt=''\n \t\tfi\n-\t\t__git_complete_refs $track_opt\n+\t\t__git_complete_refs $dwim_opt\n \t\t;;\n \tesac\n }\n@@ -2226,27 +2228,27 @@ _git_switch ()\n \t*)\n \t\t# check if --track, --no-track, or --no-guess was specified\n \t\t# if so, disable DWIM mode\n-\t\tlocal track_opt=\"--track\" only_local_ref=n\n+\t\tlocal dwim_opt=\"--dwim\" only_local_ref=n\n \t\tif [ \"$GIT_COMPLETION_CHECKOUT_NO_GUESS\" = \"1\" ] ||\n \t\t   [ -n \"$(__git_find_on_cmdline \"--track --no-track --no-guess\")\" ]; then\n-\t\t\ttrack_opt=''\n+\t\t\tdwim_opt=''\n \t\tfi\n \t\t# explicit --guess enables DWIM mode regardless of\n \t\t# $GIT_COMPLETION_CHECKOUT_NO_GUESS\n \t\tif [ -n \"$(__git_find_on_cmdline \"--guess\")\" ]; then\n-\t\t\ttrack_opt='--track'\n+\t\t\tdwim_opt='--dwim'\n \t\tfi\n \t\tif [ -z \"$(__git_find_on_cmdline \"-d --detach\")\" ]; then\n \t\t\tonly_local_ref=y\n \t\telse\n \t\t\t# --guess --detach is invalid combination, no\n \t\t\t# dwim will be done when --detach is specified\n-\t\t\ttrack_opt=\n+\t\t\tdwim_opt=\n \t\tfi\n-\t\tif [ $only_local_ref = y -a -z \"$track_opt\" ]; then\n+\t\tif [ $only_local_ref = y -a -z \"$dwim_opt\" ]; then\n \t\t\t__gitcomp_direct \"$(__git_heads \"\" \"$cur\" \" \")\"\n \t\telse\n-\t\t\t__git_complete_refs $track_opt\n+\t\t\t__git_complete_refs $dwim_opt\n \t\tfi\n \t\t;;\n \tesac\n-- \n2.25.2\n\n"},{"id":"398633","messageId":"20200527113831.3294409-6-jacob.e.keller@intel.com","threadId":"53562","inReplyTo":"20200527113831.3294409-1-jacob.e.keller@intel.com","subject":"[PATCH v2 5/9] completion: improve completion for git switch with no options","fromName":"Jacob Keller","fromEmail":"jacob.e.keller@intel.com","sentAt":"2020-05-27T11:38:27Z","receivedAt":"2020-05-27T11:38:50Z","isPatch":true,"sender":{"key":"jacob.e.keller@intel.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"From: Jacob Keller <jacob.keller@gmail.com>\n\nThe current default behavior of completion for git switch is\nsub-optimal. Unlike checkout, git switch by default focuses on switching\nbranches. It does not allow detaching HEAD without the --detach option.\nBy default, git switch accepts only branch names. If a unique remote\nbranch name is given, then it will \"Do What I Mean\" and automatically\ncreate a local branch tracking that remote branch.\n\nHowever, \"git switch <TAB>\" will complete more than just branch names!\nIt actually completes all local references, including tags and fully\nspecified remote branch names.\n\nAs an example, today completion will provide the following words:\n\n  $git switch <TAB>\n  branch-in-other\n  master\n  master-in-other\n  matching-branch\n  matching-tag\n  other/branch-in-other\n  other/master-in-other\n\nThis includes many options which are invalid, such as tags, and fully\nspecified remote branches. Avoid completing these.\n\nAdd a new --mode option to __git_complete_refs, which allows changing\nthe behavior to call __git_heads instead of __git_refs.\n\nBy passing --mode=heads, __git_complete_refs will only output local\nbranches. This enables using \"--mode=heads --dwim\" to enable listing\nlocal branches and the remote unique branch names for DWIM.\n\nRefactor completion support to use the new mode option, rather than\ncalling __git_heads directly. This has the advantage that we can now\ncorrectly allow local branches along with suitable DWIM refs, rather\nthan only allowing DWIM when we complete all references.\n\nChoose what mode it uses when calling __git_complete_refs. If -d or\n--detach have been provided, then simply complete all refs, but\n*without* the DWIM option as these DWIM names won't work properly in\n--detach mode.\n\nOtherwise, call __git_complete_refs with the default dwim_opt value and\nuse the new \"heads\" mode.\n\nIn this way, the basic support for completing just \"git switch <TAB>\"\nwill result in only local branches and remote unique names for DWIM, so\nswitch this test to test_expect_success.\n\nAdd new test cases that cover the default behavior of completion for git\nswitch and git checkout with no options.\n\nSigned-off-by: Jacob Keller <jacob.keller@gmail.com>\n---\n contrib/completion/git-completion.bash | 33 ++++++++++++++++----------\n t/t9902-completion.sh                  | 26 ++++++++++++++++++--\n 2 files changed, 44 insertions(+), 15 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 54cd676fdc9d..53afd72d0e4e 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -782,9 +782,12 @@ __git_refs ()\n #               word to be completed.\n # --sfx=<suffix>: A suffix to be appended to each ref instead of the default\n #                 space.\n+# --mode=<mode>: What set of refs to complete, one of 'refs' (the default) to\n+#                complete all refs, 'heads' to complete only branches. Note\n+#                that --remote is only compatible with --mode=refs.\n __git_complete_refs ()\n {\n-\tlocal remote dwim pfx cur_=\"$cur\" sfx=\" \"\n+\tlocal remote dwim pfx cur_=\"$cur\" sfx=\" \" mode=\"refs\"\n \n \twhile test $# != 0; do\n \t\tcase \"$1\" in\n@@ -795,13 +798,23 @@ __git_complete_refs ()\n \t\t--pfx=*)\tpfx=\"${1##--pfx=}\" ;;\n \t\t--cur=*)\tcur_=\"${1##--cur=}\" ;;\n \t\t--sfx=*)\tsfx=\"${1##--sfx=}\" ;;\n+\t\t--mode=*)\tmode=\"${1##--mode=}\" ;;\n \t\t*)\t\treturn 1 ;;\n \t\tesac\n \t\tshift\n \tdone\n \n-\t__gitcomp_direct \"$(__git_refs \"$remote\" \"\" \"$pfx\" \"$cur_\" \"$sfx\")\"\n+\t# complete references based on the specified mode\n+\tcase \"$mode\" in\n+\t\trefs)\n+\t\t\t__gitcomp_direct \"$(__git_refs \"$remote\" \"\" \"$pfx\" \"$cur_\" \"$sfx\")\" ;;\n+\t\theads)\n+\t\t\t__gitcomp_direct \"$(__git_heads \"$pfx\" \"$cur_\" \"$sfx\")\" ;;\n+\t\t*)\n+\t\t\treturn 1 ;;\n+\tesac\n \n+\t# Append DWIM remote branch names if requested\n \tif [ \"$dwim\" = \"yes\" ]; then\n \t\t__gitcomp_direct_append \"$(__git_dwim_remote_heads \"$pfx\" \"$cur_\" \"$sfx\")\"\n \tfi\n@@ -2325,18 +2338,12 @@ _git_switch ()\n \t\t__gitcomp_builtin switch\n \t\t;;\n \t*)\n-\t\tlocal dwim_opt=\"$(__git_checkout_default_dwim_mode)\" only_local_ref=n\n-\t\tif [ -z \"$(__git_find_on_cmdline \"-d --detach\")\" ]; then\n-\t\t\tonly_local_ref=y\n+\t\tlocal dwim_opt=\"$(__git_checkout_default_dwim_mode)\"\n+\n+\t\tif [ -n \"$(__git_find_on_cmdline \"-d --detach\")\" ]; then\n+\t\t\t__git_complete_refs --mode=\"refs\"\n \t\telse\n-\t\t\t# --guess --detach is invalid combination, no\n-\t\t\t# dwim will be done when --detach is specified\n-\t\t\tdwim_opt=\n-\t\tfi\n-\t\tif [ $only_local_ref = y -a -z \"$dwim_opt\" ]; then\n-\t\t\t__gitcomp_direct \"$(__git_heads \"\" \"$cur\" \" \")\"\n-\t\telse\n-\t\t\t__git_complete_refs $dwim_opt\n+\t\t\t__git_complete_refs $dwim_opt --mode=\"heads\"\n \t\tfi\n \t\t;;\n \tesac\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 6d90d19d9fe5..ec9437688cd7 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1240,6 +1240,28 @@ test_expect_success '__git_complete_fetch_refspecs - fully qualified & prefix' '\n \ttest_cmp expected out\n '\n \n+test_expect_success 'git switch - with no options, complete local branches and unique remote branch names for DWIM logic' '\n+\ttest_completion \"git switch \" <<-\\EOF\n+\tbranch-in-other Z\n+\tmaster Z\n+\tmaster-in-other Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - completes refs and unique remote branches for DWIM' '\n+\ttest_completion \"git checkout \" <<-\\EOF\n+\tHEAD Z\n+\tbranch-in-other Z\n+\tmaster Z\n+\tmaster-in-other Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n test_expect_success 'git switch - with --no-guess, complete only local branches' '\n \ttest_completion \"git switch --no-guess \" <<-\\EOF\n \tmaster Z\n@@ -1254,7 +1276,7 @@ test_expect_success 'git switch - with GIT_COMPLETION_CHECKOUT_NO_GUESS=1, compl\n \tEOF\n '\n \n-test_expect_failure 'git switch - --guess overrides GIT_COMPLETION_CHECKOUT_NO_GUESS=1, complete local branches and unique remote names for DWIM logic' '\n+test_expect_success 'git switch - --guess overrides GIT_COMPLETION_CHECKOUT_NO_GUESS=1, complete local branches and unique remote names for DWIM logic' '\n \tGIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion \"git switch --guess \" <<-\\EOF\n \tbranch-in-other Z\n \tmaster Z\n@@ -1263,7 +1285,7 @@ test_expect_failure 'git switch - --guess overrides GIT_COMPLETION_CHECKOUT_NO_G\n \tEOF\n '\n \n-test_expect_failure 'git switch - a later --guess overrides previous --no-guess, complete local and remote unique branches for DWIM' '\n+test_expect_success 'git switch - a later --guess overrides previous --no-guess, complete local and remote unique branches for DWIM' '\n \ttest_completion \"git switch --no-guess --guess \" <<-\\EOF\n \tbranch-in-other Z\n \tmaster Z\n-- \n2.25.2\n\n"},{"id":"398634","messageId":"20200527113831.3294409-8-jacob.e.keller@intel.com","threadId":"53562","inReplyTo":"20200527113831.3294409-1-jacob.e.keller@intel.com","subject":"[PATCH v2 7/9] completion: improve handling of --track in switch/checkout","fromName":"Jacob Keller","fromEmail":"jacob.e.keller@intel.com","sentAt":"2020-05-27T11:38:29Z","receivedAt":"2020-05-27T11:38:54Z","isPatch":true,"sender":{"key":"jacob.e.keller@intel.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"From: Jacob Keller <jacob.keller@gmail.com>\n\nCurrent completion for the --track option of git switch and git checkout\nis sub par. In addition to the DWIM logic of a bare branch name, --track\nhas DWIM logic to convert specified remote/branch names into a local\nbranch tracking that remote. For example\n\n  $git switch --track origin/master\n\nThis will create a local branch name master, that tracks the master\nbranch of the origin remote.\n\nIn fact, git switch --track on its own will not accept other forms of\nreferences. These must instead be specified manually via the -c/-C/-b/-B\noptions.\n\nIntroduce __git_remote_heads() and the \"remote-heads\" mode for\n__git_complete_refs. Use this when the --track option is provided while\ncompleting in _git_switch and _git_checkout. Just as in the --detach\ncase, we never enable DWIM mode for --track, because it doesn't make\nsense.\n\nIt should be noted that completion support is still a bit sub par when\nit comes to handling -c/-C and --orphan. This will be resolved in\na future change.\n\nSigned-off-by: Jacob Keller <jacob.keller@gmail.com>\n---\n contrib/completion/git-completion.bash | 24 +++++++++++++++++--\n t/t9902-completion.sh                  | 32 ++++++++++++++++++++++++++\n 2 files changed, 54 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 38b5a5a0d874..4cdf09987725 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -624,6 +624,19 @@ __git_heads ()\n \t\t\t\"refs/heads/$cur_*\" \"refs/heads/$cur_*/**\"\n }\n \n+# Lists branches from remote repositories.\n+# 1: A prefix to be added to each listed branch (optional).\n+# 2: List only branches matching this word (optional; list all branches if\n+#    unset or empty).\n+# 3: A suffix to be appended to each listed branch (optional).\n+__git_remote_heads ()\n+{\n+\tlocal pfx=\"${1-}\" cur_=\"${2-}\" sfx=\"${3-}\"\n+\n+\t__git for-each-ref --format=\"${pfx//\\%/%%}%(refname:strip=2)$sfx\" \\\n+\t\t\t\"refs/remotes/$cur_*\" \"refs/remotes/$cur_*/**\"\n+}\n+\n # Lists tags from the local repository.\n # Accepts the same positional parameters as __git_heads() above.\n __git_tags ()\n@@ -783,8 +796,9 @@ __git_refs ()\n # --sfx=<suffix>: A suffix to be appended to each ref instead of the default\n #                 space.\n # --mode=<mode>: What set of refs to complete, one of 'refs' (the default) to\n-#                complete all refs, 'heads' to complete only branches. Note\n-#                that --remote is only compatible with --mode=refs.\n+#                complete all refs, 'heads' to complete only branches, or\n+#                'remote-heads' to complete only remote branches. Note that\n+#                --remote is only compatible with --mode=refs.\n __git_complete_refs ()\n {\n \tlocal remote dwim pfx cur_=\"$cur\" sfx=\" \" mode=\"refs\"\n@@ -810,6 +824,8 @@ __git_complete_refs ()\n \t\t\t__gitcomp_direct \"$(__git_refs \"$remote\" \"\" \"$pfx\" \"$cur_\" \"$sfx\")\" ;;\n \t\theads)\n \t\t\t__gitcomp_direct \"$(__git_heads \"$pfx\" \"$cur_\" \"$sfx\")\" ;;\n+\t\tremote-heads)\n+\t\t\t__gitcomp_direct \"$(__git_remote_heads \"$pfx\" \"$cur_\" \"$sfx\")\" ;;\n \t\t*)\n \t\t\treturn 1 ;;\n \tesac\n@@ -1492,6 +1508,8 @@ _git_checkout ()\n \n \t\tif [ -n \"$(__git_find_on_cmdline \"-d --detach\")\" ]; then\n \t\t\t__git_complete_refs --mode=\"refs\"\n+\t\telif [ -n \"$(__git_find_on_cmdline \"--track\")\" ]; then\n+\t\t\t__git_complete_refs --mode=\"remote-heads\"\n \t\telse\n \t\t\t__git_complete_refs $dwim_opt --mode=\"refs\"\n \t\tfi\n@@ -2347,6 +2365,8 @@ _git_switch ()\n \n \t\tif [ -n \"$(__git_find_on_cmdline \"-d --detach\")\" ]; then\n \t\t\t__git_complete_refs --mode=\"refs\"\n+\t\telif [ -n \"$(__git_find_on_cmdline \"--track\")\" ]; then\n+\t\t\t__git_complete_refs --mode=\"remote-heads\"\n \t\telse\n \t\t\t__git_complete_refs $dwim_opt --mode=\"heads\"\n \t\tfi\ndiff --git a/t/t9902-completion.sh b/t/t9902-completion.sh\nindex 5b1868e43632..b09eb498d175 100755\n--- a/t/t9902-completion.sh\n+++ b/t/t9902-completion.sh\n@@ -1404,6 +1404,38 @@ test_expect_success 'git checkout - with -d, complete only references' '\n \tEOF\n '\n \n+test_expect_success 'git switch - with --track, complete only remote branches' '\n+\ttest_completion \"git switch --track \" <<-\\EOF\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with --track, complete only remote branches' '\n+\ttest_completion \"git checkout --track \" <<-\\EOF\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - with --no-track, complete only local branch names' '\n+\ttest_completion \"git switch --no-track \" <<-\\EOF\n+\tmaster Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with --no-track, complete only local references' '\n+\ttest_completion \"git checkout --no-track \" <<-\\EOF\n+\tHEAD Z\n+\tmaster Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/master-in-other Z\n+\tEOF\n+'\n+\n test_expect_success 'teardown after ref completion' '\n \tgit branch -d matching-branch &&\n \tgit tag -d matching-tag &&\n-- \n2.25.2\n\n"},{"id":"398675","messageId":"xmqqimghl0ft.fsf@gitster.c.googlers.com","threadId":"53562","inReplyTo":"20200527113831.3294409-3-jacob.e.keller@intel.com","subject":"Re: [PATCH v2 2/9] completion: improve handling of DWIM mode for switch/checkout","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-05-27T18:03:50Z","receivedAt":"2020-05-27T18:03:54Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jacob Keller <jacob.e.keller@intel.com> writes:\n\n> This new logic is more robust, as we will correctly identify superseded\n> options, and ensure that both _git_switch and _git_checkout enable DWIM\n> in similar ways.\n>\n> Add several tests which demonstrate the new expected behavior. Note that\n> some of the git switch tests are marked as failures because the default\n> git switch completion with --guess is sub-par as discussed in a previous\n> commit. This will be fixed in a future change.\n\n\"as discussed in a previous commit\"?  1/9 does not mention --guess\nat all.  Perhaps this is an unintended damage due to rebasing?\n\nIn any case, up to this point, the log messages are a bit\nfrustrating read, primarily because the author has spent too much\ntime on DWIM and expect everybody understands exactly what he means\nwhen he says \"DWIM mode is enabled\", while a reader in me keeps\nasking:\n\n - what refs get included when I type <TAB> without DWIM mode?\n\n - what extra refs get included when DWIM mode is enabled?\n\n - under DWIM mode, do certain refs (that would be included without\n   DWIM mode) stop appearing in the completion?\n\nand without getting any answer to them.  Perhaps the proposed log\nmessage for [1/9] can be made a bit more robust to cover it?\n\nThanks.\n\n"},{"id":"398689","messageId":"CA+P7+xoTJzsV=NbWeWs+fbdgETXwqUs0T9MToBbrGJ0EA-bFcA@mail.gmail.com","threadId":"53562","inReplyTo":"xmqqimghl0ft.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v2 2/9] completion: improve handling of DWIM mode for switch/checkout","fromName":"Jacob Keller","fromEmail":"jacob.keller@gmail.com","sentAt":"2020-05-27T19:41:43Z","receivedAt":"2020-05-27T19:41:58Z","isPatch":true,"sender":{"key":"jacob.keller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"On Wed, May 27, 2020 at 11:03 AM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Jacob Keller <jacob.e.keller@intel.com> writes:\n>\n> > This new logic is more robust, as we will correctly identify superseded\n> > options, and ensure that both _git_switch and _git_checkout enable DWIM\n> > in similar ways.\n> >\n> > Add several tests which demonstrate the new expected behavior. Note that\n> > some of the git switch tests are marked as failures because the default\n> > git switch completion with --guess is sub-par as discussed in a previous\n> > commit. This will be fixed in a future change.\n>\n> \"as discussed in a previous commit\"?  1/9 does not mention --guess\n> at all.  Perhaps this is an unintended damage due to rebasing?\n>\n\nYes I originally had a patch earlier in the series which just added\ntest cases, but I later moved that into the patch that fixed the\ntests.\n\n> In any case, up to this point, the log messages are a bit\n> frustrating read, primarily because the author has spent too much\n> time on DWIM and expect everybody understands exactly what he means\n> when he says \"DWIM mode is enabled\", while a reader in me keeps\n> asking:\n\nRight, I thought I had an explanation of this somewhere but it appears\nto have been lost while re-ordering and re-wording.\n\n>\n>  - what refs get included when I type <TAB> without DWIM mode?\n>\n>  - what extra refs get included when DWIM mode is enabled?\n>\n>  - under DWIM mode, do certain refs (that would be included without\n>    DWIM mode) stop appearing in the completion?\n>\n> and without getting any answer to them.  Perhaps the proposed log\n> message for [1/9] can be made a bit more robust to cover it?\n>\n\nSure, I'll look at what I can do to make this more logical.\n\n> Thanks.\n>\n"},{"id":"398726","messageId":"CA+P7+xrxt5oybijmRWFd-fMYxKSB8cnuX188g9x9UkRcmwigVw@mail.gmail.com","threadId":"53562","inReplyTo":"CA+P7+xoTJzsV=NbWeWs+fbdgETXwqUs0T9MToBbrGJ0EA-bFcA@mail.gmail.com","subject":"Re: [PATCH v2 2/9] completion: improve handling of DWIM mode for switch/checkout","fromName":"Jacob Keller","fromEmail":"jacob.keller@gmail.com","sentAt":"2020-05-28T08:53:17Z","receivedAt":"2020-05-28T08:53:29Z","isPatch":true,"sender":{"key":"jacob.keller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"On Wed, May 27, 2020 at 12:41 PM Jacob Keller <jacob.keller@gmail.com> wrote:\n> >\n> > and without getting any answer to them.  Perhaps the proposed log\n> > message for [1/9] can be made a bit more robust to cover it?\n> >\n>\n> Sure, I'll look at what I can do to make this more logical.\n>\n> > Thanks.\n> >\n\nI'll have a v3 which splits most of the tests into their own patch\nwith a better description of the reasoning of the problem with output\nand the new expected behavior. The commit descriptions for the\nimprovements will then focus primarily on the reasons for the\nparticular method of implementing that output. It's a few more\npatches, but hopefully it will read more logically, and we can help\nsettle some of the open questions:\n\nparticular to interest me is: what sort of words should we complete\nwhen completing a new branch name for --orphan, -c/-C and -b/-B? I\nthink all of these ought to remain as consistent as possible, but I'm\nnot sure what other folks think.\n\nThanks,\nJake\n"}]}