rebase: use reflog to find common base with upstream
Commitmaint15a147e(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 commitd44e712(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>
							parent
							
								
									48059e4050
								
							
						
					
					
						commit
						ad8261d212
					
				|  | @ -324,6 +324,16 @@ fresh commits so it can be remerged successfully without needing to "revert | ||||||
| the reversion" (see the | the reversion" (see the | ||||||
| link:howto/revert-a-faulty-merge.html[revert-a-faulty-merge How-To] for details). | 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:: | --ignore-whitespace:: | ||||||
| --whitespace=<option>:: | --whitespace=<option>:: | ||||||
| 	These flag are passed to the 'git apply' program | 	These flag are passed to the 'git apply' program | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ git-rebase --continue | --abort | --skip | --edit-todo | ||||||
| v,verbose!         display a diffstat of what changed upstream | v,verbose!         display a diffstat of what changed upstream | ||||||
| q,quiet!           be quiet. implies --no-stat | q,quiet!           be quiet. implies --no-stat | ||||||
| autostash!         automatically stash/stash pop before and after | 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 | onto=!             rebase onto given branch instead of upstream | ||||||
| p,preserve-merges! try to recreate merges instead of ignoring them | p,preserve-merges! try to recreate merges instead of ignoring them | ||||||
| s,strategy=!       use the given merge strategy | s,strategy=!       use the given merge strategy | ||||||
|  | @ -66,6 +67,7 @@ verbose= | ||||||
| diffstat= | diffstat= | ||||||
| test "$(git config --bool rebase.stat)" = true && diffstat=t | test "$(git config --bool rebase.stat)" = true && diffstat=t | ||||||
| autostash="$(git config --bool rebase.autostash || echo false)" | autostash="$(git config --bool rebase.autostash || echo false)" | ||||||
|  | fork_point=auto | ||||||
| git_am_opt= | git_am_opt= | ||||||
| rebase_root= | rebase_root= | ||||||
| force_rebase= | force_rebase= | ||||||
|  | @ -260,6 +262,12 @@ do | ||||||
| 	--no-autosquash) | 	--no-autosquash) | ||||||
| 		autosquash= | 		autosquash= | ||||||
| 		;; | 		;; | ||||||
|  | 	--fork-point) | ||||||
|  | 		fork_point=t | ||||||
|  | 		;; | ||||||
|  | 	--no-fork-point) | ||||||
|  | 		fork_point= | ||||||
|  | 		;; | ||||||
| 	-M|-m) | 	-M|-m) | ||||||
| 		do_merge=t | 		do_merge=t | ||||||
| 		;; | 		;; | ||||||
|  | @ -437,6 +445,8 @@ then | ||||||
| 			error_on_missing_default_upstream "rebase" "rebase" \ | 			error_on_missing_default_upstream "rebase" "rebase" \ | ||||||
| 				"against" "git rebase <branch>" | 				"against" "git rebase <branch>" | ||||||
| 		fi | 		fi | ||||||
|  |  | ||||||
|  | 		test "$fork_point" = auto && fork_point=t | ||||||
| 		;; | 		;; | ||||||
| 	*)	upstream_name="$1" | 	*)	upstream_name="$1" | ||||||
| 		shift | 		shift | ||||||
|  | @ -522,6 +532,15 @@ case "$#" in | ||||||
| 	;; | 	;; | ||||||
| esac | 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 | if test "$autostash" = true && ! (require_clean_work_tree) 2>/dev/null | ||||||
| then | then | ||||||
| 	stash_sha1=$(git stash create "autostash") || | 	stash_sha1=$(git stash create "autostash") || | ||||||
|  |  | ||||||
|  | @ -134,12 +134,14 @@ test_expect_success 'fail when upstream arg is missing and not configured' ' | ||||||
| 	test_must_fail git rebase | 	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 checkout -b default topic && | ||||||
| 	git config branch.default.remote . && | 	git config branch.default.remote . && | ||||||
| 	git config branch.default.merge refs/heads/master && | 	git config branch.default.merge refs/heads/master && | ||||||
| 	git rebase && | 	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' ' | test_expect_success 'rebase -q is quiet' ' | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 John Keeping
						John Keeping