summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2013-12-27 14:58:08 -0800
committerJunio C Hamano <gitster@pobox.com>2013-12-27 14:58:08 -0800
commit2b0a564e02528e006d23e3318d0d2869fb239425 (patch)
tree76f46ae7b059ac9ca0e8b725fa67f89a3c078f16
parente9ecee0423f2b24eb4e51d337044721c761cb4c3 (diff)
parentad8261d21221d27638c75f47b39892db6f7972f6 (diff)
downloadgit-2b0a564e02528e006d23e3318d0d2869fb239425.tar.gz
Merge branch 'jk/pull-rebase-using-fork-point'
* jk/pull-rebase-using-fork-point: rebase: use reflog to find common base with upstream pull: use merge-base --fork-point when appropriate
-rw-r--r--Documentation/git-rebase.txt10
-rwxr-xr-xgit-pull.sh10
-rwxr-xr-xgit-rebase.sh19
-rwxr-xr-xt/t3400-rebase.sh6
4 files changed, 34 insertions, 11 deletions
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 94e07fdab5..2889be6bdc 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -324,6 +324,16 @@ fresh commits so it can be remerged successfully without needing to "revert
the reversion" (see the
link:howto/revert-a-faulty-merge.html[revert-a-faulty-merge How-To] for details).
+--fork-point::
+--no-fork-point::
+ Use 'git merge-base --fork-point' to find a better common ancestor
+ between `upstream` and `branch` when calculating which commits have
+ have been introduced by `branch` (see linkgit:git-merge-base[1]).
++
+If no non-option arguments are given on the command line, then the default is
+`--fork-point @{u}` otherwise the `upstream` argument is interpreted literally
+unless the `--fork-point` option is specified.
+
--ignore-whitespace::
--whitespace=<option>::
These flag are passed to the 'git apply' program
diff --git a/git-pull.sh b/git-pull.sh
index 97716b885f..f210d0a147 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -229,15 +229,7 @@ test true = "$rebase" && {
test -n "$curr_branch" &&
. git-parse-remote &&
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
+ oldremoteref=$(git merge-base --fork-point "$remoteref" $curr_branch)
}
orig_head=$(git rev-parse -q --verify HEAD)
git fetch $verbosity $progress $dry_run $recurse_submodules --update-head-ok "$@" || exit 1
diff --git a/git-rebase.sh b/git-rebase.sh
index 226752fbff..7185dc8438 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -14,6 +14,7 @@ git-rebase --continue | --abort | --skip | --edit-todo
v,verbose! display a diffstat of what changed upstream
q,quiet! be quiet. implies --no-stat
autostash! automatically stash/stash pop before and after
+fork-point use 'merge-base --fork-point' to refine upstream
onto=! rebase onto given branch instead of upstream
p,preserve-merges! try to recreate merges instead of ignoring them
s,strategy=! use the given merge strategy
@@ -66,6 +67,7 @@ verbose=
diffstat=
test "$(git config --bool rebase.stat)" = true && diffstat=t
autostash="$(git config --bool rebase.autostash || echo false)"
+fork_point=auto
git_am_opt=
rebase_root=
force_rebase=
@@ -260,6 +262,12 @@ do
--no-autosquash)
autosquash=
;;
+ --fork-point)
+ fork_point=t
+ ;;
+ --no-fork-point)
+ fork_point=
+ ;;
-M|-m)
do_merge=t
;;
@@ -437,6 +445,8 @@ then
error_on_missing_default_upstream "rebase" "rebase" \
"against" "git rebase <branch>"
fi
+
+ test "$fork_point" = auto && fork_point=t
;;
*) upstream_name="$1"
shift
@@ -522,6 +532,15 @@ case "$#" in
;;
esac
+if test "$fork_point" = t
+then
+ new_upstream=$(git merge-base --fork-point "$upstream_name" "$switch_to")
+ if test -n "$new_upstream"
+ then
+ upstream=$new_upstream
+ fi
+fi
+
if test "$autostash" = true && ! (require_clean_work_tree) 2>/dev/null
then
stash_sha1=$(git stash create "autostash") ||
diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index ebf93b0695..998503db12 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -134,12 +134,14 @@ test_expect_success 'fail when upstream arg is missing and not configured' '
test_must_fail git rebase
'
-test_expect_success 'default to @{upstream} when upstream arg is missing' '
+test_expect_success 'default to common base in @{upstream}s reflog if no upstream arg' '
git checkout -b default topic &&
git config branch.default.remote . &&
git config branch.default.merge refs/heads/master &&
git rebase &&
- test "$(git rev-parse default~1)" = "$(git rev-parse master)"
+ git rev-parse --verify master >expect &&
+ git rev-parse default~1 >actual &&
+ test_cmp expect actual
'
test_expect_success 'rebase -q is quiet' '