rebase: use reflog to find common base with upstream

Commit 15a147e (rebase: use @{upstream} if no upstream specified, 2011-02-09) says: Make it default to 'git rebase @{upstream}'. That is also what 'git pull [--rebase]' defaults to, so it only makes sense that 'git rebase' defaults to the same thing. but that isn't actually the case. Since commit d44e712 (pull: support rebased upstream + fetch + pull --rebase, 2009-07-19), pull has actually chosen the most recent reflog entry which is an ancestor of the current branch if it can find one. Add a '--fork-point' argument to git-rebase that can be used to trigger this behaviour. This option is turned on by default if no non-option arguments are specified on the command line, otherwise we treat an upstream specified on the command-line literally. Signed-off-by: John Keeping <john@keeping.me.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>

John Keeping committed Dec 9, 2013 at 23:16 UTC ad8261d21221d27638c75f47b39892db6f7972f6
3 files changed +33 -2
Documentation/git-rebase.txt
+10
@@ -324,6 +324,16 @@ fresh commits so it can be remerged successfully without needing to "revert
324 the reversion" (see the
325 link:howto/revert-a-faulty-merge.html[revert-a-faulty-merge How-To] for details).
326
327 +--fork-point::
328 +--no-fork-point::
329 + Use 'git merge-base --fork-point' to find a better common ancestor
330 + between `upstream` and `branch` when calculating which commits have
331 + have been introduced by `branch` (see linkgit:git-merge-base[1]).
332 ++
333 +If no non-option arguments are given on the command line, then the default is
334 +`--fork-point @{u}` otherwise the `upstream` argument is interpreted literally
335 +unless the `--fork-point` option is specified.
336 +
337 --ignore-whitespace::
338 --whitespace=<option>::
339 These flag are passed to the 'git apply' program
git-rebase.sh
+19
@@ -14,6 +14,7 @@ git-rebase --continue | --abort | --skip | --edit-todo
14 v,verbose! display a diffstat of what changed upstream
15 q,quiet! be quiet. implies --no-stat
16 autostash! automatically stash/stash pop before and after
17 +fork-point use 'merge-base --fork-point' to refine upstream
18 onto=! rebase onto given branch instead of upstream
19 p,preserve-merges! try to recreate merges instead of ignoring them
20 s,strategy=! use the given merge strategy
@@ -66,6 +67,7 @@ verbose=
67 diffstat=
68 test "$(git config --bool rebase.stat)" = true && diffstat=t
69 autostash="$(git config --bool rebase.autostash || echo false)"
70 +fork_point=auto
71 git_am_opt=
72 rebase_root=
73 force_rebase=
@@ -260,6 +262,12 @@ do
262 --no-autosquash)
263 autosquash=
264 ;;
265 + --fork-point)
266 + fork_point=t
267 + ;;
268 + --no-fork-point)
269 + fork_point=
270 + ;;
271 -M|-m)
272 do_merge=t
273 ;;
@@ -437,6 +445,8 @@ then
445 error_on_missing_default_upstream "rebase" "rebase" \
446 "against" "git rebase <branch>"
447 fi
448 +
449 + test "$fork_point" = auto && fork_point=t
450 ;;
451 *) upstream_name="$1"
452 shift
@@ -522,6 +532,15 @@ case "$#" in
532 ;;
533 esac
534
535 +if test "$fork_point" = t
536 +then
537 + new_upstream=$(git merge-base --fork-point "$upstream_name" "$switch_to")
538 + if test -n "$new_upstream"
539 + then
540 + upstream=$new_upstream
541 + fi
542 +fi
543 +
544 if test "$autostash" = true && ! (require_clean_work_tree) 2>/dev/null
545 then
546 stash_sha1=$(git stash create "autostash") ||
t/t3400-rebase.sh
+4 -2
@@ -134,12 +134,14 @@ test_expect_success 'fail when upstream arg is missing and not configured' '
134 test_must_fail git rebase
135 '
136
137 -test_expect_success 'default to @{upstream} when upstream arg is missing' '
137 +test_expect_success 'default to common base in @{upstream}s reflog if no upstream arg' '
138 git checkout -b default topic &&
139 git config branch.default.remote . &&
140 git config branch.default.merge refs/heads/master &&
141 git rebase &&
142 - test "$(git rev-parse default~1)" = "$(git rev-parse master)"
142 + git rev-parse --verify master >expect &&
143 + git rev-parse default~1 >actual &&
144 + test_cmp expect actual
145 '
146
147 test_expect_success 'rebase -q is quiet' '