Browse Source

rebase: Support preserving merges in non-interactive mode

As a result of implementation details, 'git rebase' could
previously only preserve merges in interactive mode. That
limitation was hard for users to understand and awkward to
explain.

This patch works around it by running the interactive rebase
helper git-rebase--interactive with GIT_EDITOR set to ':'
when the user passes "-p" but not "-i" to the rebase command.
The effect is that the interactive rebase helper is used but
the user never sees an editor.

The test-case included in this patch was originally written
by Stephen Habermann <stephen@exigencecorp.com>, but has
been extensively modified since its creation.

Signed-off-by: Andreas Ericsson <ae@op5.se>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
maint
Andreas Ericsson 17 years ago committed by Shawn O. Pearce
parent
commit
f8cca019b9
  1. 3
      Documentation/git-rebase.txt
  2. 22
      git-rebase.sh
  3. 61
      t/t3409-rebase-preserve-merges.sh

3
Documentation/git-rebase.txt

@ -250,8 +250,7 @@ OPTIONS


-p:: -p::
--preserve-merges:: --preserve-merges::
Instead of ignoring merges, try to recreate them. This option Instead of ignoring merges, try to recreate them.
only works in interactive mode.


include::merge-strategies.txt[] include::merge-strategies.txt[]



22
git-rebase.sh

@ -138,10 +138,26 @@ finish_rb_merge () {
} }


is_interactive () { is_interactive () {
test -f "$dotest"/interactive || while test $# != 0
while :; do case $#,"$1" in 0,|*,-i|*,--interactive) break ;; esac do
case "$1" in
-i|--interactive)
interactive_rebase=explicit
break
;;
-p|--preserve-merges)
interactive_rebase=implied
;;
esac
shift shift
done && test -n "$1" done

if [ "$interactive_rebase" = implied ]; then
GIT_EDITOR=:
export GIT_EDITOR
fi

test -n "$interactive_rebase" || test -f "$dotest"/interactive
} }


test -f "$GIT_DIR"/rebase-apply/applying && test -f "$GIT_DIR"/rebase-apply/applying &&

61
t/t3409-rebase-preserve-merges.sh

@ -0,0 +1,61 @@
#!/bin/sh
#
# Copyright(C) 2008 Stephen Habermann & Andreas Ericsson
#
test_description='git rebase -p should preserve merges

Run "git rebase -p" and check that merges are properly carried along
'
. ./test-lib.sh

GIT_AUTHOR_EMAIL=bogus_email_address
export GIT_AUTHOR_EMAIL

#echo 'Setting up:
#
#A1--A2 <-- origin/master
# \ \
# B1--M <-- topic
# \
# B2 <-- origin/topic
#
#'

test_expect_success 'setup for merge-preserving rebase' \
'echo First > A &&
git add A &&
git-commit -m "Add A1" &&
git checkout -b topic &&
echo Second > B &&
git add B &&
git-commit -m "Add B1" &&
git checkout -f master &&
echo Third >> A &&
git-commit -a -m "Modify A2" &&

git clone ./. clone1 &&
cd clone1 &&
git checkout -b topic origin/topic &&
git merge origin/master &&
cd ..

git clone ./. clone2
cd clone2 &&
git checkout -b topic origin/topic &&
git merge origin/master &&
cd .. &&

git checkout topic &&
echo Fourth >> B &&
git commit -a -m "Modify B2"
'

test_expect_success 'rebase -p fakes interactive rebase' '
cd clone2 &&
git fetch &&
git rebase -p origin/topic &&
test 1 = $(git rev-list --all --pretty=oneline | grep "Modify A" | wc -l) &&
test 1 = $(git rev-list --all --pretty=oneline | grep "Merge commit" | wc -l)
'

test_done
Loading…
Cancel
Save