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