pull: add pull.autoStash config option

Git uses `rebase.autostash` or `merge.autostash` to determine whether a dirty worktree is allowed during pull. However, this behavior is not clearly documented, making it difficult for users to discover how to enable autostash, or causing them to unknowingly enable it. Add new config option `pull.autostash` along with its documentation and test cases. `pull.autostash` provides the same functionality as `rebase.autostash` and `merge.autostash`, but overrides them when set. If `pull.autostash` is not set, it falls back to `rebase.autostash` or `merge.autostash`, depending on the value of `pull.rebase`. Signed-off-by: Lidong Yan <yldhome2d2@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Lidong Yan committed Jul 20, 2025 at 20:43 UTC e3378607c8675a2db6d997bd9781ae5500a2ec57
3 files changed +93 -3
Documentation/config/pull.adoc
+16
@@ -29,5 +29,21 @@ pull.octopus::
29 The default merge strategy to use when pulling multiple branches
30 at once.
31
32 +pull.autoStash::
33 + When set to true, automatically create a temporary stash entry
34 + to record the local changes before the operation begins, and
35 + restore them after the operation completes. When your "git
36 + pull" rebases (instead of merges), this may be convenient, since
37 + unlike merging pull that tolerates local changes that do not
38 + interfere with the merge, rebasing pull refuses to work with any
39 + local changes.
40 ++
41 +If `pull.autostash` is set (either to true or false),
42 +`merge.autostash` and `rebase.autostash` are ignored. If
43 +`pull.autostash` is not set at all, depending on the value of
44 +`pull.rebase`, `merge.autostash` or `rebase.autostash` is used
45 +instead. Can be overridden by the `--[no-]autostash` command line
46 +option.
47 +
48 pull.twohead::
49 The default merge strategy to use when pulling a single branch.
builtin/pull.c
+17 -3
@@ -90,7 +90,8 @@ static char *opt_ff;
90 static const char *opt_verify_signatures;
91 static const char *opt_verify;
92 static int opt_autostash = -1;
93 -static int config_autostash;
93 +static int config_rebase_autostash;
94 +static int config_pull_autostash = -1;
95 static int check_trust_level = 1;
96 static struct strvec opt_strategies = STRVEC_INIT;
97 static struct strvec opt_strategy_opts = STRVEC_INIT;
@@ -364,7 +365,18 @@ static int git_pull_config(const char *var, const char *value,
365 const struct config_context *ctx, void *cb)
366 {
367 if (!strcmp(var, "rebase.autostash")) {
367 - config_autostash = git_config_bool(var, value);
368 + /*
369 + * run_rebase() also reads this option. The reason we handle it here is
370 + * that when pull.rebase is true, a fast-forward may occur without
371 + * invoking run_rebase(). We need to ensure that autostash is set even
372 + * in the fast-forward case.
373 + *
374 + * run_merge() handles merge.autostash, so we don't handle it here.
375 + */
376 + config_rebase_autostash = git_config_bool(var, value);
377 + return 0;
378 + } else if (!strcmp(var, "pull.autostash")) {
379 + config_pull_autostash = git_config_bool(var, value);
380 return 0;
381 } else if (!strcmp(var, "submodule.recurse")) {
382 recurse_submodules = git_config_bool(var, value) ?
@@ -1003,6 +1015,8 @@ int cmd_pull(int argc,
1015 }
1016
1017 argc = parse_options(argc, argv, prefix, pull_options, pull_usage, 0);
1018 + if (opt_autostash == -1)
1019 + opt_autostash = config_pull_autostash;
1020
1021 if (recurse_submodules_cli != RECURSE_SUBMODULES_DEFAULT)
1022 recurse_submodules = recurse_submodules_cli;
@@ -1049,7 +1063,7 @@ int cmd_pull(int argc,
1063
1064 if (opt_rebase) {
1065 if (opt_autostash == -1)
1052 - opt_autostash = config_autostash;
1066 + opt_autostash = config_rebase_autostash;
1067
1068 if (is_null_oid(&orig_head) && !is_index_unborn(the_repository->index))
1069 die(_("Updating an unborn branch with changes added to the index."));
t/t5520-pull.sh
+60
@@ -472,6 +472,66 @@ test_expect_success 'pull --no-autostash & merge.autostash unset' '
472 test_pull_autostash_fail --no-autostash --no-rebase
473 '
474
475 +test_expect_success 'pull succeeds with dirty working directory and pull.autostash=true' '
476 + test_config pull.autostash true &&
477 + test_pull_autostash 1 --rebase &&
478 + test_pull_autostash 2 --no-rebase &&
479 + test_pull_autostash 1 --autostash --rebase &&
480 + test_pull_autostash 2 --autostash --no-rebase
481 +'
482 +
483 +test_expect_success 'pull fails with dirty working directory and pull.autostash=false' '
484 + test_config pull.autostash false &&
485 + test_pull_autostash_fail --rebase &&
486 + test_pull_autostash_fail --no-rebase &&
487 + test_pull_autostash_fail --no-autostash --rebase &&
488 + test_pull_autostash_fail --no-autostash --no-rebase
489 +'
490 +
491 +test_expect_success 'pull --autostash overrides pull.autostash=false' '
492 + test_config pull.autostash false &&
493 + test_pull_autostash 1 --autostash --rebase &&
494 + test_pull_autostash 2 --autostash --no-rebase
495 +'
496 +
497 +test_expect_success 'pull --no-autostash overrides pull.autostash=true' '
498 + test_config pull.autostash true &&
499 + test_pull_autostash_fail --no-autostash --rebase &&
500 + test_pull_autostash_fail --no-autostash --no-rebase
501 +'
502 +
503 +test_expect_success 'pull.autostash=true overrides rebase.autostash' '
504 + test_config pull.autostash true &&
505 + test_config rebase.autostash true &&
506 + test_pull_autostash 1 --rebase &&
507 + test_config rebase.autostash false &&
508 + test_pull_autostash 1 --rebase
509 +'
510 +
511 +test_expect_success 'pull.autostash=false overrides rebase.autostash' '
512 + test_config pull.autostash false &&
513 + test_config rebase.autostash true &&
514 + test_pull_autostash_fail --rebase &&
515 + test_config rebase.autostash false &&
516 + test_pull_autostash_fail --rebase
517 +'
518 +
519 +test_expect_success 'pull.autostash=true overrides merge.autostash' '
520 + test_config pull.autostash true &&
521 + test_config merge.autostash true &&
522 + test_pull_autostash 2 --no-rebase &&
523 + test_config merge.autostash false &&
524 + test_pull_autostash 2 --no-rebase
525 +'
526 +
527 +test_expect_success 'pull.autostash=false overrides merge.autostash' '
528 + test_config pull.autostash false &&
529 + test_config merge.autostash true &&
530 + test_pull_autostash_fail --no-rebase &&
531 + test_config merge.autostash false &&
532 + test_pull_autostash_fail --no-rebase
533 +'
534 +
535 test_expect_success 'pull.rebase' '
536 git reset --hard before-rebase &&
537 test_config pull.rebase true &&