From c48d73bdececb38af237450724b1a67307d7a013 Mon Sep 17 00:00:00 2001 From: Mehul Jain Date: Mon, 21 Mar 2016 23:48:02 +0530 Subject: git-pull.c: introduce git_pull_config() git-pull makes a seperate call to git_config_get_bool() to read the value of "rebase.autostash". This can be reduced as a call to git_config() is already there in the code. Introduce a callback function git_pull_config() to read "rebase.autostash" along with other variables. Helped-by: Junio C Hamano Helped-by: Paul Tan Helped-by: Eric Sunshine Signed-off-by: Mehul Jain Signed-off-by: Junio C Hamano --- builtin/pull.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/builtin/pull.c b/builtin/pull.c index 10eff03967..c21897d9ab 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -86,6 +86,7 @@ static char *opt_commit; static char *opt_edit; static char *opt_ff; static char *opt_verify_signatures; +static int config_autostash; static struct argv_array opt_strategies = ARGV_ARRAY_INIT; static struct argv_array opt_strategy_opts = ARGV_ARRAY_INIT; static char *opt_gpg_sign; @@ -305,6 +306,18 @@ static enum rebase_type config_get_rebase(void) return REBASE_FALSE; } +/** + * Read config variables. + */ +static int git_pull_config(const char *var, const char *value, void *cb) +{ + if (!strcmp(var, "rebase.autostash")) { + config_autostash = git_config_bool(var, value); + return 0; + } + return git_default_config(var, value, cb); +} + /** * Returns 1 if there are unstaged changes, 0 otherwise. */ @@ -823,7 +836,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix) if (opt_rebase < 0) opt_rebase = config_get_rebase(); - git_config(git_default_config, NULL); + git_config(git_pull_config, NULL); if (read_cache_unmerged()) die_resolve_conflict("Pull"); @@ -835,12 +848,11 @@ int cmd_pull(int argc, const char **argv, const char *prefix) hashclr(orig_head); if (opt_rebase) { - int autostash = 0; + int autostash = config_autostash; if (is_null_sha1(orig_head) && !is_cache_unborn()) die(_("Updating an unborn branch with changes added to the index.")); - git_config_get_bool("rebase.autostash", &autostash); if (!autostash) die_on_unclean_work_tree(prefix); -- cgit v1.2.3 From f66398eb57c627169429f47bbe4d943d2c975959 Mon Sep 17 00:00:00 2001 From: Mehul Jain Date: Mon, 21 Mar 2016 23:48:03 +0530 Subject: pull --rebase: add --[no-]autostash flag If rebase.autoStash configuration variable is set, there is no way to override it for "git pull --rebase" from the command line. Teach "git pull --rebase" the --[no-]autostash command line flag which overrides the current value of rebase.autoStash, if set. As "git rebase" understands the --[no-]autostash option, it's just a matter of passing the option to underlying "git rebase" when "git pull --rebase" is called. Helped-by: Matthieu Moy Helped-by: Junio C Hamano Helped-by: Paul Tan Helped-by: Eric Sunshine Signed-off-by: Mehul Jain Signed-off-by: Junio C Hamano --- Documentation/git-pull.txt | 9 ++++++ builtin/pull.c | 12 ++++++++ t/t5520-pull.sh | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt index a62a2a615d..d033b258e5 100644 --- a/Documentation/git-pull.txt +++ b/Documentation/git-pull.txt @@ -128,6 +128,15 @@ unless you have read linkgit:git-rebase[1] carefully. --no-rebase:: Override earlier --rebase. +--autostash:: +--no-autostash:: + Before starting rebase, stash local modifications away (see + linkgit:git-stash[1]) if needed, and apply the stash when + done. `--no-autostash` is useful to override the `rebase.autoStash` + configuration variable (see linkgit:git-config[1]). ++ +This option is only valid when "--rebase" is used. + Options related to fetching ~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/builtin/pull.c b/builtin/pull.c index c21897d9ab..d98f481d31 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -86,6 +86,7 @@ static char *opt_commit; static char *opt_edit; static char *opt_ff; static char *opt_verify_signatures; +static int opt_autostash = -1; static int config_autostash; static struct argv_array opt_strategies = ARGV_ARRAY_INIT; static struct argv_array opt_strategy_opts = ARGV_ARRAY_INIT; @@ -150,6 +151,8 @@ static struct option pull_options[] = { OPT_PASSTHRU(0, "verify-signatures", &opt_verify_signatures, NULL, N_("verify that the named commit has a valid GPG signature"), PARSE_OPT_NOARG), + OPT_BOOL(0, "autostash", &opt_autostash, + N_("automatically stash/stash pop before and after rebase")), OPT_PASSTHRU_ARGV('s', "strategy", &opt_strategies, N_("strategy"), N_("merge strategy to use"), 0), @@ -802,6 +805,10 @@ static int run_rebase(const unsigned char *curr_head, argv_array_pushv(&args, opt_strategy_opts.argv); if (opt_gpg_sign) argv_array_push(&args, opt_gpg_sign); + if (opt_autostash == 0) + argv_array_push(&args, "--no-autostash"); + else if (opt_autostash == 1) + argv_array_push(&args, "--autostash"); argv_array_push(&args, "--onto"); argv_array_push(&args, sha1_to_hex(merge_head)); @@ -847,8 +854,13 @@ int cmd_pull(int argc, const char **argv, const char *prefix) if (get_sha1("HEAD", orig_head)) hashclr(orig_head); + if (!opt_rebase && opt_autostash != -1) + die(_("--[no-]autostash option is only valid with --rebase.")); + if (opt_rebase) { int autostash = config_autostash; + if (opt_autostash != -1) + autostash = opt_autostash; if (is_null_sha1(orig_head) && !is_cache_unborn()) die(_("Updating an unborn branch with changes added to the index.")); diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index c952d5ef5c..745e59ecf5 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -256,6 +256,76 @@ test_expect_success 'pull --rebase succeeds with dirty working directory and reb test "$(cat file)" = "modified again" ' +test_expect_success 'pull --rebase --autostash & rebase.autostash=true' ' + test_config rebase.autostash true && + git reset --hard before-rebase && + echo dirty >new_file && + git add new_file && + git pull --rebase --autostash . copy && + test_cmp_rev HEAD^ copy && + test "$(cat new_file)" = dirty && + test "$(cat file)" = "modified again" +' + +test_expect_success 'pull --rebase --autostash & rebase.autoStash=false' ' + test_config rebase.autostash false && + git reset --hard before-rebase && + echo dirty >new_file && + git add new_file && + git pull --rebase --autostash . copy && + test_cmp_rev HEAD^ copy && + test "$(cat new_file)" = dirty && + test "$(cat file)" = "modified again" +' + +test_expect_success 'pull --rebase: --autostash & rebase.autoStash unset' ' + git reset --hard before-rebase && + echo dirty >new_file && + git add new_file && + git pull --rebase --autostash . copy && + test_cmp_rev HEAD^ copy && + test "$(cat new_file)" = dirty && + test "$(cat file)" = "modified again" +' + +test_expect_success 'pull --rebase --no-autostash & rebase.autostash=true' ' + test_config rebase.autostash true && + git reset --hard before-rebase && + echo dirty >new_file && + git add new_file && + test_must_fail git pull --rebase --no-autostash . copy 2>err && + test_i18ngrep "Cannot pull with rebase: Your index contains uncommitted changes." err +' + +test_expect_success 'pull --rebase --no-autostash & rebase.autostash=false' ' + test_config rebase.autostash false && + git reset --hard before-rebase && + echo dirty >new_file && + git add new_file && + test_must_fail git pull --rebase --no-autostash . copy 2>err && + test_i18ngrep "Cannot pull with rebase: Your index contains uncommitted changes." err +' + +test_expect_success 'pull --rebase --no-autostash & rebase.autostash unset' ' + git reset --hard before-rebase && + echo dirty >new_file && + git add new_file && + test_must_fail git pull --rebase --no-autostash . copy 2>err && + test_i18ngrep "Cannot pull with rebase: Your index contains uncommitted changes." err +' + +test_expect_success 'pull --autostash (without --rebase) should error out' ' + test_must_fail git pull --autostash . copy 2>actual && + echo "fatal: --[no-]autostash option is only valid with --rebase." >expect && + test_i18ncmp actual expect +' + +test_expect_success 'pull --no-autostash (without --rebase) should error out' ' + test_must_fail git pull --no-autostash . copy 2>actual && + echo "fatal: --[no-]autostash option is only valid with --rebase." >expect && + test_i18ncmp actual expect +' + test_expect_success 'pull.rebase' ' git reset --hard before-rebase && test_config pull.rebase true && -- cgit v1.2.3 From efa195d5b3ab69b419d16b1882e8e1c0537186f5 Mon Sep 17 00:00:00 2001 From: Mehul Jain Date: Sat, 2 Apr 2016 23:28:26 +0530 Subject: t5520: use consistent capitalization in test titles Signed-off-by: Mehul Jain Reviewed-by: Eric Sunshine Signed-off-by: Junio C Hamano --- t/t5520-pull.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 745e59ecf5..5be39df50a 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -267,7 +267,7 @@ test_expect_success 'pull --rebase --autostash & rebase.autostash=true' ' test "$(cat file)" = "modified again" ' -test_expect_success 'pull --rebase --autostash & rebase.autoStash=false' ' +test_expect_success 'pull --rebase --autostash & rebase.autostash=false' ' test_config rebase.autostash false && git reset --hard before-rebase && echo dirty >new_file && @@ -278,7 +278,7 @@ test_expect_success 'pull --rebase --autostash & rebase.autoStash=false' ' test "$(cat file)" = "modified again" ' -test_expect_success 'pull --rebase: --autostash & rebase.autoStash unset' ' +test_expect_success 'pull --rebase: --autostash & rebase.autostash unset' ' git reset --hard before-rebase && echo dirty >new_file && git add new_file && -- cgit v1.2.3 From eff960b3afc70cb936dbf133e8c60d397d8069ac Mon Sep 17 00:00:00 2001 From: Mehul Jain Date: Sat, 2 Apr 2016 23:28:27 +0530 Subject: t5520: ensure consistent test conditions Test title says that tests are done with rebase.autostash unset, but does not take any action to make sure that it is indeed unset. This may lead to test failure if future changes somehow pollutes the configuration globally. Ensure consistent test conditions by explicitly unsetting rebase.autostash. Signed-off-by: Mehul Jain Reviewed-by: Eric Sunshine Signed-off-by: Junio C Hamano --- t/t5520-pull.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 5be39df50a..9ee22185f3 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -279,6 +279,7 @@ test_expect_success 'pull --rebase --autostash & rebase.autostash=false' ' ' test_expect_success 'pull --rebase: --autostash & rebase.autostash unset' ' + test_unconfig rebase.autostash && git reset --hard before-rebase && echo dirty >new_file && git add new_file && @@ -307,6 +308,7 @@ test_expect_success 'pull --rebase --no-autostash & rebase.autostash=false' ' ' test_expect_success 'pull --rebase --no-autostash & rebase.autostash unset' ' + test_unconfig rebase.autostash && git reset --hard before-rebase && echo dirty >new_file && git add new_file && -- cgit v1.2.3 From 6ddc97c7dc11076be30846c13666e5bc1844629a Mon Sep 17 00:00:00 2001 From: Mehul Jain Date: Sat, 2 Apr 2016 23:28:28 +0530 Subject: t5520: use better test to check stderr output Checking stderr output using test_i18ncmp may lead to test failure as some shells write trace output to stderr when run under 'set -x'. Use test_i18ngrep instead of test_i18ncmp. Signed-off-by: Mehul Jain Reviewed-by: Eric Sunshine Signed-off-by: Junio C Hamano --- t/t5520-pull.sh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 9ee22185f3..d03cb842e2 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -317,15 +317,13 @@ test_expect_success 'pull --rebase --no-autostash & rebase.autostash unset' ' ' test_expect_success 'pull --autostash (without --rebase) should error out' ' - test_must_fail git pull --autostash . copy 2>actual && - echo "fatal: --[no-]autostash option is only valid with --rebase." >expect && - test_i18ncmp actual expect + test_must_fail git pull --autostash . copy 2>err && + test_i18ngrep "only valid with --rebase" err ' test_expect_success 'pull --no-autostash (without --rebase) should error out' ' - test_must_fail git pull --no-autostash . copy 2>actual && - echo "fatal: --[no-]autostash option is only valid with --rebase." >expect && - test_i18ncmp actual expect + test_must_fail git pull --no-autostash . copy 2>err && + test_i18ngrep "only valid with --rebase" err ' test_expect_success 'pull.rebase' ' -- cgit v1.2.3 From 5c82bcddf4f436f137bf0608321c92b8328a270a Mon Sep 17 00:00:00 2001 From: Mehul Jain Date: Sat, 2 Apr 2016 23:28:29 +0530 Subject: t5520: factor out common "successful autostash" code Four tests contains repetitive lines of code. Factor out common code into test_pull_autostash() and then call it in these tests. Helped-by: Eric Sunshine Signed-off-by: Mehul Jain Reviewed-by: Eric Sunshine Signed-off-by: Junio C Hamano --- t/t5520-pull.sh | 44 +++++++++++++++----------------------------- 1 file changed, 15 insertions(+), 29 deletions(-) diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index d03cb842e2..0b52a3497e 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -9,6 +9,16 @@ modify () { mv "$2.x" "$2" } +test_pull_autostash () { + git reset --hard before-rebase && + echo dirty >new_file && + git add new_file && + git pull "$@" . copy && + test_cmp_rev HEAD^ copy && + test "$(cat new_file)" = dirty && + test "$(cat file)" = "modified again" +} + test_expect_success setup ' echo file >file && git add file && @@ -247,46 +257,22 @@ test_expect_success '--rebase fails with multiple branches' ' test_expect_success 'pull --rebase succeeds with dirty working directory and rebase.autostash set' ' test_config rebase.autostash true && - git reset --hard before-rebase && - echo dirty >new_file && - git add new_file && - git pull --rebase . copy && - test_cmp_rev HEAD^ copy && - test "$(cat new_file)" = dirty && - test "$(cat file)" = "modified again" + test_pull_autostash --rebase ' test_expect_success 'pull --rebase --autostash & rebase.autostash=true' ' test_config rebase.autostash true && - git reset --hard before-rebase && - echo dirty >new_file && - git add new_file && - git pull --rebase --autostash . copy && - test_cmp_rev HEAD^ copy && - test "$(cat new_file)" = dirty && - test "$(cat file)" = "modified again" + test_pull_autostash --rebase --autostash ' test_expect_success 'pull --rebase --autostash & rebase.autostash=false' ' test_config rebase.autostash false && - git reset --hard before-rebase && - echo dirty >new_file && - git add new_file && - git pull --rebase --autostash . copy && - test_cmp_rev HEAD^ copy && - test "$(cat new_file)" = dirty && - test "$(cat file)" = "modified again" + test_pull_autostash --rebase --autostash ' -test_expect_success 'pull --rebase: --autostash & rebase.autostash unset' ' +test_expect_success 'pull --rebase --autostash & rebase.autostash unset' ' test_unconfig rebase.autostash && - git reset --hard before-rebase && - echo dirty >new_file && - git add new_file && - git pull --rebase --autostash . copy && - test_cmp_rev HEAD^ copy && - test "$(cat new_file)" = dirty && - test "$(cat file)" = "modified again" + test_pull_autostash --rebase --autostash ' test_expect_success 'pull --rebase --no-autostash & rebase.autostash=true' ' -- cgit v1.2.3 From 44a59fff4598f3d2f68b5bc83c75e8483637a33d Mon Sep 17 00:00:00 2001 From: Mehul Jain Date: Sat, 2 Apr 2016 23:28:30 +0530 Subject: t5520: factor out common "failing autostash" code Three tests contains repetitive lines of code. Factor out common code into test_pull_autostash_fail() and then call it in these tests. Helped-by: Eric Sunshine Signed-off-by: Mehul Jain Reviewed-by: Eric Sunshine Signed-off-by: Junio C Hamano --- t/t5520-pull.sh | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 0b52a3497e..7392ee1433 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -19,6 +19,14 @@ test_pull_autostash () { test "$(cat file)" = "modified again" } +test_pull_autostash_fail () { + git reset --hard before-rebase && + echo dirty >new_file && + git add new_file && + test_must_fail git pull "$@" . copy 2>err && + test_i18ngrep "uncommitted changes." err +} + test_expect_success setup ' echo file >file && git add file && @@ -277,29 +285,17 @@ test_expect_success 'pull --rebase --autostash & rebase.autostash unset' ' test_expect_success 'pull --rebase --no-autostash & rebase.autostash=true' ' test_config rebase.autostash true && - git reset --hard before-rebase && - echo dirty >new_file && - git add new_file && - test_must_fail git pull --rebase --no-autostash . copy 2>err && - test_i18ngrep "Cannot pull with rebase: Your index contains uncommitted changes." err + test_pull_autostash_fail --rebase --no-autostash ' test_expect_success 'pull --rebase --no-autostash & rebase.autostash=false' ' test_config rebase.autostash false && - git reset --hard before-rebase && - echo dirty >new_file && - git add new_file && - test_must_fail git pull --rebase --no-autostash . copy 2>err && - test_i18ngrep "Cannot pull with rebase: Your index contains uncommitted changes." err + test_pull_autostash_fail --rebase --no-autostash ' test_expect_success 'pull --rebase --no-autostash & rebase.autostash unset' ' test_unconfig rebase.autostash && - git reset --hard before-rebase && - echo dirty >new_file && - git add new_file && - test_must_fail git pull --rebase --no-autostash . copy 2>err && - test_i18ngrep "Cannot pull with rebase: Your index contains uncommitted changes." err + test_pull_autostash_fail --rebase --no-autostash ' test_expect_success 'pull --autostash (without --rebase) should error out' ' -- cgit v1.2.3 From 16622979f8eaf864da5cf932d3d60de7c7d40d7d Mon Sep 17 00:00:00 2001 From: Mehul Jain Date: Sat, 2 Apr 2016 23:28:31 +0530 Subject: t5520: reduce commom lines of code These two tests are almost similar and thus can be folded in a for-loop. Helped-by: Eric Sunshine Signed-off-by: Mehul Jain Reviewed-by: Eric Sunshine Signed-off-by: Junio C Hamano --- t/t5520-pull.sh | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 7392ee1433..8b0c9d8988 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -298,15 +298,13 @@ test_expect_success 'pull --rebase --no-autostash & rebase.autostash unset' ' test_pull_autostash_fail --rebase --no-autostash ' -test_expect_success 'pull --autostash (without --rebase) should error out' ' - test_must_fail git pull --autostash . copy 2>err && - test_i18ngrep "only valid with --rebase" err -' - -test_expect_success 'pull --no-autostash (without --rebase) should error out' ' - test_must_fail git pull --no-autostash . copy 2>err && - test_i18ngrep "only valid with --rebase" err -' +for i in --autostash --no-autostash +do + test_expect_success "pull $i (without --rebase) is illegal" ' + test_must_fail git pull $i . copy 2>err && + test_i18ngrep "only valid with --rebase" err + ' +done test_expect_success 'pull.rebase' ' git reset --hard before-rebase && -- cgit v1.2.3 From 450dd1dce1fbf6a6743e74d6aef750068fc5069c Mon Sep 17 00:00:00 2001 From: Mehul Jain Date: Sat, 2 Apr 2016 23:28:32 +0530 Subject: t5520: test --[no-]autostash with pull.rebase=true The "--[no-]autostash" options for git-pull are only valid in rebase mode (i.e. either --rebase is used or pull.rebase=true). Existing tests already check the cases when --rebase is used but fail to check for pull.rebase=true case. Add two new tests to check that the --[no-]autostash options work with pull.rebase=true. Signed-off-by: Mehul Jain Reviewed-by: Eric Sunshine Signed-off-by: Junio C Hamano --- t/t5520-pull.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 8b0c9d8988..739c089d50 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -314,6 +314,16 @@ test_expect_success 'pull.rebase' ' test new = "$(git show HEAD:file2)" ' +test_expect_success 'pull --autostash & pull.rebase=true' ' + test_config pull.rebase true && + test_pull_autostash --autostash +' + +test_expect_success 'pull --no-autostash & pull.rebase=true' ' + test_config pull.rebase true && + test_pull_autostash_fail --no-autostash +' + test_expect_success 'branch.to-rebase.rebase' ' git reset --hard before-rebase && test_config branch.to-rebase.rebase true && -- cgit v1.2.3