@matheusbsbs / matheus-bagliano / commits / 64f1f58fe7
Fork 0

checkout: learn to respect checkout.guess

The current behavior of git checkout/switch is that --guess is currently enabled by default. However, some users may not wish for this to happen automatically. Instead of forcing users to specify --no-guess manually each time, teach these commands the checkout.guess configuration variable that gives users the option to set a default behavior. Teach the completion script to recognize the new config variable and disable DWIM logic if it is set to false. Signed-off-by: Denton Liu <liu.denton@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Denton Liu committed Oct 7, 2020 at 22:48 UTC 64f1f58fe7c0837bd0ae56ba83add5e1b84c54d3
8 files changed +101 -12
Documentation/config/checkout.txt
+5
@@ -16,3 +16,8 @@ will checkout the `<something>` branch on another remote,
16 and by linkgit:git-worktree[1] when `git worktree add` refers to a
17 remote branch. This setting might be used for other checkout-like
18 commands or functionality in the future.
19 +
20 +checkout.guess::
21 + Provides the default value for the `--guess` or `--no-guess`
22 + option in `git checkout` and `git switch`. See
23 + linkgit:git-switch[1] and linkgit:git-checkout[1].
Documentation/git-checkout.txt
+4 -1
@@ -192,7 +192,10 @@ branches from there if `<branch>` is ambiguous but exists on the
192 'origin' remote. See also `checkout.defaultRemote` in
193 linkgit:git-config[1].
194 +
195 -Use `--no-guess` to disable this.
195 +`--guess` is the default behavior. Use `--no-guess` to disable it.
196 ++
197 +The default behavior can be set via the `checkout.guess` configuration
198 +variable.
199
200 -l::
201 Create the new branch's reflog; see linkgit:git-branch[1] for
Documentation/git-switch.txt
+3
@@ -103,6 +103,9 @@ ambiguous but exists on the 'origin' remote. See also
103 `checkout.defaultRemote` in linkgit:git-config[1].
104 +
105 `--guess` is the default behavior. Use `--no-guess` to disable it.
106 ++
107 +The default behavior can be set via the `checkout.guess` configuration
108 +variable.
109
110 -f::
111 --force::
builtin/checkout.c
+6 -1
@@ -1093,11 +1093,16 @@ static int switch_branches(const struct checkout_opts *opts,
1093
1094 static int git_checkout_config(const char *var, const char *value, void *cb)
1095 {
1096 + struct checkout_opts *opts = cb;
1097 +
1098 if (!strcmp(var, "diff.ignoresubmodules")) {
1097 - struct checkout_opts *opts = cb;
1099 handle_ignore_submodules_arg(&opts->diff_options, value);
1100 return 0;
1101 }
1102 + if (!strcmp(var, "checkout.guess")) {
1103 + opts->dwim_new_local_branch = git_config_bool(var, value);
1104 + return 0;
1105 + }
1106
1107 if (starts_with(var, "submodule."))
1108 return git_default_submodule_config(var, value, NULL);
contrib/completion/git-completion.bash
+16 -9
@@ -1467,14 +1467,15 @@ _git_bundle ()
1467 # Helper function to decide whether or not we should enable DWIM logic for
1468 # git-switch and git-checkout.
1469 #
1470 -# To decide between the following rules in priority order
1471 -# 1) the last provided of "--guess" or "--no-guess" explicitly enable or
1472 -# disable completion of DWIM logic respectively.
1473 -# 2) If the --no-track option is provided, take this as a hint to disable the
1474 -# DWIM completion logic
1475 -# 3) If GIT_COMPLETION_CHECKOUT_NO_GUESS is set, disable the DWIM completion
1476 -# logic, as requested by the user.
1477 -# 4) Enable DWIM logic otherwise.
1470 +# To decide between the following rules in decreasing priority order:
1471 +# - the last provided of "--guess" or "--no-guess" explicitly enable or
1472 +# disable completion of DWIM logic respectively.
1473 +# - If checkout.guess is false, disable completion of DWIM logic.
1474 +# - If the --no-track option is provided, take this as a hint to disable the
1475 +# DWIM completion logic
1476 +# - If GIT_COMPLETION_CHECKOUT_NO_GUESS is set, disable the DWIM completion
1477 +# logic, as requested by the user.
1478 +# - Enable DWIM logic otherwise.
1479 #
1480 __git_checkout_default_dwim_mode ()
1481 {
@@ -1485,11 +1486,17 @@ __git_checkout_default_dwim_mode ()
1486 fi
1487
1488 # --no-track disables DWIM, but with lower priority than
1488 - # --guess/--no-guess
1489 + # --guess/--no-guess/checkout.guess
1490 if [ -n "$(__git_find_on_cmdline "--no-track")" ]; then
1491 dwim_opt=""
1492 fi
1493
1494 + # checkout.guess = false disables DWIM, but with lower priority than
1495 + # --guess/--no-guess
1496 + if [ "$(__git config --type=bool checkout.guess)" = "false" ]; then
1497 + dwim_opt=""
1498 + fi
1499 +
1500 # Find the last provided --guess or --no-guess
1501 last_option="$(__git_find_last_on_cmdline "--guess --no-guess")"
1502 case "$last_option" in
t/t2024-checkout-dwim.sh
+11
@@ -166,6 +166,17 @@ test_expect_success '--no-guess suppresses branch auto-vivification' '
166 test_branch master
167 '
168
169 +test_expect_success 'checkout.guess = false suppresses branch auto-vivification' '
170 + git checkout -B master &&
171 + status_uno_is_clean &&
172 + test_might_fail git branch -D bar &&
173 +
174 + test_config checkout.guess false &&
175 + test_must_fail git checkout bar &&
176 + test_must_fail git rev-parse --verify refs/heads/bar &&
177 + test_branch master
178 +'
179 +
180 test_expect_success 'setup more remotes with unconventional refspecs' '
181 git checkout -B master &&
182 status_uno_is_clean &&
t/t2060-switch.sh
+4 -1
@@ -85,9 +85,12 @@ test_expect_success 'switching ignores file of same branch name' '
85 test_cmp expected actual
86 '
87
88 -test_expect_success 'guess and create branch ' '
88 +test_expect_success 'guess and create branch' '
89 test_when_finished git switch master &&
90 test_must_fail git switch --no-guess foo &&
91 + test_config checkout.guess false &&
92 + test_must_fail git switch foo &&
93 + test_config checkout.guess true &&
94 git switch foo &&
95 echo refs/heads/foo >expected &&
96 git symbolic-ref HEAD >actual &&
t/t9902-completion.sh
+52
@@ -1360,6 +1360,58 @@ test_expect_success 'git checkout - a later --no-guess overrides previous --gues
1360 EOF
1361 '
1362
1363 +test_expect_success 'git checkout - with checkout.guess = false, only completes refs' '
1364 + test_config checkout.guess false &&
1365 + test_completion "git checkout " <<-\EOF
1366 + HEAD Z
1367 + master Z
1368 + matching-branch Z
1369 + matching-tag Z
1370 + other/branch-in-other Z
1371 + other/master-in-other Z
1372 + EOF
1373 +'
1374 +
1375 +test_expect_success 'git checkout - with checkout.guess = true, completes refs and unique remote branches for DWIM' '
1376 + test_config checkout.guess true &&
1377 + test_completion "git checkout " <<-\EOF
1378 + HEAD Z
1379 + branch-in-other Z
1380 + master Z
1381 + master-in-other Z
1382 + matching-branch Z
1383 + matching-tag Z
1384 + other/branch-in-other Z
1385 + other/master-in-other Z
1386 + EOF
1387 +'
1388 +
1389 +test_expect_success 'git checkout - a later --guess overrides previous checkout.guess = false, complete refs and unique remote branches for DWIM' '
1390 + test_config checkout.guess false &&
1391 + test_completion "git checkout --guess " <<-\EOF
1392 + HEAD Z
1393 + branch-in-other Z
1394 + master Z
1395 + master-in-other Z
1396 + matching-branch Z
1397 + matching-tag Z
1398 + other/branch-in-other Z
1399 + other/master-in-other Z
1400 + EOF
1401 +'
1402 +
1403 +test_expect_success 'git checkout - a later --no-guess overrides previous checkout.guess = true, complete only refs' '
1404 + test_config checkout.guess true &&
1405 + test_completion "git checkout --no-guess " <<-\EOF
1406 + HEAD Z
1407 + master Z
1408 + matching-branch Z
1409 + matching-tag Z
1410 + other/branch-in-other Z
1411 + other/master-in-other Z
1412 + EOF
1413 +'
1414 +
1415 test_expect_success 'git switch - with --detach, complete all references' '
1416 test_completion "git switch --detach " <<-\EOF
1417 HEAD Z