From b0ad11ea165e07308fc02a5091efbe2e2d22237c Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 14 Oct 2008 15:32:20 -0700 Subject: pull: allow "git pull origin $something:$current_branch" into an unborn branch Some misguided documents floating on the Net suggest this sequence: mkdir newdir && cd newdir git init git remote add origin $url git pull origin master:master "git pull" has known about misguided "pull" that lets the underlying fetch update the current branch for a long time. It also has known about "git pull origin master" into a branch yet to be born. These two workarounds however were not aware of the existence of each other and did not work well together. This fixes it. Signed-off-by: Junio C Hamano --- git-pull.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'git-pull.sh') diff --git a/git-pull.sh b/git-pull.sh index 75c36100a2..664fe34419 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -124,7 +124,7 @@ orig_head=$(git rev-parse --verify HEAD 2>/dev/null) git fetch --update-head-ok "$@" || exit 1 curr_head=$(git rev-parse --verify HEAD 2>/dev/null) -if test "$curr_head" != "$orig_head" +if test -n "$orig_head" && test "$curr_head" != "$orig_head" then # The fetch involved updating the current branch. @@ -172,7 +172,7 @@ esac if test -z "$orig_head" then - git update-ref -m "initial pull" HEAD $merge_head "" && + git update-ref -m "initial pull" HEAD $merge_head "$curr_head" && git read-tree --reset -u HEAD || exit 1 exit fi -- cgit v1.3 From 7f87aff22c0232a5ce327ea3d2923776936c97f4 Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Sat, 15 Nov 2008 01:14:24 +0100 Subject: Teach/Fix pull/fetch -q/-v options Implement git-pull --quiet and git-pull --verbose by adding the options to git-pull and fixing verbosity handling in git-fetch. Signed-off-by: Junio C Hamano --- Documentation/merge-options.txt | 8 ++++++ builtin-fetch.c | 19 +++++++------ builtin-merge.c | 21 ++++++++++----- git-pull.sh | 10 ++++--- parse-options.c | 22 +++++++++++++++ parse-options.h | 6 +++++ t/t5521-pull-options.sh | 60 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 126 insertions(+), 20 deletions(-) create mode 100755 t/t5521-pull-options.sh (limited to 'git-pull.sh') diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt index 007909a82f..427cdefd01 100644 --- a/Documentation/merge-options.txt +++ b/Documentation/merge-options.txt @@ -1,3 +1,11 @@ +-q:: +--quiet:: + Operate quietly. + +-v:: +--verbose:: + Be verbose. + --stat:: Show a diffstat at the end of the merge. The diffstat is also controlled by the configuration option merge.stat. diff --git a/builtin-fetch.c b/builtin-fetch.c index f151cfa2fd..7568163af2 100644 --- a/builtin-fetch.c +++ b/builtin-fetch.c @@ -22,7 +22,7 @@ enum { TAGS_SET = 2 }; -static int append, force, keep, update_head_ok, verbose, quiet; +static int append, force, keep, update_head_ok, verbosity; static int tags = TAGS_DEFAULT; static const char *depth; static const char *upload_pack; @@ -30,8 +30,7 @@ static struct strbuf default_rla = STRBUF_INIT; static struct transport *transport; static struct option builtin_fetch_options[] = { - OPT__QUIET(&quiet), - OPT__VERBOSE(&verbose), + OPT__VERBOSITY(&verbosity), OPT_BOOLEAN('a', "append", &append, "append to .git/FETCH_HEAD instead of overwriting"), OPT_STRING(0, "upload-pack", &upload_pack, "PATH", @@ -192,7 +191,6 @@ static int s_update_ref(const char *action, static int update_local_ref(struct ref *ref, const char *remote, - int verbose, char *display) { struct commit *current = NULL, *updated; @@ -210,7 +208,7 @@ static int update_local_ref(struct ref *ref, die("object %s not found", sha1_to_hex(ref->new_sha1)); if (!hashcmp(ref->old_sha1, ref->new_sha1)) { - if (verbose) + if (verbosity > 0) sprintf(display, "= %-*s %-*s -> %s", SUMMARY_WIDTH, "[up to date]", REFCOL_WIDTH, remote, pretty_ref); @@ -366,18 +364,19 @@ static int store_updated_refs(const char *url, const char *remote_name, note); if (ref) - rc |= update_local_ref(ref, what, verbose, note); + rc |= update_local_ref(ref, what, note); else sprintf(note, "* %-*s %-*s -> FETCH_HEAD", SUMMARY_WIDTH, *kind ? kind : "branch", REFCOL_WIDTH, *what ? what : "HEAD"); if (*note) { - if (!shown_url) { + if (verbosity >= 0 && !shown_url) { fprintf(stderr, "From %.*s\n", url_len, url); shown_url = 1; } - fprintf(stderr, " %s\n", note); + if (verbosity >= 0) + fprintf(stderr, " %s\n", note); } } fclose(fp); @@ -637,9 +636,9 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) remote = remote_get(argv[0]); transport = transport_get(remote, remote->url[0]); - if (verbose >= 2) + if (verbosity >= 2) transport->verbose = 1; - if (quiet) + if (verbosity < 0) transport->verbose = -1; if (upload_pack) set_option(TRANS_OPT_UPLOADPACK, upload_pack); diff --git a/builtin-merge.c b/builtin-merge.c index 5e7910bd8d..7c2b90c70b 100644 --- a/builtin-merge.c +++ b/builtin-merge.c @@ -50,6 +50,7 @@ static unsigned char head[20], stash[20]; static struct strategy **use_strategies; static size_t use_strategies_nr, use_strategies_alloc; static const char *branch; +static int verbosity; static struct strategy all_strategy[] = { { "recursive", DEFAULT_TWOHEAD | NO_TRIVIAL }, @@ -171,6 +172,7 @@ static struct option builtin_merge_options[] = { OPT_CALLBACK('m', "message", &merge_msg, "message", "message to be used for the merge commit (if any)", option_parse_message), + OPT__VERBOSITY(&verbosity), OPT_END() }; @@ -250,7 +252,8 @@ static void restore_state(void) /* This is called when no merge was necessary. */ static void finish_up_to_date(const char *msg) { - printf("%s%s\n", squash ? " (nothing to squash)" : "", msg); + if (verbosity >= 0) + printf("%s%s\n", squash ? " (nothing to squash)" : "", msg); drop_save(); } @@ -331,14 +334,15 @@ static void finish(const unsigned char *new_head, const char *msg) if (!msg) strbuf_addstr(&reflog_message, getenv("GIT_REFLOG_ACTION")); else { - printf("%s\n", msg); + if (verbosity >= 0) + printf("%s\n", msg); strbuf_addf(&reflog_message, "%s: %s", getenv("GIT_REFLOG_ACTION"), msg); } if (squash) { squash_message(); } else { - if (!merge_msg.len) + if (verbosity >= 0 && !merge_msg.len) printf("No merge message -- not updating HEAD\n"); else { const char *argv_gc_auto[] = { "gc", "--auto", NULL }; @@ -872,6 +876,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, builtin_merge_options, builtin_merge_usage, 0); + if (verbosity < 0) + show_diffstat = 0; if (squash) { if (!allow_fast_forward) @@ -1013,10 +1019,11 @@ int cmd_merge(int argc, const char **argv, const char *prefix) strcpy(hex, find_unique_abbrev(head, DEFAULT_ABBREV)); - printf("Updating %s..%s\n", - hex, - find_unique_abbrev(remoteheads->item->object.sha1, - DEFAULT_ABBREV)); + if (verbosity >= 0) + printf("Updating %s..%s\n", + hex, + find_unique_abbrev(remoteheads->item->object.sha1, + DEFAULT_ABBREV)); strbuf_addstr(&msg, "Fast forward"); if (have_message) strbuf_addstr(&msg, diff --git a/git-pull.sh b/git-pull.sh index 664fe34419..8866f2a1e2 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -16,13 +16,17 @@ cd_to_toplevel test -z "$(git ls-files -u)" || die "You are in the middle of a conflicted merge." -strategy_args= no_stat= no_commit= squash= no_ff= log_arg= +strategy_args= no_stat= no_commit= squash= no_ff= log_arg= verbosity= curr_branch=$(git symbolic-ref -q HEAD) curr_branch_short=$(echo "$curr_branch" | sed "s|refs/heads/||") rebase=$(git config --bool branch.$curr_branch_short.rebase) while : do case "$1" in + -q|--quiet) + verbosity=-q ;; + -v|--verbose) + verbosity=-v ;; -n|--no-stat|--no-summary) no_stat=-n ;; --stat|--summary) @@ -121,7 +125,7 @@ test true = "$rebase" && { "refs/remotes/$origin/$reflist" 2>/dev/null)" } orig_head=$(git rev-parse --verify HEAD 2>/dev/null) -git fetch --update-head-ok "$@" || exit 1 +git fetch $verbosity --update-head-ok "$@" || exit 1 curr_head=$(git rev-parse --verify HEAD 2>/dev/null) if test -n "$orig_head" && test "$curr_head" != "$orig_head" @@ -182,4 +186,4 @@ test true = "$rebase" && exec git-rebase $strategy_args --onto $merge_head \ ${oldremoteref:-$merge_head} exec git-merge $no_stat $no_commit $squash $no_ff $log_arg $strategy_args \ - "$merge_name" HEAD $merge_head + "$merge_name" HEAD $merge_head $verbosity diff --git a/parse-options.c b/parse-options.c index fd08bb425c..9eb55cc8b5 100644 --- a/parse-options.c +++ b/parse-options.c @@ -484,6 +484,28 @@ int parse_opt_approxidate_cb(const struct option *opt, const char *arg, return 0; } +int parse_opt_verbosity_cb(const struct option *opt, const char *arg, + int unset) +{ + int *target = opt->value; + + if (unset) + /* --no-quiet, --no-verbose */ + *target = 0; + else if (opt->short_name == 'v') { + if (*target >= 0) + (*target)++; + else + *target = 1; + } else { + if (*target <= 0) + (*target)--; + else + *target = -1; + } + return 0; +} + /* * This should really be OPTION_FILENAME type as a part of * parse_options that take prefix to do this while parsing. diff --git a/parse-options.h b/parse-options.h index 5199950c00..034162ec69 100644 --- a/parse-options.h +++ b/parse-options.h @@ -150,9 +150,15 @@ extern int parse_options_end(struct parse_opt_ctx_t *ctx); /*----- some often used options -----*/ extern int parse_opt_abbrev_cb(const struct option *, const char *, int); extern int parse_opt_approxidate_cb(const struct option *, const char *, int); +extern int parse_opt_verbosity_cb(const struct option *, const char *, int); #define OPT__VERBOSE(var) OPT_BOOLEAN('v', "verbose", (var), "be verbose") #define OPT__QUIET(var) OPT_BOOLEAN('q', "quiet", (var), "be quiet") +#define OPT__VERBOSITY(var) \ + { OPTION_CALLBACK, 'v', "verbose", (var), NULL, "be more verbose", \ + PARSE_OPT_NOARG, &parse_opt_verbosity_cb, 0 }, \ + { OPTION_CALLBACK, 'q', "quiet", (var), NULL, "be more quiet", \ + PARSE_OPT_NOARG, &parse_opt_verbosity_cb, 0 } #define OPT__DRY_RUN(var) OPT_BOOLEAN('n', "dry-run", (var), "dry run") #define OPT__ABBREV(var) \ { OPTION_CALLBACK, 0, "abbrev", (var), "n", \ diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh new file mode 100755 index 0000000000..83e2e8ab80 --- /dev/null +++ b/t/t5521-pull-options.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +test_description='pull options' + +. ./test-lib.sh + +D=`pwd` + +test_expect_success 'setup' ' + mkdir parent && + (cd parent && git init && + echo one >file && git add file && + git commit -m one) +' + +cd "$D" + +test_expect_success 'git pull -q' ' + mkdir clonedq && + cd clonedq && + git pull -q "$D/parent" >out 2>err && + test ! -s out +' + +cd "$D" + +test_expect_success 'git pull' ' + mkdir cloned && + cd cloned && + git pull "$D/parent" >out 2>err && + test -s out +' +cd "$D" + +test_expect_success 'git pull -v' ' + mkdir clonedv && + cd clonedv && + git pull -v "$D/parent" >out 2>err && + test -s out +' + +cd "$D" + +test_expect_success 'git pull -v -q' ' + mkdir clonedvq && + cd clonedvq && + git pull -v -q "$D/parent" >out 2>err && + test ! -s out +' + +cd "$D" + +test_expect_success 'git pull -q -v' ' + mkdir clonedqv && + cd clonedqv && + git pull -q -v "$D/parent" >out 2>err && + test -s out +' + +test_done -- cgit v1.3 From c6576f912fc34193a02d7ec587484f7c2ce3fe77 Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Mon, 17 Nov 2008 23:09:30 +0100 Subject: Retain multiple -q/-v occurrences in git pull To support counting -q/-v options in git pull retain them by concatenating. Signed-off-by: Tuncer Ayaz Signed-off-by: Junio C Hamano --- git-pull.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'git-pull.sh') diff --git a/git-pull.sh b/git-pull.sh index 8866f2a1e2..1cac898a24 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -24,9 +24,9 @@ while : do case "$1" in -q|--quiet) - verbosity=-q ;; + verbosity="$verbosity -q" ;; -v|--verbose) - verbosity=-v ;; + verbosity="$verbosity -v" ;; -n|--no-stat|--no-summary) no_stat=-n ;; --stat|--summary) -- cgit v1.3 From 2d17985782256d3505791a814b16e4e772fd341f Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Wed, 3 Dec 2008 14:26:50 +0100 Subject: pull: use git rev-parse -q Signed-off-by: Miklos Vajna Signed-off-by: Junio C Hamano --- git-pull.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'git-pull.sh') diff --git a/git-pull.sh b/git-pull.sh index 1cac898a24..2c7f432dc0 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -121,13 +121,13 @@ test true = "$rebase" && { test -z "$origin" && origin=$(get_default_remote) reflist="$(get_remote_refs_for_fetch "$@" 2>/dev/null | sed "s|refs/heads/\(.*\):|\1|")" && - oldremoteref="$(git rev-parse --verify \ - "refs/remotes/$origin/$reflist" 2>/dev/null)" + oldremoteref="$(git rev-parse -q --verify \ + "refs/remotes/$origin/$reflist")" } -orig_head=$(git rev-parse --verify HEAD 2>/dev/null) +orig_head=$(git rev-parse -q --verify HEAD) git fetch $verbosity --update-head-ok "$@" || exit 1 -curr_head=$(git rev-parse --verify HEAD 2>/dev/null) +curr_head=$(git rev-parse -q --verify HEAD) if test -n "$orig_head" && test "$curr_head" != "$orig_head" then # The fetch involved updating the current branch. -- cgit v1.3 From 51b2ead03c8cdc0ddeeca2fb5db14b7bac584337 Mon Sep 17 00:00:00 2001 From: Jay Soffian Date: Wed, 18 Feb 2009 08:44:02 -0500 Subject: disallow providing multiple upstream branches to rebase, pull --rebase It does not make sense to provide multiple upstream branches to either git pull --rebase, or to git rebase, so disallow both. Signed-off-by: Jay Soffian Signed-off-by: Junio C Hamano --- git-pull.sh | 5 +++++ git-rebase.sh | 1 + 2 files changed, 6 insertions(+) (limited to 'git-pull.sh') diff --git a/git-pull.sh b/git-pull.sh index 2c7f432dc0..25adddfddf 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -171,6 +171,11 @@ case "$merge_head" in echo >&2 "Cannot merge multiple branches into empty head" exit 1 fi + if test true = "$rebase" + then + echo >&2 "Cannot rebase onto multiple branches" + exit 1 + fi ;; esac diff --git a/git-rebase.sh b/git-rebase.sh index 6d3eddbada..368c0ef434 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -310,6 +310,7 @@ do esac shift done +test $# -gt 2 && usage # Make sure we do not have $GIT_DIR/rebase-apply if test -z "$do_merge" -- cgit v1.3 From a334e1254c0c2d55f20b271872fbac9a6a67218b Mon Sep 17 00:00:00 2001 From: Tor Arne Vestbø Date: Sun, 1 Mar 2009 22:28:28 +0100 Subject: git-pull: Allow --stat and --no-stat to be used with --rebase MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Forwards the --stat, --no-stat, and --summary options on to git-rebase. Signed-off-by: Tor Arne Vestbø Signed-off-by: Junio C Hamano --- git-pull.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'git-pull.sh') diff --git a/git-pull.sh b/git-pull.sh index 25adddfddf..8a26763206 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -16,7 +16,7 @@ cd_to_toplevel test -z "$(git ls-files -u)" || die "You are in the middle of a conflicted merge." -strategy_args= no_stat= no_commit= squash= no_ff= log_arg= verbosity= +strategy_args= diffstat= no_commit= squash= no_ff= log_arg= verbosity= curr_branch=$(git symbolic-ref -q HEAD) curr_branch_short=$(echo "$curr_branch" | sed "s|refs/heads/||") rebase=$(git config --bool branch.$curr_branch_short.rebase) @@ -28,9 +28,9 @@ do -v|--verbose) verbosity="$verbosity -v" ;; -n|--no-stat|--no-summary) - no_stat=-n ;; + diffstat=--no-stat ;; --stat|--summary) - no_stat=$1 ;; + diffstat=--stat ;; --log|--no-log) log_arg=$1 ;; --no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit) @@ -188,7 +188,7 @@ fi merge_name=$(git fmt-merge-msg $log_arg <"$GIT_DIR/FETCH_HEAD") || exit test true = "$rebase" && - exec git-rebase $strategy_args --onto $merge_head \ + exec git-rebase $diffstat $strategy_args --onto $merge_head \ ${oldremoteref:-$merge_head} -exec git-merge $no_stat $no_commit $squash $no_ff $log_arg $strategy_args \ +exec git-merge $diffstat $no_commit $squash $no_ff $log_arg $strategy_args \ "$merge_name" HEAD $merge_head $verbosity -- cgit v1.3 From 61e6108d94353d932d397e4be498c7e5293723eb Mon Sep 17 00:00:00 2001 From: Matthieu Moy Date: Wed, 8 Apr 2009 09:24:03 +0200 Subject: git-pull.sh: better warning message for "git pull" on detached head. Otherwise, git complains about not finding a branch to pull from in 'branch..merge', which is hardly understandable. While we're there, reword the sentences slightly. Signed-off-by: Matthieu Moy Signed-off-by: Junio C Hamano --- git-pull.sh | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) (limited to 'git-pull.sh') diff --git a/git-pull.sh b/git-pull.sh index 25adddfddf..c892059605 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -90,23 +90,31 @@ error_on_no_merge_candidates () { curr_branch=${curr_branch#refs/heads/} - echo "You asked me to pull without telling me which branch you" - echo "want to merge with, and 'branch.${curr_branch}.merge' in" - echo "your configuration file does not tell me either. Please" - echo "name which branch you want to merge on the command line and" - echo "try again (e.g. 'git pull ')." - echo "See git-pull(1) for details on the refspec." - echo - echo "If you often merge with the same branch, you may want to" - echo "configure the following variables in your configuration" - echo "file:" - echo - echo " branch.${curr_branch}.remote = " - echo " branch.${curr_branch}.merge = " - echo " remote..url = " - echo " remote..fetch = " - echo - echo "See git-config(1) for details." + if [ -z "$curr_branch" ]; then + echo "You are not currently on a branch, so I cannot use any" + echo "'branch..merge' in your configuration file." + echo "Please specify which branch you want to merge on the command" + echo "line and try again (e.g. 'git pull ')." + echo "See git-pull(1) for details." + else + echo "You asked me to pull without telling me which branch you" + echo "want to merge with, and 'branch.${curr_branch}.merge' in" + echo "your configuration file does not tell me either. Please" + echo "specify which branch you want to merge on the command line and" + echo "try again (e.g. 'git pull ')." + echo "See git-pull(1) for details." + echo + echo "If you often merge with the same branch, you may want to" + echo "configure the following variables in your configuration" + echo "file:" + echo + echo " branch.${curr_branch}.remote = " + echo " branch.${curr_branch}.merge = " + echo " remote..url = " + echo " remote..fetch = " + echo + echo "See git-config(1) for details." + fi exit 1 } -- cgit v1.3 From 7bd93c1c625ce5fa03f0d13d728f34f8ab868991 Mon Sep 17 00:00:00 2001 From: Dan Loewenherz Date: Wed, 22 Apr 2009 21:46:02 -0400 Subject: Convert to use quiet option when available A minor fix that eliminates usage of "2>/dev/null" when --quiet or -q has already been implemented. Signed-off-by: Dan Loewenherz Signed-off-by: Junio C Hamano --- git-filter-branch.sh | 2 +- git-merge-resolve.sh | 4 ++-- git-parse-remote.sh | 2 +- git-pull.sh | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'git-pull.sh') diff --git a/git-filter-branch.sh b/git-filter-branch.sh index b90d3df3a7..37e044db40 100755 --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@ -430,7 +430,7 @@ if [ "$filter_tag_name" ]; then if [ "$type" = "tag" ]; then # Dereference to a commit sha1t="$sha1" - sha1="$(git rev-parse "$sha1"^{commit} 2>/dev/null)" || continue + sha1="$(git rev-parse -q "$sha1"^{commit})" || continue fi [ -f "../map/$sha1" ] || continue diff --git a/git-merge-resolve.sh b/git-merge-resolve.sh index 93bcfc2f5d..c9da747fcf 100755 --- a/git-merge-resolve.sh +++ b/git-merge-resolve.sh @@ -37,10 +37,10 @@ then exit 2 fi -git update-index --refresh 2>/dev/null +git update-index -q --refresh git read-tree -u -m --aggressive $bases $head $remotes || exit 2 echo "Trying simple merge." -if result_tree=$(git write-tree 2>/dev/null) +if result_tree=$(git write-tree 2>/dev/null) then exit 0 else diff --git a/git-parse-remote.sh b/git-parse-remote.sh index 695a4094bb..a296719861 100755 --- a/git-parse-remote.sh +++ b/git-parse-remote.sh @@ -2,7 +2,7 @@ # git-ls-remote could be called from outside a git managed repository; # this would fail in that case and would issue an error message. -GIT_DIR=$(git rev-parse --git-dir 2>/dev/null) || :; +GIT_DIR=$(git rev-parse -q --git-dir) || :; get_data_source () { case "$1" in diff --git a/git-pull.sh b/git-pull.sh index 8c750270e9..35261539ab 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -147,7 +147,7 @@ then echo >&2 "Warning: fetch updated the current branch head." echo >&2 "Warning: fast forwarding your working tree from" echo >&2 "Warning: commit $orig_head." - git update-index --refresh 2>/dev/null + git update-index -q --refresh git read-tree -u -m "$orig_head" "$curr_head" || die 'Cannot fast-forward your working tree. After making sure that you saved anything precious from -- cgit v1.3 From 97af7ff0553ed81bb905dbc0c8b0f9a0c10bfb3d Mon Sep 17 00:00:00 2001 From: Santi Béjar Date: Fri, 12 Jun 2009 00:39:18 +0200 Subject: parse-remote: function to get the tracking branch to be merge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The only user of get_remote_refs_for_fetch was "git pull --rebase" and it only wanted the tracking branch to be merge. So, add a simple function (get_remote_merge_branch) with this new meaning. No behavior changes. The new function behaves like the old code in "git pull --rebase". In particular, it only works with the default refspec mapping and with remote branches, not tags. Signed-off-by: Santi Béjar Signed-off-by: Junio C Hamano --- git-parse-remote.sh | 29 +++++++++++++++++++++++++++++ git-pull.sh | 7 ++----- 2 files changed, 31 insertions(+), 5 deletions(-) (limited to 'git-pull.sh') diff --git a/git-parse-remote.sh b/git-parse-remote.sh index a296719861..a991564b95 100755 --- a/git-parse-remote.sh +++ b/git-parse-remote.sh @@ -229,6 +229,34 @@ get_remote_refs_for_fetch () { esac } +get_remote_merge_branch () { + case "$#" in + 0|1) + die "internal error: get-remote-merge-branch." ;; + *) + repo=$1 + shift + ref=$1 + # FIXME: It should return the tracking branch + # Currently only works with the default mapping + case "$ref" in + +*) + ref=$(expr "z$ref" : 'z+\(.*\)') + ;; + esac + expr "z$ref" : 'z.*:' >/dev/null || ref="${ref}:" + remote=$(expr "z$ref" : 'z\([^:]*\):') + case "$remote" in + '' | HEAD ) remote=HEAD ;; + heads/*) remote=${remote#heads/} ;; + refs/heads/*) remote=${remote#refs/heads/} ;; + refs/* | tags/* | remotes/* ) remote= + esac + + [ -n "$remote" ] && echo "refs/remotes/$repo/$remote" + esac +} + resolve_alternates () { # original URL (xxx.git) top_=`expr "z$1" : 'z\([^:]*:/*[^/]*\)/'` @@ -262,3 +290,4 @@ get_uploadpack () { ;; esac } + diff --git a/git-pull.sh b/git-pull.sh index 35261539ab..3cf26634ad 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -125,12 +125,9 @@ test true = "$rebase" && { die "refusing to pull with rebase: your working tree is not up-to-date" . git-parse-remote && - origin="$1" - test -z "$origin" && origin=$(get_default_remote) - reflist="$(get_remote_refs_for_fetch "$@" 2>/dev/null | - sed "s|refs/heads/\(.*\):|\1|")" && + reflist="$(get_remote_merge_branch "$@" 2>/dev/null)" && oldremoteref="$(git rev-parse -q --verify \ - "refs/remotes/$origin/$reflist")" + "$reflist")" } orig_head=$(git rev-parse -q --verify HEAD) git fetch $verbosity --update-head-ok "$@" || exit 1 -- cgit v1.3 From bc2bbc4542a220da5d28c432b6bf78a845a421c0 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Sun, 14 Jun 2009 16:08:56 -0700 Subject: pull, rebase: simplify to use die() Signed-off-by: Stephen Boyd Signed-off-by: Junio C Hamano --- git-pull.sh | 6 ++---- git-rebase.sh | 9 +++------ 2 files changed, 5 insertions(+), 10 deletions(-) (limited to 'git-pull.sh') diff --git a/git-pull.sh b/git-pull.sh index 35261539ab..cab367ada0 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -176,13 +176,11 @@ case "$merge_head" in ?*' '?*) if test -z "$orig_head" then - echo >&2 "Cannot merge multiple branches into empty head" - exit 1 + die "Cannot merge multiple branches into empty head" fi if test true = "$rebase" then - echo >&2 "Cannot rebase onto multiple branches" - exit 1 + die "Cannot rebase onto multiple branches" fi ;; esac diff --git a/git-rebase.sh b/git-rebase.sh index b83fd3f970..334629fc97 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -168,10 +168,8 @@ run_pre_rebase_hook () { if test -z "$OK_TO_SKIP_PRE_REBASE" && test -x "$GIT_DIR/hooks/pre-rebase" then - "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || { - echo >&2 "The pre-rebase hook refused to rebase." - exit 1 - } + "$GIT_DIR/hooks/pre-rebase" ${1+"$@"} || + die "The pre-rebase hook refused to rebase." fi } @@ -359,8 +357,7 @@ fi # The tree must be really really clean. if ! git update-index --ignore-submodules --refresh; then - echo >&2 "cannot rebase: you have unstaged changes" - exit 1 + die "cannot rebase: you have unstaged changes" fi diff=$(git diff-index --cached --name-status -r --ignore-submodules HEAD --) case "$diff" in -- cgit v1.3 From d44e71261f91d3cc81293e0976bb40daa8abb583 Mon Sep 17 00:00:00 2001 From: Santi Béjar Date: Sun, 19 Jul 2009 09:45:16 +0200 Subject: pull: support rebased upstream + fetch + pull --rebase MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit You cannot do a "git pull --rebase" with a rebased upstream, if you have already run "git fetch". Try to behave as if the "git fetch" was not run. In other words, find the fork point of the current branch, where the tip of upstream branch used to be, and use it as the upstream parameter of "git rebase". This patch computes the fork point by walking the reflog to find the first commit which is an ancestor of the current branch. Maybe there are smarter ways to compute it, but this is a straight forward implementation. Signed-off-by: Santi Béjar Signed-off-by: Junio C Hamano --- git-pull.sh | 14 +++++++++++--- t/t5520-pull.sh | 5 ++--- 2 files changed, 13 insertions(+), 6 deletions(-) (limited to 'git-pull.sh') diff --git a/git-pull.sh b/git-pull.sh index 4b78a0cd37..0f24182974 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -124,10 +124,18 @@ test true = "$rebase" && { git diff-index --ignore-submodules --cached --quiet HEAD -- || die "refusing to pull with rebase: your working tree is not up-to-date" + oldremoteref= && . git-parse-remote && - reflist="$(get_remote_merge_branch "$@" 2>/dev/null)" && - oldremoteref="$(git rev-parse -q --verify \ - "$reflist")" + remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)" && + oldremoteref="$(git rev-parse -q --verify "$remoteref")" && + for reflog in $(git rev-list -g $remoteref 2>/dev/null) + do + if test "$reflog" = "$(git merge-base $reflog $curr_branch)" + then + oldremoteref="$reflog" + break + fi + done } orig_head=$(git rev-parse -q --verify HEAD) git fetch $verbosity --update-head-ok "$@" || exit 1 diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 3ebc886bdc..e78d40242a 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -117,15 +117,14 @@ test_expect_success '--rebase with rebased default upstream' ' ' -test_expect_failure 'rebased upstream + fetch + pull --rebase' ' +test_expect_success 'rebased upstream + fetch + pull --rebase' ' git update-ref refs/remotes/me/copy copy-orig && git reset --hard to-rebase-orig && git checkout --track -b to-rebase3 me/copy && git reset --hard to-rebase-orig && git fetch && - test_must_fail git pull --rebase && - git rebase --abort && + git pull --rebase && test "conflicting modification" = "$(cat file)" && test file = "$(cat file2)" -- cgit v1.3 From 19a7fcbf16276321f83e0c1748b3935a2ea42675 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Tue, 11 Aug 2009 23:27:40 -0400 Subject: allow pull --rebase on branch yet to be born When doing a "pull --rebase", we check to make sure that the index and working tree are clean. The index-clean check compares the index against HEAD. The test erroneously reports dirtiness if we don't have a HEAD yet. In such an "unborn branch" case, by definition, a non-empty index won't be based on whatever we are pulling down from the remote, and will lose the local change. Just check if $GIT_DIR/index exists and error out. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- git-pull.sh | 18 +++++++++++++----- t/t5520-pull.sh | 11 +++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) (limited to 'git-pull.sh') diff --git a/git-pull.sh b/git-pull.sh index 0f24182974..0bbd5bf7df 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -119,11 +119,19 @@ error_on_no_merge_candidates () { } test true = "$rebase" && { - git update-index --ignore-submodules --refresh && - git diff-files --ignore-submodules --quiet && - git diff-index --ignore-submodules --cached --quiet HEAD -- || - die "refusing to pull with rebase: your working tree is not up-to-date" - + if ! git rev-parse -q --verify HEAD >/dev/null + then + # On an unborn branch + if test -f "$GIT_DIR/index" + then + die "updating an unborn branch with changes added to the index" + fi + else + git update-index --ignore-submodules --refresh && + git diff-files --ignore-submodules --quiet && + git diff-index --ignore-submodules --cached --quiet HEAD -- || + die "refusing to pull with rebase: your working tree is not up-to-date" + fi oldremoteref= && . git-parse-remote && remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)" && diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index e78d40242a..dd2ee842e0 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -149,4 +149,15 @@ test_expect_success 'pull --rebase dies early with dirty working directory' ' ' +test_expect_success 'pull --rebase works on branch yet to be born' ' + git rev-parse master >expect && + mkdir empty_repo && + (cd empty_repo && + git init && + git pull --rebase .. master && + git rev-parse HEAD >../actual + ) && + test_cmp expect actual +' + test_done -- cgit v1.3 From a6dbf8814f433a7fbfa9cde6333c98019f6db1e4 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 13 Sep 2009 13:38:48 -0700 Subject: pull: Clarify "helpful" message for another corner case When the remote branch we asked for merging did not exist in the set of fetched refs, we unconditionally hinted that it was because of lack of configuration. It is not necessarily so, and risks sending users for a wild goose chase. Make sure to check if that is indeed the case before telling a wild guess to the user. Signed-off-by: Junio C Hamano --- git-pull.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'git-pull.sh') diff --git a/git-pull.sh b/git-pull.sh index 0bbd5bf7df..edf3ce33bf 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -89,6 +89,7 @@ error_on_no_merge_candidates () { done curr_branch=${curr_branch#refs/heads/} + upstream=$(git config "branch.$curr_branch.merge") if [ -z "$curr_branch" ]; then echo "You are not currently on a branch, so I cannot use any" @@ -96,7 +97,7 @@ error_on_no_merge_candidates () { echo "Please specify which branch you want to merge on the command" echo "line and try again (e.g. 'git pull ')." echo "See git-pull(1) for details." - else + elif [ -z "$upstream" ]; then echo "You asked me to pull without telling me which branch you" echo "want to merge with, and 'branch.${curr_branch}.merge' in" echo "your configuration file does not tell me either. Please" @@ -114,6 +115,10 @@ error_on_no_merge_candidates () { echo " remote..fetch = " echo echo "See git-config(1) for details." + else + echo "Your configuration specifies to merge the ref" + echo "'${upstream#refs/heads/}' from the remote, but no such ref" + echo "was fetched." fi exit 1 } -- cgit v1.3 From 4973aa2286110fcedc0e8ff0da57c10509fb1a65 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 5 Oct 2009 12:03:25 -0700 Subject: git-pull: dead code removal Back when a74b170 (git-pull: disallow implicit merging to detached HEAD, 2007-01-15) added this check, $? referred to the error status of reading HEAD as a symbolic-ref; but cd67e4d (Teach 'git pull' about --rebase, 2007-11-28) moved the command away from where the check is, and nobody noticed the breakage. Ever since, $? has always been 0 (tr at the end of the pipe to find merge_head never fails) and other case arms were never reached. These days, error_on_no_merge_candidates function is prepared to handle a detached HEAD case, which was what the code this patch removes used to handle. Signed-off-by: Junio C Hamano --- git-pull.sh | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'git-pull.sh') diff --git a/git-pull.sh b/git-pull.sh index edf3ce33bf..66d73eb59d 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -182,14 +182,7 @@ merge_head=$(sed -e '/ not-for-merge /d' \ case "$merge_head" in '') - case $? in - 0) error_on_no_merge_candidates "$@";; - 1) echo >&2 "You are not currently on a branch; you must explicitly" - echo >&2 "specify which branch you wish to merge:" - echo >&2 " git pull " - exit 1;; - *) exit $?;; - esac + error_on_no_merge_candidates "$@" ;; ?*' '?*) if test -z "$orig_head" -- cgit v1.3 From a8c9bef4e0b87e596f37ec238991b447c739dee9 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Mon, 5 Oct 2009 15:35:16 -0400 Subject: pull: improve advice for unconfigured error case There are several reasons a git-pull invocation might not have anything marked for merge: 1. We're not on a branch, so there is no branch configuration. 2. We're on a branch, but there is no configuration for this branch. 3. We fetched from the configured remote, but the configured branch to merge didn't get fetched (either it doesn't exist, or wasn't part of the fetch refspec). 4. We fetched from the non-default remote, but didn't specify a branch to merge. We can't use the configured one because it applies to the default remote. 5. We fetched from a specified remote, and a refspec was given, but it ended up not fetching anything (this is actually hard to do; if the refspec points to a remote branch and it doesn't exist, then fetch will fail and we never make it to this code path. But if you provide a wildcard refspec like refs/bogus/*:refs/remotes/origin/* then you can see this failure). We have handled (1) and (2) for some time. Recently, commit a6dbf88 added code to handle case (3). This patch handles cases (4) and (5), which previously just fell under other cases, producing a confusing message. While we're at it, let's rewrap the text for case (3), which looks terribly ugly as it is. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- git-pull.sh | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'git-pull.sh') diff --git a/git-pull.sh b/git-pull.sh index 66d73eb59d..fc78592ae0 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -90,8 +90,17 @@ error_on_no_merge_candidates () { curr_branch=${curr_branch#refs/heads/} upstream=$(git config "branch.$curr_branch.merge") + remote=$(git config "branch.$curr_branch.remote") - if [ -z "$curr_branch" ]; then + if [ $# -gt 1 ]; then + echo "There are no candidates for merging in the refs that you just fetched." + echo "Generally this means that you provided a wildcard refspec which had no" + echo "matches on the remote end." + elif [ $# -gt 0 ] && [ "$1" != "$remote" ]; then + echo "You asked to pull from the remote '$1', but did not specify" + echo "a branch to merge. Because this is not the default configured remote" + echo "for your current branch, you must specify a branch on the command line." + elif [ -z "$curr_branch" ]; then echo "You are not currently on a branch, so I cannot use any" echo "'branch..merge' in your configuration file." echo "Please specify which branch you want to merge on the command" @@ -116,9 +125,8 @@ error_on_no_merge_candidates () { echo echo "See git-config(1) for details." else - echo "Your configuration specifies to merge the ref" - echo "'${upstream#refs/heads/}' from the remote, but no such ref" - echo "was fetched." + echo "Your configuration specifies to merge the ref '${upstream#refs/heads/}' from the" + echo "remote, but no such ref was fetched." fi exit 1 } -- cgit v1.3 From a75d7b54097ef0d0945cbe673a9940d6c561f95c Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Sat, 24 Oct 2009 11:31:32 +0300 Subject: Use 'fast-forward' all over the place It's a compound word. Signed-off-by: Felipe Contreras Signed-off-by: Junio C Hamano --- Documentation/config.txt | 2 +- Documentation/git-http-push.txt | 4 ++-- Documentation/git-push.txt | 14 +++++++------- Documentation/git-read-tree.txt | 2 +- Documentation/git-receive-pack.txt | 2 +- Documentation/git-reset.txt | 4 ++-- Documentation/git-send-pack.txt | 4 ++-- Documentation/gitcore-tutorial.txt | 4 ++-- Documentation/githooks.txt | 2 +- Documentation/glossary-content.txt | 4 ++-- Documentation/howto/maintain-git.txt | 2 +- Documentation/howto/revert-branch-rebase.txt | 4 ++-- Documentation/howto/update-hook-example.txt | 2 +- Documentation/pull-fetch-param.txt | 4 ++-- Documentation/user-manual.txt | 14 +++++++------- builtin-fetch--tool.c | 8 ++++---- builtin-fetch.c | 4 ++-- builtin-merge.c | 8 ++++---- builtin-push.c | 2 +- builtin-receive-pack.c | 4 ++-- builtin-remote.c | 2 +- builtin-send-pack.c | 2 +- contrib/examples/git-merge.sh | 8 ++++---- contrib/examples/git-resolve.sh | 2 +- contrib/hooks/post-receive-email | 6 +++--- git-merge-octopus.sh | 2 +- git-pull.sh | 2 +- git-rebase--interactive.sh | 6 +++--- git-rebase.sh | 2 +- t/t1001-read-tree-m-2way.sh | 6 +++--- t/t5505-remote.sh | 2 +- t/t5518-fetch-exit-status.sh | 2 +- t/t6028-merge-up-to-date.sh | 2 +- transport.c | 2 +- unpack-trees.c | 2 +- 35 files changed, 71 insertions(+), 71 deletions(-) (limited to 'git-pull.sh') diff --git a/Documentation/config.txt b/Documentation/config.txt index cd1781498e..52bbafbefa 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -1351,7 +1351,7 @@ receive.denyCurrentBranch:: receive.denyNonFastForwards:: If set to true, git-receive-pack will deny a ref update which is - not a fast forward. Use this to prevent such an update via a push, + not a fast-forward. Use this to prevent such an update via a push, even if that push is forced. This configuration variable is set when initializing a shared repository. diff --git a/Documentation/git-http-push.txt b/Documentation/git-http-push.txt index aef383e0b1..ddf7a18dc4 100644 --- a/Documentation/git-http-push.txt +++ b/Documentation/git-http-push.txt @@ -82,11 +82,11 @@ destination side. Without '--force', the ref is stored at the remote only if does not exist, or is a proper subset (i.e. an -ancestor) of . This check, known as "fast forward check", +ancestor) of . This check, known as "fast-forward check", is performed in order to avoid accidentally overwriting the remote ref and lose other peoples' commits from there. -With '--force', the fast forward check is disabled for all refs. +With '--force', the fast-forward check is disabled for all refs. Optionally, a parameter can be prefixed with a plus '+' sign to disable the fast-forward check only on that ref. diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt index ba6a8a2fb2..1a9d886bb3 100644 --- a/Documentation/git-push.txt +++ b/Documentation/git-push.txt @@ -50,9 +50,9 @@ updated. + The object referenced by is used to update the reference on the remote side, but by default this is only allowed if the -update can fast forward . By having the optional leading `{plus}`, +update can fast-forward . By having the optional leading `{plus}`, you can tell git to update the ref even when the update is not a -fast forward. This does *not* attempt to merge into . See +fast-forward. This does *not* attempt to merge into . See EXAMPLES below for details. + `tag ` means the same as `refs/tags/:refs/tags/`. @@ -60,7 +60,7 @@ EXAMPLES below for details. Pushing an empty allows you to delete the ref from the remote repository. + -The special refspec `:` (or `{plus}:` to allow non-fast forward updates) +The special refspec `:` (or `{plus}:` to allow non-fast-forward updates) directs git to push "matching" branches: for every branch that exists on the local side, the remote side is updated if a branch of the same name already exists on the remote side. This is the default operation mode @@ -171,10 +171,10 @@ summary:: For a successfully pushed ref, the summary shows the old and new values of the ref in a form suitable for using as an argument to `git log` (this is `..` in most cases, and - `...` for forced non-fast forward updates). For a + `...` for forced non-fast-forward updates). For a failed update, more details are given for the failure. The string `rejected` indicates that git did not try to send the - ref at all (typically because it is not a fast forward). The + ref at all (typically because it is not a fast-forward). The string `remote rejected` indicates that the remote end refused the update; this rejection is typically caused by a hook on the remote side. The string `remote failure` indicates that the @@ -342,9 +342,9 @@ git push origin :experimental:: git push origin {plus}dev:master:: Update the origin repository's master branch with the dev branch, - allowing non-fast forward updates. *This can leave unreferenced + allowing non-fast-forward updates. *This can leave unreferenced commits dangling in the origin repository.* Consider the - following situation, where a fast forward is not possible: + following situation, where a fast-forward is not possible: + ---- o---o---o---A---B origin/master diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt index 4a932b08c6..a10ce4ba40 100644 --- a/Documentation/git-read-tree.txt +++ b/Documentation/git-read-tree.txt @@ -144,7 +144,7 @@ Two Tree Merge Typically, this is invoked as `git read-tree -m $H $M`, where $H is the head commit of the current repository, and $M is the head of a foreign tree, which is simply ahead of $H (i.e. we are in a -fast forward situation). +fast-forward situation). When two trees are specified, the user is telling 'git-read-tree' the following: diff --git a/Documentation/git-receive-pack.txt b/Documentation/git-receive-pack.txt index 514f03c979..cb5f405280 100644 --- a/Documentation/git-receive-pack.txt +++ b/Documentation/git-receive-pack.txt @@ -20,7 +20,7 @@ The UI for the protocol is on the 'git-send-pack' side, and the program pair is meant to be used to push updates to remote repository. For pull operations, see linkgit:git-fetch-pack[1]. -The command allows for creation and fast forwarding of sha1 refs +The command allows for creation and fast-forwarding of sha1 refs (heads/tags) on the remote end (strictly speaking, it is the local end 'git-receive-pack' runs, but to the user who is sitting at the send-pack end, it is updating the remote. Confused?) diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt index 469cf6dbac..2d27e405a3 100644 --- a/Documentation/git-reset.txt +++ b/Documentation/git-reset.txt @@ -150,7 +150,7 @@ Automatic merge failed; fix conflicts and then commit the result. $ git reset --hard <2> $ git pull . topic/branch <3> Updating from 41223... to 13134... -Fast forward +Fast-forward $ git reset --hard ORIG_HEAD <4> ------------ + @@ -161,7 +161,7 @@ right now, so you decide to do that later. which is a synonym for "git reset --hard HEAD" clears the mess from the index file and the working tree. <3> Merge a topic branch into the current branch, which resulted -in a fast forward. +in a fast-forward. <4> But you decided that the topic branch is not ready for public consumption yet. "pull" or "merge" always leaves the original tip of the current branch in ORIG_HEAD, so resetting hard to it diff --git a/Documentation/git-send-pack.txt b/Documentation/git-send-pack.txt index 399821832c..5a04c6eaf7 100644 --- a/Documentation/git-send-pack.txt +++ b/Documentation/git-send-pack.txt @@ -105,11 +105,11 @@ name. See linkgit:git-rev-parse[1]. Without '--force', the ref is stored at the remote only if does not exist, or is a proper subset (i.e. an -ancestor) of . This check, known as "fast forward check", +ancestor) of . This check, known as "fast-forward check", is performed in order to avoid accidentally overwriting the remote ref and lose other peoples' commits from there. -With '--force', the fast forward check is disabled for all refs. +With '--force', the fast-forward check is disabled for all refs. Optionally, a parameter can be prefixed with a plus '+' sign to disable the fast-forward check only on that ref. diff --git a/Documentation/gitcore-tutorial.txt b/Documentation/gitcore-tutorial.txt index b3640c4e64..253ef624eb 100644 --- a/Documentation/gitcore-tutorial.txt +++ b/Documentation/gitcore-tutorial.txt @@ -993,7 +993,7 @@ would be different) ---------------- Updating from ae3a2da... to a80b4aa.... -Fast forward (no commit created; -m option ignored) +Fast-forward (no commit created; -m option ignored) example | 1 + hello | 1 + 2 files changed, 2 insertions(+), 0 deletions(-) @@ -1003,7 +1003,7 @@ Because your branch did not contain anything more than what had already been merged into the `master` branch, the merge operation did not actually do a merge. Instead, it just updated the top of the tree of your branch to that of the `master` branch. This is -often called 'fast forward' merge. +often called 'fast-forward' merge. You can run `gitk \--all` again to see how the commit ancestry looks like, or run 'show-branch', which tells you this. diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt index 06e0f315c3..4cc3d1387f 100644 --- a/Documentation/githooks.txt +++ b/Documentation/githooks.txt @@ -229,7 +229,7 @@ from updating that ref. This hook can be used to prevent 'forced' update on certain refs by making sure that the object name is a commit object that is a descendant of the commit object named by the old object name. -That is, to enforce a "fast forward only" policy. +That is, to enforce a "fast-forward only" policy. It could also be used to log the old..new status. However, it does not know the entire set of branches, so it would end up diff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt index 43d84d15e9..1f029f8aa0 100644 --- a/Documentation/glossary-content.txt +++ b/Documentation/glossary-content.txt @@ -124,7 +124,7 @@ to point at the new commit. An evil merge is a <> that introduces changes that do not appear in any <>. -[[def_fast_forward]]fast forward:: +[[def_fast_forward]]fast-forward:: A fast-forward is a special type of <> where you have a <> and you are "merging" another <>'s changes that happen to be a descendant of what @@ -220,7 +220,7 @@ to point at the new commit. conflict, manual intervention may be required to complete the merge. + -As a noun: unless it is a <>, a +As a noun: unless it is a <>, a successful merge results in the creation of a new <> representing the result of the merge, and having as <> the tips of the merged <>. diff --git a/Documentation/howto/maintain-git.txt b/Documentation/howto/maintain-git.txt index 4357e26913..d527b30770 100644 --- a/Documentation/howto/maintain-git.txt +++ b/Documentation/howto/maintain-git.txt @@ -59,7 +59,7 @@ The policy. not yet pass the criteria set for 'next'. - The tips of 'master', 'maint' and 'next' branches will always - fast forward, to allow people to build their own + fast-forward, to allow people to build their own customization on top of them. - Usually 'master' contains all of 'maint', 'next' contains all diff --git a/Documentation/howto/revert-branch-rebase.txt b/Documentation/howto/revert-branch-rebase.txt index e70d8a31e7..8c32da6deb 100644 --- a/Documentation/howto/revert-branch-rebase.txt +++ b/Documentation/howto/revert-branch-rebase.txt @@ -85,7 +85,7 @@ Fortunately I did not have to; what I have in the current branch ------------------------------------------------ $ git checkout master -$ git merge revert-c99 ;# this should be a fast forward +$ git merge revert-c99 ;# this should be a fast-forward Updating from 10d781b9caa4f71495c7b34963bef137216f86a8 to e3a693c... cache.h | 8 ++++---- commit.c | 2 +- @@ -95,7 +95,7 @@ Updating from 10d781b9caa4f71495c7b34963bef137216f86a8 to e3a693c... 5 files changed, 8 insertions(+), 8 deletions(-) ------------------------------------------------ -There is no need to redo the test at this point. We fast forwarded +There is no need to redo the test at this point. We fast-forwarded and we know 'master' matches 'revert-c99' exactly. In fact: ------------------------------------------------ diff --git a/Documentation/howto/update-hook-example.txt b/Documentation/howto/update-hook-example.txt index 697d918885..b7f8d416d6 100644 --- a/Documentation/howto/update-hook-example.txt +++ b/Documentation/howto/update-hook-example.txt @@ -76,7 +76,7 @@ case "$1" in if expr "$2" : '0*$' >/dev/null; then info "The branch '$1' is new..." else - # updating -- make sure it is a fast forward + # updating -- make sure it is a fast-forward mb=$(git-merge-base "$2" "$3") case "$mb,$2" in "$2,$mb") info "Update is fast-forward" ;; diff --git a/Documentation/pull-fetch-param.txt b/Documentation/pull-fetch-param.txt index f9811f2473..44d936341f 100644 --- a/Documentation/pull-fetch-param.txt +++ b/Documentation/pull-fetch-param.txt @@ -11,9 +11,9 @@ + The remote ref that matches is fetched, and if is not empty string, the local -ref that matches it is fast forwarded using . +ref that matches it is fast-forwarded using . If the optional plus `+` is used, the local ref -is updated even if it does not result in a fast forward +is updated even if it does not result in a fast-forward update. + [NOTE] diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt index 67ebffa568..269ec475e6 100644 --- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.txt @@ -1384,7 +1384,7 @@ were merged. However, if the current branch is a descendant of the other--so every commit present in the one is already contained in the other--then git -just performs a "fast forward"; the head of the current branch is moved +just performs a "fast-forward"; the head of the current branch is moved forward to point at the head of the merged-in branch, without any new commits being created. @@ -1719,7 +1719,7 @@ producing a default commit message documenting the branch and repository that you pulled from. (But note that no such commit will be created in the case of a -<>; instead, your branch will just be +<>; instead, your branch will just be updated to point to the latest commit from the upstream branch.) The `git pull` command can also be given "." as the "remote" repository, @@ -1943,7 +1943,7 @@ $ git push ssh://yourserver.com/~you/proj.git master ------------------------------------------------- As with `git fetch`, `git push` will complain if this does not result in a -<>; see the following section for details on +<>; see the following section for details on handling this case. Note that the target of a "push" is normally a @@ -1976,7 +1976,7 @@ details. What to do when a push fails ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If a push would not result in a <> of the +If a push would not result in a <> of the remote branch, then it will fail with an error like: ------------------------------------------------- @@ -2115,7 +2115,7 @@ $ git checkout release && git pull Important note! If you have any local changes in these branches, then this merge will create a commit object in the history (with no local -changes git will simply do a "Fast forward" merge). Many people dislike +changes git will simply do a "fast-forward" merge). Many people dislike the "noise" that this creates in the Linux history, so you should avoid doing this capriciously in the "release" branch, as these noisy commits will become part of the permanent history when you ask Linus to pull @@ -2729,9 +2729,9 @@ In the previous example, when updating an existing branch, "git fetch" checks to make sure that the most recent commit on the remote branch is a descendant of the most recent commit on your copy of the branch before updating your copy of the branch to point at the new -commit. Git calls this process a <>. +commit. Git calls this process a <>. -A fast forward looks something like this: +A fast-forward looks something like this: ................................................ o--o--o--o <-- old head of the branch diff --git a/builtin-fetch--tool.c b/builtin-fetch--tool.c index 3dbdf7a288..cd10dbcbc9 100644 --- a/builtin-fetch--tool.c +++ b/builtin-fetch--tool.c @@ -97,21 +97,21 @@ static int update_local_ref(const char *name, strcpy(newh, find_unique_abbrev(sha1_new, DEFAULT_ABBREV)); if (in_merge_bases(current, &updated, 1)) { - fprintf(stderr, "* %s: fast forward to %s\n", + fprintf(stderr, "* %s: fast-forward to %s\n", name, note); fprintf(stderr, " old..new: %s..%s\n", oldh, newh); - return update_ref_env("fast forward", name, sha1_new, sha1_old); + return update_ref_env("fast-forward", name, sha1_new, sha1_old); } if (!force) { fprintf(stderr, - "* %s: not updating to non-fast forward %s\n", + "* %s: not updating to non-fast-forward %s\n", name, note); fprintf(stderr, " old...new: %s...%s\n", oldh, newh); return 1; } fprintf(stderr, - "* %s: forcing update to non-fast forward %s\n", + "* %s: forcing update to non-fast-forward %s\n", name, note); fprintf(stderr, " old...new: %s...%s\n", oldh, newh); return update_ref_env("forced-update", name, sha1_new, sha1_old); diff --git a/builtin-fetch.c b/builtin-fetch.c index cb48c57ca3..6303aa0f58 100644 --- a/builtin-fetch.c +++ b/builtin-fetch.c @@ -269,7 +269,7 @@ static int update_local_ref(struct ref *ref, strcpy(quickref, find_unique_abbrev(current->object.sha1, DEFAULT_ABBREV)); strcat(quickref, ".."); strcat(quickref, find_unique_abbrev(ref->new_sha1, DEFAULT_ABBREV)); - r = s_update_ref("fast forward", ref, 1); + r = s_update_ref("fast-forward", ref, 1); sprintf(display, "%c %-*s %-*s -> %s%s", r ? '!' : ' ', SUMMARY_WIDTH, quickref, REFCOL_WIDTH, remote, pretty_ref, r ? " (unable to update local ref)" : ""); @@ -287,7 +287,7 @@ static int update_local_ref(struct ref *ref, r ? "unable to update local ref" : "forced update"); return r; } else { - sprintf(display, "! %-*s %-*s -> %s (non fast forward)", + sprintf(display, "! %-*s %-*s -> %s (non-fast-forward)", SUMMARY_WIDTH, "[rejected]", REFCOL_WIDTH, remote, pretty_ref); return 1; diff --git a/builtin-merge.c b/builtin-merge.c index b6b84286b2..a595b8b47b 100644 --- a/builtin-merge.c +++ b/builtin-merge.c @@ -166,7 +166,7 @@ static struct option builtin_merge_options[] = { OPT_BOOLEAN(0, "commit", &option_commit, "perform a commit if the merge succeeds (default)"), OPT_BOOLEAN(0, "ff", &allow_fast_forward, - "allow fast forward (default)"), + "allow fast-forward (default)"), OPT_CALLBACK('s', "strategy", &use_strategies, "strategy", "merge strategy to use", option_parse_strategy), OPT_CALLBACK('m', "message", &merge_msg, "message", @@ -1013,7 +1013,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) hex, find_unique_abbrev(remoteheads->item->object.sha1, DEFAULT_ABBREV)); - strbuf_addstr(&msg, "Fast forward"); + strbuf_addstr(&msg, "Fast-forward"); if (have_message) strbuf_addstr(&msg, " (no commit created; -m option ignored)"); @@ -1031,12 +1031,12 @@ int cmd_merge(int argc, const char **argv, const char *prefix) } else if (!remoteheads->next && common->next) ; /* - * We are not doing octopus and not fast forward. Need + * We are not doing octopus and not fast-forward. Need * a real merge. */ else if (!remoteheads->next && !common->next && option_commit) { /* - * We are not doing octopus, not fast forward, and have + * We are not doing octopus, not fast-forward, and have * only one common. */ refresh_cache(REFRESH_QUIET); diff --git a/builtin-push.c b/builtin-push.c index 3cb1ee46d1..e883574f03 100644 --- a/builtin-push.c +++ b/builtin-push.c @@ -159,7 +159,7 @@ static int do_push(const char *repo, int flags) error("failed to push some refs to '%s'", url[i]); if (nonfastforward && advice_push_nonfastforward) { printf("To prevent you from losing history, non-fast-forward updates were rejected\n" - "Merge the remote changes before pushing again. See the 'non-fast forward'\n" + "Merge the remote changes before pushing again. See the 'non-fast-forward'\n" "section of 'git push --help' for details.\n"); } errs++; diff --git a/builtin-receive-pack.c b/builtin-receive-pack.c index b771fe9b20..fea8fcdd8a 100644 --- a/builtin-receive-pack.c +++ b/builtin-receive-pack.c @@ -329,9 +329,9 @@ static const char *update(struct command *cmd) break; free_commit_list(bases); if (!ent) { - error("denying non-fast forward %s" + error("denying non-fast-forward %s" " (you should pull first)", name); - return "non-fast forward"; + return "non-fast-forward"; } } if (run_update_hook(cmd)) { diff --git a/builtin-remote.c b/builtin-remote.c index 0777dd719b..9aafc19c4d 100644 --- a/builtin-remote.c +++ b/builtin-remote.c @@ -953,7 +953,7 @@ static int show_push_info_item(struct string_list_item *item, void *cb_data) status = "up to date"; break; case PUSH_STATUS_FASTFORWARD: - status = "fast forwardable"; + status = "fast-forwardable"; break; case PUSH_STATUS_OUTOFDATE: status = "local out of date"; diff --git a/builtin-send-pack.c b/builtin-send-pack.c index 37e528e283..37acad5ac1 100644 --- a/builtin-send-pack.c +++ b/builtin-send-pack.c @@ -246,7 +246,7 @@ static int print_one_push_status(struct ref *ref, const char *dest, int count) break; case REF_STATUS_REJECT_NONFASTFORWARD: print_ref_status('!', "[rejected]", ref, ref->peer_ref, - "non-fast forward"); + "non-fast-forward"); break; case REF_STATUS_REMOTE_REJECT: print_ref_status('!', "[remote rejected]", ref, diff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh index e9588eec33..500635fe4b 100755 --- a/contrib/examples/git-merge.sh +++ b/contrib/examples/git-merge.sh @@ -14,7 +14,7 @@ summary (synonym to --stat) log add list of one-line log to merge commit message squash create a single commit instead of doing a merge commit perform a commit if the merge succeeds (default) -ff allow fast forward (default) +ff allow fast-forward (default) s,strategy= merge strategy to use m,message= message to be used for the merge commit (if any) " @@ -353,7 +353,7 @@ t,1,"$head",*) # Again the most common case of merging one remote. echo "Updating $(git rev-parse --short $head)..$(git rev-parse --short $1)" git update-index --refresh 2>/dev/null - msg="Fast forward" + msg="Fast-forward" if test -n "$have_message" then msg="$msg (no commit created; -m option ignored)" @@ -365,11 +365,11 @@ t,1,"$head",*) exit 0 ;; ?,1,?*"$LF"?*,*) - # We are not doing octopus and not fast forward. Need a + # We are not doing octopus and not fast-forward. Need a # real merge. ;; ?,1,*,) - # We are not doing octopus, not fast forward, and have only + # We are not doing octopus, not fast-forward, and have only # one common. git update-index --refresh 2>/dev/null case "$allow_trivial_merge" in diff --git a/contrib/examples/git-resolve.sh b/contrib/examples/git-resolve.sh index 0ee1bd898e..8f98142f77 100755 --- a/contrib/examples/git-resolve.sh +++ b/contrib/examples/git-resolve.sh @@ -48,7 +48,7 @@ case "$common" in "$head") echo "Updating $(git rev-parse --short $head)..$(git rev-parse --short $merge)" git read-tree -u -m $head $merge || exit 1 - git update-ref -m "resolve $merge_name: Fast forward" \ + git update-ref -m "resolve $merge_name: Fast-forward" \ HEAD "$merge" "$head" git diff-tree -p $head $merge | git apply --stat dropheads diff --git a/contrib/hooks/post-receive-email b/contrib/hooks/post-receive-email index 2a66063e44..58a35c8287 100755 --- a/contrib/hooks/post-receive-email +++ b/contrib/hooks/post-receive-email @@ -315,8 +315,8 @@ generate_update_branch_email() # "remotes/" will be ignored as well. # List all of the revisions that were removed by this update, in a - # fast forward update, this list will be empty, because rev-list O - # ^N is empty. For a non fast forward, O ^N is the list of removed + # fast-forward update, this list will be empty, because rev-list O + # ^N is empty. For a non-fast-forward, O ^N is the list of removed # revisions fast_forward="" rev="" @@ -411,7 +411,7 @@ generate_update_branch_email() # revision because the base is effectively a random revision at this # point - the user will be interested in what this revision changed # - including the undoing of previous revisions in the case of - # non-fast forward updates. + # non-fast-forward updates. echo "" echo "Summary of changes:" git diff-tree --stat --summary --find-copies-harder $oldrev..$newrev diff --git a/git-merge-octopus.sh b/git-merge-octopus.sh index 1dadbb4966..825c52c243 100755 --- a/git-merge-octopus.sh +++ b/git-merge-octopus.sh @@ -81,7 +81,7 @@ do # tree as the intermediate result of the merge. # We still need to count this as part of the parent set. - echo "Fast forwarding to: $SHA1" + echo "Fast-forwarding to: $SHA1" git read-tree -u -m $head $SHA1 || exit MRC=$SHA1 MRT=$(git write-tree) continue diff --git a/git-pull.sh b/git-pull.sh index fc78592ae0..f36eb3e397 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -171,7 +171,7 @@ then # First update the working tree to match $curr_head. echo >&2 "Warning: fetch updated the current branch head." - echo >&2 "Warning: fast forwarding your working tree from" + echo >&2 "Warning: fast-forwarding your working tree from" echo >&2 "Warning: commit $orig_head." git update-index -q --refresh git read-tree -u -m "$orig_head" "$curr_head" || diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 23ded48322..c8987887f2 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -168,7 +168,7 @@ pick_one () { output git reset --hard $sha1 test "a$1" = a-n && output git reset --soft $current_sha1 sha1=$(git rev-parse --short $sha1) - output warn Fast forward to $sha1 + output warn Fast-forward to $sha1 else output git cherry-pick "$@" fi @@ -248,9 +248,9 @@ pick_one_preserving_merges () { done case $fast_forward in t) - output warn "Fast forward to $sha1" + output warn "Fast-forward to $sha1" output git reset --hard $sha1 || - die "Cannot fast forward to $sha1" + die "Cannot fast-forward to $sha1" ;; f) first_parent=$(expr "$new_parents" : ' \([^ ]*\)') diff --git a/git-rebase.sh b/git-rebase.sh index 6ec155cf03..6830e1627d 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -496,7 +496,7 @@ then fi # If the $onto is a proper descendant of the tip of the branch, then -# we just fast forwarded. +# we just fast-forwarded. if test "$mb" = "$branch" then say "Fast-forwarded $branch_name to $onto_name." diff --git a/t/t1001-read-tree-m-2way.sh b/t/t1001-read-tree-m-2way.sh index 271bc4e17f..c2d408b461 100755 --- a/t/t1001-read-tree-m-2way.sh +++ b/t/t1001-read-tree-m-2way.sh @@ -5,7 +5,7 @@ test_description='Two way merge with read-tree -m $H $M -This test tries two-way merge (aka fast forward with carry forward). +This test tries two-way merge (aka fast-forward with carry forward). There is the head (called H) and another commit (called M), which is simply ahead of H. The index and the work tree contains a state that @@ -51,7 +51,7 @@ check_cache_at () { } cat >bozbar-old <<\EOF -This is a sample file used in two-way fast forward merge +This is a sample file used in two-way fast-forward merge tests. Its second line ends with a magic word bozbar which will be modified by the merged head to gnusto. It has some extra lines so that external tools can @@ -300,7 +300,7 @@ test_expect_success \ echo gnusto gnusto >bozbar && if read_tree_twoway $treeH $treeM; then false; else :; fi' -# This fails with straight two-way fast forward. +# This fails with straight two-way fast-forward. test_expect_success \ '22 - local change cache updated.' \ 'rm -f .git/index && diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 852ccb5d7d..220b6a3413 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -158,7 +158,7 @@ cat > test/expect << EOF another master Local refs configured for 'git push': - ahead forces to master (fast forwardable) + ahead forces to master (fast-forwardable) master pushes to another (up to date) EOF diff --git a/t/t5518-fetch-exit-status.sh b/t/t5518-fetch-exit-status.sh index c6bc65faa0..c2060bb870 100755 --- a/t/t5518-fetch-exit-status.sh +++ b/t/t5518-fetch-exit-status.sh @@ -22,7 +22,7 @@ test_expect_success setup ' git commit -a -m next ' -test_expect_success 'non fast forward fetch' ' +test_expect_success 'non-fast-forward fetch' ' test_must_fail git fetch . master:side diff --git a/t/t6028-merge-up-to-date.sh b/t/t6028-merge-up-to-date.sh index f8f3e3ff2c..a91644e3b2 100755 --- a/t/t6028-merge-up-to-date.sh +++ b/t/t6028-merge-up-to-date.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='merge fast forward and up to date' +test_description='merge fast-forward and up to date' . ./test-lib.sh diff --git a/transport.c b/transport.c index 644a30a0b2..d81a42aec4 100644 --- a/transport.c +++ b/transport.c @@ -668,7 +668,7 @@ static int print_one_push_status(struct ref *ref, const char *dest, int count, i break; case REF_STATUS_REJECT_NONFASTFORWARD: print_ref_status('!', "[rejected]", ref, ref->peer_ref, - "non-fast forward", porcelain); + "non-fast-forward", porcelain); break; case REF_STATUS_REMOTE_REJECT: print_ref_status('!', "[remote rejected]", ref, diff --git a/unpack-trees.c b/unpack-trees.c index 720f7a1616..157d5d001f 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -895,7 +895,7 @@ int threeway_merge(struct cache_entry **stages, struct unpack_trees_options *o) * Two-way merge. * * The rule is to "carry forward" what is in the index without losing - * information across a "fast forward", favoring a successful merge + * information across a "fast-forward", favoring a successful merge * over a merge failure when it makes sense. For details of the * "carry forward" rule, please see . * -- cgit v1.3 From 134748353b2a71a34f899c9b1326ccf7ae082412 Mon Sep 17 00:00:00 2001 From: Björn Gustavsson Date: Thu, 29 Oct 2009 23:08:31 +0100 Subject: Teach 'git merge' and 'git pull' the option --ff-only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For convenience in scripts and aliases, add the option --ff-only to only allow fast-forwards (and up-to-date, despite the name). Disallow combining --ff-only and --no-ff, since they flatly contradict each other. Allow all other options to be combined with --ff-only (i.e. do not add any code to handle them specially), including the following options: * --strategy (one or more): As long as the chosen merge strategy results in up-to-date or fast-forward, the command will succeed. * --squash: I cannot imagine why anyone would want to squash commits only if fast-forward is possible, but I also see no reason why it should not be allowed. * --message: The message will always be ignored, but I see no need to explicitly disallow providing a redundant message. Acknowledgements: I did look at Yuval Kogman's earlier patch (107768 in gmane), mainly as shortcut to find my way in the code, but I did not copy anything directly. Signed-off-by: Björn Gustavsson Signed-off-by: Junio C Hamano --- Documentation/merge-options.txt | 5 +++++ builtin-merge.c | 11 ++++++++++- git-pull.sh | 7 +++++-- t/t7600-merge.sh | 41 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 3 deletions(-) (limited to 'git-pull.sh') diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt index adadf8e4bf..27a9a8489c 100644 --- a/Documentation/merge-options.txt +++ b/Documentation/merge-options.txt @@ -60,6 +60,11 @@ a fast-forward, only update the branch pointer. This is the default behavior of git-merge. +--ff-only:: + Refuse to merge and exit with a non-zero status unless the + current `HEAD` is already up-to-date or the merge can be + resolved as a fast-forward. + -s :: --strategy=:: Use the given merge strategy; can be supplied more than diff --git a/builtin-merge.c b/builtin-merge.c index b6b84286b2..5e8c4b5e4b 100644 --- a/builtin-merge.c +++ b/builtin-merge.c @@ -43,6 +43,7 @@ static const char * const builtin_merge_usage[] = { static int show_diffstat = 1, option_log, squash; static int option_commit = 1, allow_fast_forward = 1; +static int fast_forward_only; static int allow_trivial = 1, have_message; static struct strbuf merge_msg; static struct commit_list *remoteheads; @@ -167,6 +168,8 @@ static struct option builtin_merge_options[] = { "perform a commit if the merge succeeds (default)"), OPT_BOOLEAN(0, "ff", &allow_fast_forward, "allow fast forward (default)"), + OPT_BOOLEAN(0, "ff-only", &fast_forward_only, + "abort if fast forward is not possible"), OPT_CALLBACK('s', "strategy", &use_strategies, "strategy", "merge strategy to use", option_parse_strategy), OPT_CALLBACK('m', "message", &merge_msg, "message", @@ -874,6 +877,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix) option_commit = 0; } + if (!allow_fast_forward && fast_forward_only) + die("You cannot combine --no-ff with --ff-only."); + if (!argc) usage_with_options(builtin_merge_usage, builtin_merge_options); @@ -1040,7 +1046,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) * only one common. */ refresh_cache(REFRESH_QUIET); - if (allow_trivial) { + if (allow_trivial && !fast_forward_only) { /* See if it is really trivial. */ git_committer_info(IDENT_ERROR_ON_NO_NAME); printf("Trying really trivial in-index merge...\n"); @@ -1079,6 +1085,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix) } } + if (fast_forward_only) + die("Not possible to fast forward, aborting."); + /* We are going to make a new commit. */ git_committer_info(IDENT_ERROR_ON_NO_NAME); diff --git a/git-pull.sh b/git-pull.sh index fc78592ae0..37f3d93017 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -16,7 +16,8 @@ cd_to_toplevel test -z "$(git ls-files -u)" || die "You are in the middle of a conflicted merge." -strategy_args= diffstat= no_commit= squash= no_ff= log_arg= verbosity= +strategy_args= diffstat= no_commit= squash= no_ff= ff_only= +log_arg= verbosity= curr_branch=$(git symbolic-ref -q HEAD) curr_branch_short=$(echo "$curr_branch" | sed "s|refs/heads/||") rebase=$(git config --bool branch.$curr_branch_short.rebase) @@ -45,6 +46,8 @@ do no_ff=--ff ;; --no-ff) no_ff=--no-ff ;; + --ff-only) + ff_only=--ff-only ;; -s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\ --strateg=*|--strategy=*|\ -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy) @@ -215,5 +218,5 @@ merge_name=$(git fmt-merge-msg $log_arg <"$GIT_DIR/FETCH_HEAD") || exit test true = "$rebase" && exec git-rebase $diffstat $strategy_args --onto $merge_head \ ${oldremoteref:-$merge_head} -exec git-merge $diffstat $no_commit $squash $no_ff $log_arg $strategy_args \ +exec git-merge $diffstat $no_commit $squash $no_ff $ff_only $log_arg $strategy_args \ "$merge_name" HEAD $merge_head $verbosity diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh index e5b210bc96..57f6d2bae7 100755 --- a/t/t7600-merge.sh +++ b/t/t7600-merge.sh @@ -243,6 +243,16 @@ test_expect_success 'merge c0 with c1' ' test_debug 'gitk --all' +test_expect_success 'merge c0 with c1 with --ff-only' ' + git reset --hard c0 && + git merge --ff-only c1 && + git merge --ff-only HEAD c0 c1 && + verify_merge file result.1 && + verify_head "$c1" +' + +test_debug 'gitk --all' + test_expect_success 'merge c1 with c2' ' git reset --hard c1 && test_tick && @@ -263,6 +273,14 @@ test_expect_success 'merge c1 with c2 and c3' ' test_debug 'gitk --all' +test_expect_success 'failing merges with --ff-only' ' + git reset --hard c1 && + test_tick && + test_must_fail git merge --ff-only c2 && + test_must_fail git merge --ff-only c3 && + test_must_fail git merge --ff-only c2 c3 +' + test_expect_success 'merge c0 with c1 (no-commit)' ' git reset --hard c0 && git merge --no-commit c1 && @@ -303,6 +321,17 @@ test_expect_success 'merge c0 with c1 (squash)' ' test_debug 'gitk --all' +test_expect_success 'merge c0 with c1 (squash, ff-only)' ' + git reset --hard c0 && + git merge --squash --ff-only c1 && + verify_merge file result.1 && + verify_head $c0 && + verify_no_mergehead && + verify_diff squash.1 .git/SQUASH_MSG "[OOPS] bad squash message" +' + +test_debug 'gitk --all' + test_expect_success 'merge c1 with c2 (squash)' ' git reset --hard c1 && git merge --squash c2 && @@ -314,6 +343,13 @@ test_expect_success 'merge c1 with c2 (squash)' ' test_debug 'gitk --all' +test_expect_success 'unsuccesful merge of c1 with c2 (squash, ff-only)' ' + git reset --hard c1 && + test_must_fail git merge --squash --ff-only c2 +' + +test_debug 'gitk --all' + test_expect_success 'merge c1 with c2 and c3 (squash)' ' git reset --hard c1 && git merge --squash c2 c3 && @@ -432,6 +468,11 @@ test_expect_success 'combining --squash and --no-ff is refused' ' test_must_fail git merge --no-ff --squash c1 ' +test_expect_success 'combining --ff-only and --no-ff is refused' ' + test_must_fail git merge --ff-only --no-ff c1 && + test_must_fail git merge --no-ff --ff-only c1 +' + test_expect_success 'merge c0 with c1 (ff overrides no-ff)' ' git reset --hard c0 && git config branch.master.mergeoptions "--no-ff" && -- cgit v1.3 From c0ecb07048ce2123589a2f077d296e8cf29a9570 Mon Sep 17 00:00:00 2001 From: "Horst H. von Brand" Date: Tue, 1 Dec 2009 19:44:11 -0300 Subject: git-pull.sh: Fix call to git-merge for new command format Now "git merge HEAD" is officially deprecated, we should clean our own use as well. Signed-off-by: Horst H. von Brand Signed-off-by: Junio C Hamano --- git-pull.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'git-pull.sh') diff --git a/git-pull.sh b/git-pull.sh index bfeb4a0ff6..502af1a9c4 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -216,7 +216,7 @@ fi merge_name=$(git fmt-merge-msg $log_arg <"$GIT_DIR/FETCH_HEAD") || exit test true = "$rebase" && - exec git-rebase $diffstat $strategy_args --onto $merge_head \ + exec git rebase $diffstat $strategy_args --onto $merge_head \ ${oldremoteref:-$merge_head} -exec git-merge $diffstat $no_commit $squash $no_ff $ff_only $log_arg $strategy_args \ - "$merge_name" HEAD $merge_head $verbosity +exec git merge $verbosity $diffstat $no_commit $squash $no_ff $ff_only $log_arg $strategy_args \ + -m "$merge_name" $merge_head -- cgit v1.3 From 995fc2f7e17fab8dd59f31f25870a0823cdb6f27 Mon Sep 17 00:00:00 2001 From: Jan Krüger Date: Fri, 27 Nov 2009 08:17:05 -0600 Subject: pull: clarify advice for the unconfigured error case MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When pull --rebase fails because it cannot find what branch to merge against, the error message implies we are trying to merge. Say "rebase against" instead of "merge with" to avoid confusion. The configuration suggested to remedy the situation uses a confusing syntax, with variables specified in the dotted form accepted by 'git config' but separated from their values by the '=' delimiter used by config files. Since the user will have to edit this output anyway, it is more helpful to provide a config file snippet to paste into an editor and modify. Signed-off-by: Jan Krüger Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- git-pull.sh | 48 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) (limited to 'git-pull.sh') diff --git a/git-pull.sh b/git-pull.sh index fc78592ae0..2530f21861 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -88,45 +88,63 @@ error_on_no_merge_candidates () { esac done + if test true = "$rebase" + then + op_type=rebase + op_prep=against + else + op_type=merge + op_prep=with + fi + curr_branch=${curr_branch#refs/heads/} upstream=$(git config "branch.$curr_branch.merge") remote=$(git config "branch.$curr_branch.remote") if [ $# -gt 1 ]; then - echo "There are no candidates for merging in the refs that you just fetched." + if [ "$rebase" = true ]; then + printf "There is no candidate for rebasing against " + else + printf "There are no candidates for merging " + fi + echo "among the refs that you just fetched." echo "Generally this means that you provided a wildcard refspec which had no" echo "matches on the remote end." elif [ $# -gt 0 ] && [ "$1" != "$remote" ]; then echo "You asked to pull from the remote '$1', but did not specify" - echo "a branch to merge. Because this is not the default configured remote" + echo "a branch. Because this is not the default configured remote" echo "for your current branch, you must specify a branch on the command line." elif [ -z "$curr_branch" ]; then echo "You are not currently on a branch, so I cannot use any" echo "'branch..merge' in your configuration file." - echo "Please specify which branch you want to merge on the command" + echo "Please specify which remote branch you want to use on the command" echo "line and try again (e.g. 'git pull ')." echo "See git-pull(1) for details." elif [ -z "$upstream" ]; then echo "You asked me to pull without telling me which branch you" - echo "want to merge with, and 'branch.${curr_branch}.merge' in" - echo "your configuration file does not tell me either. Please" - echo "specify which branch you want to merge on the command line and" + echo "want to $op_type $op_prep, and 'branch.${curr_branch}.merge' in" + echo "your configuration file does not tell me, either. Please" + echo "specify which branch you want to use on the command line and" echo "try again (e.g. 'git pull ')." echo "See git-pull(1) for details." echo - echo "If you often merge with the same branch, you may want to" - echo "configure the following variables in your configuration" - echo "file:" + echo "If you often $op_type $op_prep the same branch, you may want to" + echo "use something like the following in your configuration file:" + echo + echo " [branch \"${curr_branch}\"]" + echo " remote = " + echo " merge = " + test rebase = "$op_type" && + echo " rebase = true" echo - echo " branch.${curr_branch}.remote = " - echo " branch.${curr_branch}.merge = " - echo " remote..url = " - echo " remote..fetch = " + echo " [remote \"\"]" + echo " url = " + echo " fetch = " echo echo "See git-config(1) for details." else - echo "Your configuration specifies to merge the ref '${upstream#refs/heads/}' from the" - echo "remote, but no such ref was fetched." + echo "Your configuration specifies to $op_type $op_prep the ref '${upstream#refs/heads/}'" + echo "from the remote, but no such ref was fetched." fi exit 1 } -- cgit v1.3 From 77c29b4acae2f129f71e4856b8d0518982802d83 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 8 Dec 2009 15:21:02 -0800 Subject: Revert recent "git merge HEAD ..." deprecation This reverts commit c0ecb07048ce2123589a2f077d296e8cf29a9570 "git-pull.sh: Fix call to git-merge for new command format" and commit b81e00a965c62ca72a4b9db425ee173de147808d "git-merge: a deprecation notice of the ancient command line syntax". They caused a "git pull" (without any arguments, and without any local commits---only to update to the other side) to warn that commit log message is ignored because the merge resulted in a fast-forward. Another possible solution is to add an extra option to "git merge" so that "git pull" can tell it that the message given is not coming from the end user (the canned message is passed just in case the merge resulted in a non-ff and caused commit), but I think it is easier _not_ to deprecate the old syntax. Signed-off-by: Junio C Hamano --- builtin-merge.c | 6 ------ git-pull.sh | 6 +++--- 2 files changed, 3 insertions(+), 9 deletions(-) (limited to 'git-pull.sh') diff --git a/builtin-merge.c b/builtin-merge.c index 56a1bb651f..f1c84d759d 100644 --- a/builtin-merge.c +++ b/builtin-merge.c @@ -796,11 +796,6 @@ static int suggest_conflicts(void) return 1; } -static const char deprecation_warning[] = - "'git merge HEAD ' is deprecated. Please update\n" - "your script to use 'git merge -m ' instead.\n" - "In future versions of git, this syntax will be removed."; - static struct commit *is_old_style_invocation(int argc, const char **argv) { struct commit *second_token = NULL; @@ -814,7 +809,6 @@ static struct commit *is_old_style_invocation(int argc, const char **argv) die("'%s' is not a commit", argv[1]); if (hashcmp(second_token->object.sha1, head)) return NULL; - warning(deprecation_warning); } return second_token; } diff --git a/git-pull.sh b/git-pull.sh index 502af1a9c4..bfeb4a0ff6 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -216,7 +216,7 @@ fi merge_name=$(git fmt-merge-msg $log_arg <"$GIT_DIR/FETCH_HEAD") || exit test true = "$rebase" && - exec git rebase $diffstat $strategy_args --onto $merge_head \ + exec git-rebase $diffstat $strategy_args --onto $merge_head \ ${oldremoteref:-$merge_head} -exec git merge $verbosity $diffstat $no_commit $squash $no_ff $ff_only $log_arg $strategy_args \ - -m "$merge_name" $merge_head +exec git-merge $diffstat $no_commit $squash $no_ff $ff_only $log_arg $strategy_args \ + "$merge_name" HEAD $merge_head $verbosity -- cgit v1.3 From d38a30df7dd54c5c6883af1de1a03ec7d523cee5 Mon Sep 17 00:00:00 2001 From: Matthieu Moy Date: Tue, 12 Jan 2010 10:54:44 +0100 Subject: Be more user-friendly when refusing to do something because of conflict. Various commands refuse to run in the presence of conflicts (commit, merge, pull, cherry-pick/revert). They all used to provide rough, and inconsistant error messages. A new variable advice.resolveconflict is introduced, and allows more verbose messages, pointing the user to the appropriate solution. For commit, the error message used to look like this: $ git commit foo.txt: needs merge foo.txt: unmerged (c34a92682e0394bc0d6f4d4a67a8e2d32395c169) foo.txt: unmerged (3afcd75de8de0bb5076942fcb17446be50451030) foo.txt: unmerged (c9785d77b76dfe4fb038bf927ee518f6ae45ede4) error: Error building trees The "need merge" line is given by refresh_cache. We add the IN_PORCELAIN option to make the output more consistant with the other porcelain commands, and catch the error in return, to stop with a clean error message. The next lines were displayed by a call to cache_tree_update(), which is not reached anymore if we noticed the conflict. The new output looks like: U foo.txt fatal: 'commit' is not possible because you have unmerged files. Please, fix them up in the work tree, and then use 'git add/rm ' as appropriate to mark resolution and make a commit, or use 'git commit -a'. Pull is slightly modified to abort immediately if $GIT_DIR/MERGE_HEAD exists instead of waiting for merge to complain. The behavior of merge and the test-case are slightly modified to reflect the usual flow: start with conflicts, fix them, and afterwards get rid of MERGE_HEAD, with different error messages at each stage. Signed-off-by: Matthieu Moy Signed-off-by: Junio C Hamano --- Documentation/config.txt | 4 ++++ advice.c | 16 ++++++++++++++++ advice.h | 5 +++++ builtin-commit.c | 14 ++++++++++++-- builtin-merge.c | 19 ++++++++++++++----- builtin-revert.c | 15 ++++++++++++++- git-pull.sh | 25 +++++++++++++++++++++++-- t/t3030-merge-recursive.sh | 6 ++++-- t/t3501-revert-cherry-pick.sh | 2 +- 9 files changed, 93 insertions(+), 13 deletions(-) (limited to 'git-pull.sh') diff --git a/Documentation/config.txt b/Documentation/config.txt index a1e36d7e42..9c27686fab 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -130,6 +130,10 @@ advice.*:: Advice shown when linkgit:git-merge[1] refuses to merge to avoid overwritting local changes. Default: true. + resolveConflict:: + Advices shown by various commands when conflicts + prevent the operation from being performed. + Default: true. -- core.fileMode:: diff --git a/advice.c b/advice.c index cb666acc3c..3309521f45 100644 --- a/advice.c +++ b/advice.c @@ -3,6 +3,7 @@ int advice_push_nonfastforward = 1; int advice_status_hints = 1; int advice_commit_before_merge = 1; +int advice_resolve_conflict = 1; static struct { const char *name; @@ -11,6 +12,7 @@ static struct { { "pushnonfastforward", &advice_push_nonfastforward }, { "statushints", &advice_status_hints }, { "commitbeforemerge", &advice_commit_before_merge }, + { "resolveconflict", &advice_resolve_conflict }, }; int git_default_advice_config(const char *var, const char *value) @@ -27,3 +29,17 @@ int git_default_advice_config(const char *var, const char *value) return 0; } + +void NORETURN die_resolve_conflict(const char *me) +{ + if (advice_resolve_conflict) + /* + * Message used both when 'git commit' fails and when + * other commands doing a merge do. + */ + die("'%s' is not possible because you have unmerged files.\n" + "Please, fix them up in the work tree, and then use 'git add/rm ' as\n" + "appropriate to mark resolution and make a commit, or use 'git commit -a'.", me); + else + die("'%s' is not possible because you have unmerged files.", me); +} diff --git a/advice.h b/advice.h index 3de5000d8c..acd5fdde3f 100644 --- a/advice.h +++ b/advice.h @@ -1,10 +1,15 @@ #ifndef ADVICE_H #define ADVICE_H +#include "git-compat-util.h" + extern int advice_push_nonfastforward; extern int advice_status_hints; extern int advice_commit_before_merge; +extern int advice_resolve_conflict; int git_default_advice_config(const char *var, const char *value); +extern void NORETURN die_resolve_conflict(const char *me); + #endif /* ADVICE_H */ diff --git a/builtin-commit.c b/builtin-commit.c index f54772f74a..c58712c539 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -219,6 +219,16 @@ static void create_base_index(void) exit(128); /* We've already reported the error, finish dying */ } +static void refresh_cache_or_die(int refresh_flags) +{ + /* + * refresh_flags contains REFRESH_QUIET, so the only errors + * are for unmerged entries. + */ + if (refresh_cache(refresh_flags | REFRESH_IN_PORCELAIN)) + die_resolve_conflict("commit"); +} + static char *prepare_index(int argc, const char **argv, const char *prefix, int is_status) { int fd; @@ -258,7 +268,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, int if (all || (also && pathspec && *pathspec)) { int fd = hold_locked_index(&index_lock, 1); add_files_to_cache(also ? prefix : NULL, pathspec, 0); - refresh_cache(refresh_flags); + refresh_cache_or_die(refresh_flags); if (write_cache(fd, active_cache, active_nr) || close_lock_file(&index_lock)) die("unable to write new_index file"); @@ -277,7 +287,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, int */ if (!pathspec || !*pathspec) { fd = hold_locked_index(&index_lock, 1); - refresh_cache(refresh_flags); + refresh_cache_or_die(refresh_flags); if (write_cache(fd, active_cache, active_nr) || commit_locked_index(&index_lock)) die("unable to write new_index file"); diff --git a/builtin-merge.c b/builtin-merge.c index f1c84d759d..79a35c305b 100644 --- a/builtin-merge.c +++ b/builtin-merge.c @@ -847,11 +847,20 @@ int cmd_merge(int argc, const char **argv, const char *prefix) const char *best_strategy = NULL, *wt_strategy = NULL; struct commit_list **remotes = &remoteheads; - if (file_exists(git_path("MERGE_HEAD"))) - die("You have not concluded your merge. (MERGE_HEAD exists)"); - if (read_cache_unmerged()) - die("You are in the middle of a conflicted merge." - " (index unmerged)"); + if (read_cache_unmerged()) { + die_resolve_conflict("merge"); + } + if (file_exists(git_path("MERGE_HEAD"))) { + /* + * There is no unmerged entry, don't advise 'git + * add/rm ', just 'git commit'. + */ + if (advice_resolve_conflict) + die("You have not concluded your merge (MERGE_HEAD exists).\n" + "Please, commit your changes before you can merge."); + else + die("You have not concluded your merge (MERGE_HEAD exists)."); + } /* * Check if we are _not_ on a detached HEAD, i.e. if there is a diff --git a/builtin-revert.c b/builtin-revert.c index 151aa6a981..d14dde3fbf 100644 --- a/builtin-revert.c +++ b/builtin-revert.c @@ -233,6 +233,19 @@ static struct tree *empty_tree(void) return tree; } +static NORETURN void die_dirty_index(const char *me) +{ + if (read_cache_unmerged()) { + die_resolve_conflict(me); + } else { + if (advice_commit_before_merge) + die("Your local changes would be overwritten by %s.\n" + "Please, commit your changes or stash them to proceed.", me); + else + die("Your local changes would be overwritten by %s.\n", me); + } +} + static int revert_or_cherry_pick(int argc, const char **argv) { unsigned char head[20]; @@ -269,7 +282,7 @@ static int revert_or_cherry_pick(int argc, const char **argv) if (get_sha1("HEAD", head)) die ("You do not have a valid HEAD"); if (index_differs_from("HEAD", 0)) - die ("Dirty index: cannot %s", me); + die_dirty_index(me); } discard_cache(); diff --git a/git-pull.sh b/git-pull.sh index 9e69ada413..54ce0af2d4 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -13,8 +13,29 @@ set_reflog_action "pull $*" require_work_tree cd_to_toplevel -test -z "$(git ls-files -u)" || - die "You are in the middle of a conflicted merge." + +die_conflict () { + git diff-index --cached --name-status -r --ignore-submodules HEAD -- + if [ $(git config --bool --get advice.resolveConflict || echo true) = "true" ]; then + die "Pull is not possible because you have unmerged files. +Please, fix them up in the work tree, and then use 'git add/rm ' +as appropriate to mark resolution, or use 'git commit -a'." + else + die "Pull is not possible because you have unmerged files." + fi +} + +die_merge () { + if [ $(git config --bool --get advice.resolveConflict || echo true) = "true" ]; then + die "You have not concluded your merge (MERGE_HEAD exists). +Please, commit your changes before you can merge." + else + die "You have not concluded your merge (MERGE_HEAD exists)." + fi +} + +test -z "$(git ls-files -u)" || die_conflict +test -f "$GIT_DIR/MERGE_HEAD" && die_merge strategy_args= diffstat= no_commit= squash= no_ff= ff_only= log_arg= verbosity= diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh index 9b3fa2bdcd..9929f82021 100755 --- a/t/t3030-merge-recursive.sh +++ b/t/t3030-merge-recursive.sh @@ -276,11 +276,13 @@ test_expect_success 'fail if the index has unresolved entries' ' test_must_fail git merge "$c5" && test_must_fail git merge "$c5" 2> out && + grep "not possible because you have unmerged files" out && + git add -u && + test_must_fail git merge "$c5" 2> out && grep "You have not concluded your merge" out && rm -f .git/MERGE_HEAD && test_must_fail git merge "$c5" 2> out && - grep "You are in the middle of a conflicted merge" out - + grep "Your local changes to .* would be overwritten by merge." out ' test_expect_success 'merge-recursive remove conflict' ' diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh index bb4cf00d78..7f858151d4 100755 --- a/t/t3501-revert-cherry-pick.sh +++ b/t/t3501-revert-cherry-pick.sh @@ -66,7 +66,7 @@ test_expect_success 'revert forbidden on dirty working tree' ' echo content >extra_file && git add extra_file && test_must_fail git revert HEAD 2>errors && - grep "Dirty index" errors + grep "Your local changes would be overwritten by " errors ' -- cgit v1.3 From ee2c79552acceaa59a78518c6c084bd515606374 Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Wed, 25 Nov 2009 21:23:57 -0500 Subject: Teach git-pull to pass -X