Skip to content

Commit e337860

Browse files
brandb97gitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 16bd9f2 commit e337860

File tree

3 files changed

+93
-3
lines changed

3 files changed

+93
-3
lines changed

Documentation/config/pull.adoc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,21 @@ pull.octopus::
2929
The default merge strategy to use when pulling multiple branches
3030
at once.
3131

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+
3248
pull.twohead::
3349
The default merge strategy to use when pulling a single branch.

builtin/pull.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ static char *opt_ff;
9090
static const char *opt_verify_signatures;
9191
static const char *opt_verify;
9292
static int opt_autostash = -1;
93-
static int config_autostash;
93+
static int config_rebase_autostash;
94+
static int config_pull_autostash = -1;
9495
static int check_trust_level = 1;
9596
static struct strvec opt_strategies = STRVEC_INIT;
9697
static struct strvec opt_strategy_opts = STRVEC_INIT;
@@ -364,7 +365,18 @@ static int git_pull_config(const char *var, const char *value,
364365
const struct config_context *ctx, void *cb)
365366
{
366367
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);
368380
return 0;
369381
} else if (!strcmp(var, "submodule.recurse")) {
370382
recurse_submodules = git_config_bool(var, value) ?
@@ -1003,6 +1015,8 @@ int cmd_pull(int argc,
10031015
}
10041016

10051017
argc = parse_options(argc, argv, prefix, pull_options, pull_usage, 0);
1018+
if (opt_autostash == -1)
1019+
opt_autostash = config_pull_autostash;
10061020

10071021
if (recurse_submodules_cli != RECURSE_SUBMODULES_DEFAULT)
10081022
recurse_submodules = recurse_submodules_cli;
@@ -1049,7 +1063,7 @@ int cmd_pull(int argc,
10491063

10501064
if (opt_rebase) {
10511065
if (opt_autostash == -1)
1052-
opt_autostash = config_autostash;
1066+
opt_autostash = config_rebase_autostash;
10531067

10541068
if (is_null_oid(&orig_head) && !is_index_unborn(the_repository->index))
10551069
die(_("Updating an unborn branch with changes added to the index."));

t/t5520-pull.sh

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,66 @@ test_expect_success 'pull --no-autostash & merge.autostash unset' '
472472
test_pull_autostash_fail --no-autostash --no-rebase
473473
'
474474

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+
475535
test_expect_success 'pull.rebase' '
476536
git reset --hard before-rebase &&
477537
test_config pull.rebase true &&

0 commit comments

Comments
 (0)