rebase: support -X to pass through strategy options
git-rebase calls out to merge strategies, but did not support merge strategy options so far. Add this, in the same style used in git-merge. Sadly we have to do the full quoting/eval dance here, since merge-recursive supports the --subtree=<path> option which potentially contains whitespace. This patch does not cover git rebase -i, which does not call any merge strategy directly except in --preserve-merges, and even then only for merges. [jc: with a trivial fix-up for 'expr'] Signed-off-by: Mike Lundy <mike@fluffypenguin.org> Signed-off-by: Thomas Rast <trast@student.ethz.ch> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Mike Lundy committed
Jul 29, 2010 at 00:04 UTC
93ce190cd16b4c5ff16cc000eb75bd6e6c3238ac
3 files changed
+39
-1
Documentation/git-rebase.txt
+7
@@ -250,6 +250,13 @@ on top of the <upstream> branch using the given strategy, using
250
the 'ours' strategy simply discards all patches from the <branch>,
251
which makes little sense.
252
253
+-X <strategy-option>::
254
+--strategy-option=<strategy-option>::
255
+ Pass the <strategy-option> through to the merge strategy.
256
+ This implies `\--merge` and, if no strategy has been
257
+ specified, `-s recursive`. Note the reversal of 'ours' and
258
+ 'theirs' as noted in above for the `-m` option.
259
+
260
-q::
261
--quiet::
262
Be quiet. Implies --no-stat.
git-rebase.sh
+23
-1
@@ -44,6 +44,7 @@ To restore the original branch and stop rebasing run \"git rebase --abort\".
44
"
45
unset newbase
46
strategy=recursive
47
+strategy_opts=
48
do_merge=
49
dotest="$GIT_DIR"/rebase-merge
50
prec=4
@@ -112,7 +113,7 @@ call_merge () {
113
then
114
export GIT_MERGE_VERBOSITY=1
115
fi
115
- git-merge-$strategy "$cmt^" -- "$hd" "$cmt"
116
+ eval 'git-merge-$strategy' $strategy_opts '"$cmt^" -- "$hd" "$cmt"'
117
rv=$?
118
case "$rv" in
119
0)
@@ -293,6 +294,27 @@ do
294
-M|-m|--m|--me|--mer|--merg|--merge)
295
do_merge=t
296
;;
297
+ -X*|--strategy-option*)
298
+ case "$#,$1" in
299
+ 1,-X|1,--strategy-option)
300
+ usage ;;
301
+ *,-X|*,--strategy-option)
302
+ newopt="$2"
303
+ shift ;;
304
+ *,--strategy-option=*)
305
+ newopt="$(expr " $1" : ' --strategy-option=\(.*\)')" ;;
306
+ *,-X*)
307
+ newopt="$(expr " $1" : ' -X\(.*\)')" ;;
308
+ 1,*)
309
+ usage ;;
310
+ esac
311
+ strategy_opts="$strategy_opts $(git rev-parse --sq-quote "--$newopt")"
312
+ do_merge=t
313
+ if test -n "$strategy"
314
+ then
315
+ strategy=recursive
316
+ fi
317
+ ;;
318
-s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
319
--strateg=*|--strategy=*|\
320
-s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
t/t3402-rebase-merge.sh
+9
@@ -74,6 +74,15 @@ test_expect_success 'rebase the other way' '
74
git rebase --merge side
75
'
76
77
+test_expect_success 'rebase -Xtheirs' '
78
+ git checkout -b conflicting master~2 &&
79
+ echo "AB $T" >> original &&
80
+ git commit -mconflicting original &&
81
+ git rebase -Xtheirs master &&
82
+ grep AB original &&
83
+ ! grep 11 original
84
+'
85
+
86
test_expect_success 'merge and rebase should match' '
87
git diff-tree -r test-rebase test-merge >difference &&
88
if test -s difference