Skip to content

Commit 7c137bb

Browse files
committed
Merge branch 'mj/pull-rebase-autostash'
"git pull --rebase" learned "--[no-]autostash" option, so that the rebase.autostash configuration variable set to true can be overridden from the command line. * mj/pull-rebase-autostash: t5520: test --[no-]autostash with pull.rebase=true t5520: reduce commom lines of code t5520: factor out common "failing autostash" code t5520: factor out common "successful autostash" code t5520: use better test to check stderr output t5520: ensure consistent test conditions t5520: use consistent capitalization in test titles pull --rebase: add --[no-]autostash flag git-pull.c: introduce git_pull_config()
2 parents 34e859d + 450dd1d commit 7c137bb

File tree

3 files changed

+103
-10
lines changed

3 files changed

+103
-10
lines changed

Documentation/git-pull.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,15 @@ unless you have read linkgit:git-rebase[1] carefully.
128128
--no-rebase::
129129
Override earlier --rebase.
130130

131+
--autostash::
132+
--no-autostash::
133+
Before starting rebase, stash local modifications away (see
134+
linkgit:git-stash[1]) if needed, and apply the stash when
135+
done. `--no-autostash` is useful to override the `rebase.autoStash`
136+
configuration variable (see linkgit:git-config[1]).
137+
+
138+
This option is only valid when "--rebase" is used.
139+
131140
Options related to fetching
132141
~~~~~~~~~~~~~~~~~~~~~~~~~~~
133142

builtin/pull.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ static char *opt_commit;
8686
static char *opt_edit;
8787
static char *opt_ff;
8888
static char *opt_verify_signatures;
89+
static int opt_autostash = -1;
90+
static int config_autostash;
8991
static struct argv_array opt_strategies = ARGV_ARRAY_INIT;
9092
static struct argv_array opt_strategy_opts = ARGV_ARRAY_INIT;
9193
static char *opt_gpg_sign;
@@ -149,6 +151,8 @@ static struct option pull_options[] = {
149151
OPT_PASSTHRU(0, "verify-signatures", &opt_verify_signatures, NULL,
150152
N_("verify that the named commit has a valid GPG signature"),
151153
PARSE_OPT_NOARG),
154+
OPT_BOOL(0, "autostash", &opt_autostash,
155+
N_("automatically stash/stash pop before and after rebase")),
152156
OPT_PASSTHRU_ARGV('s', "strategy", &opt_strategies, N_("strategy"),
153157
N_("merge strategy to use"),
154158
0),
@@ -305,6 +309,18 @@ static enum rebase_type config_get_rebase(void)
305309
return REBASE_FALSE;
306310
}
307311

312+
/**
313+
* Read config variables.
314+
*/
315+
static int git_pull_config(const char *var, const char *value, void *cb)
316+
{
317+
if (!strcmp(var, "rebase.autostash")) {
318+
config_autostash = git_config_bool(var, value);
319+
return 0;
320+
}
321+
return git_default_config(var, value, cb);
322+
}
323+
308324
/**
309325
* Returns 1 if there are unstaged changes, 0 otherwise.
310326
*/
@@ -789,6 +805,10 @@ static int run_rebase(const unsigned char *curr_head,
789805
argv_array_pushv(&args, opt_strategy_opts.argv);
790806
if (opt_gpg_sign)
791807
argv_array_push(&args, opt_gpg_sign);
808+
if (opt_autostash == 0)
809+
argv_array_push(&args, "--no-autostash");
810+
else if (opt_autostash == 1)
811+
argv_array_push(&args, "--autostash");
792812

793813
argv_array_push(&args, "--onto");
794814
argv_array_push(&args, sha1_to_hex(merge_head));
@@ -823,7 +843,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
823843
if (opt_rebase < 0)
824844
opt_rebase = config_get_rebase();
825845

826-
git_config(git_default_config, NULL);
846+
git_config(git_pull_config, NULL);
827847

828848
if (read_cache_unmerged())
829849
die_resolve_conflict("Pull");
@@ -834,13 +854,17 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
834854
if (get_sha1("HEAD", orig_head))
835855
hashclr(orig_head);
836856

857+
if (!opt_rebase && opt_autostash != -1)
858+
die(_("--[no-]autostash option is only valid with --rebase."));
859+
837860
if (opt_rebase) {
838-
int autostash = 0;
861+
int autostash = config_autostash;
862+
if (opt_autostash != -1)
863+
autostash = opt_autostash;
839864

840865
if (is_null_sha1(orig_head) && !is_cache_unborn())
841866
die(_("Updating an unborn branch with changes added to the index."));
842867

843-
git_config_get_bool("rebase.autostash", &autostash);
844868
if (!autostash)
845869
die_on_unclean_work_tree(prefix);
846870

t/t5520-pull.sh

Lines changed: 67 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,24 @@ modify () {
99
mv "$2.x" "$2"
1010
}
1111

12+
test_pull_autostash () {
13+
git reset --hard before-rebase &&
14+
echo dirty >new_file &&
15+
git add new_file &&
16+
git pull "$@" . copy &&
17+
test_cmp_rev HEAD^ copy &&
18+
test "$(cat new_file)" = dirty &&
19+
test "$(cat file)" = "modified again"
20+
}
21+
22+
test_pull_autostash_fail () {
23+
git reset --hard before-rebase &&
24+
echo dirty >new_file &&
25+
git add new_file &&
26+
test_must_fail git pull "$@" . copy 2>err &&
27+
test_i18ngrep "uncommitted changes." err
28+
}
29+
1230
test_expect_success setup '
1331
echo file >file &&
1432
git add file &&
@@ -247,15 +265,47 @@ test_expect_success '--rebase fails with multiple branches' '
247265

248266
test_expect_success 'pull --rebase succeeds with dirty working directory and rebase.autostash set' '
249267
test_config rebase.autostash true &&
250-
git reset --hard before-rebase &&
251-
echo dirty >new_file &&
252-
git add new_file &&
253-
git pull --rebase . copy &&
254-
test_cmp_rev HEAD^ copy &&
255-
test "$(cat new_file)" = dirty &&
256-
test "$(cat file)" = "modified again"
268+
test_pull_autostash --rebase
257269
'
258270

271+
test_expect_success 'pull --rebase --autostash & rebase.autostash=true' '
272+
test_config rebase.autostash true &&
273+
test_pull_autostash --rebase --autostash
274+
'
275+
276+
test_expect_success 'pull --rebase --autostash & rebase.autostash=false' '
277+
test_config rebase.autostash false &&
278+
test_pull_autostash --rebase --autostash
279+
'
280+
281+
test_expect_success 'pull --rebase --autostash & rebase.autostash unset' '
282+
test_unconfig rebase.autostash &&
283+
test_pull_autostash --rebase --autostash
284+
'
285+
286+
test_expect_success 'pull --rebase --no-autostash & rebase.autostash=true' '
287+
test_config rebase.autostash true &&
288+
test_pull_autostash_fail --rebase --no-autostash
289+
'
290+
291+
test_expect_success 'pull --rebase --no-autostash & rebase.autostash=false' '
292+
test_config rebase.autostash false &&
293+
test_pull_autostash_fail --rebase --no-autostash
294+
'
295+
296+
test_expect_success 'pull --rebase --no-autostash & rebase.autostash unset' '
297+
test_unconfig rebase.autostash &&
298+
test_pull_autostash_fail --rebase --no-autostash
299+
'
300+
301+
for i in --autostash --no-autostash
302+
do
303+
test_expect_success "pull $i (without --rebase) is illegal" '
304+
test_must_fail git pull $i . copy 2>err &&
305+
test_i18ngrep "only valid with --rebase" err
306+
'
307+
done
308+
259309
test_expect_success 'pull.rebase' '
260310
git reset --hard before-rebase &&
261311
test_config pull.rebase true &&
@@ -264,6 +314,16 @@ test_expect_success 'pull.rebase' '
264314
test new = "$(git show HEAD:file2)"
265315
'
266316

317+
test_expect_success 'pull --autostash & pull.rebase=true' '
318+
test_config pull.rebase true &&
319+
test_pull_autostash --autostash
320+
'
321+
322+
test_expect_success 'pull --no-autostash & pull.rebase=true' '
323+
test_config pull.rebase true &&
324+
test_pull_autostash_fail --no-autostash
325+
'
326+
267327
test_expect_success 'branch.to-rebase.rebase' '
268328
git reset --hard before-rebase &&
269329
test_config branch.to-rebase.rebase true &&

0 commit comments

Comments
 (0)