Skip to content

Commit 310237b

Browse files
committed
Merge branch 'sh/maint-rebase3'
* sh/maint-rebase3: rebase--interactive: fix parent rewriting for dropped commits
2 parents 310d188 + faae853 commit 310237b

File tree

2 files changed

+174
-2
lines changed

2 files changed

+174
-2
lines changed

git-rebase--interactive.sh

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ DONE="$DOTEST"/done
3838
MSG="$DOTEST"/message
3939
SQUASH_MSG="$DOTEST"/message-squash
4040
REWRITTEN="$DOTEST"/rewritten
41+
DROPPED="$DOTEST"/dropped
4142
PRESERVE_MERGES=
4243
STRATEGY=
4344
ONTO=
@@ -182,8 +183,12 @@ pick_one_preserving_merges () {
182183

183184
# rewrite parents; if none were rewritten, we can fast-forward.
184185
new_parents=
185-
for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -f2-)
186+
pend=" $(git rev-list --parents -1 $sha1 | cut -d' ' -f2-)"
187+
while [ "$pend" != "" ]
186188
do
189+
p=$(expr "$pend" : ' \([^ ]*\)')
190+
pend="${pend# $p}"
191+
187192
if test -f "$REWRITTEN"/$p
188193
then
189194
new_p=$(cat "$REWRITTEN"/$p)
@@ -196,7 +201,13 @@ pick_one_preserving_merges () {
196201
;;
197202
esac
198203
else
199-
new_parents="$new_parents $p"
204+
if test -f "$DROPPED"/$p
205+
then
206+
fast_forward=f
207+
pend=" $(cat "$DROPPED"/$p)$pend"
208+
else
209+
new_parents="$new_parents $p"
210+
fi
200211
fi
201212
done
202213
case $fast_forward in
@@ -607,6 +618,28 @@ first and then run 'git rebase --continue' again."
607618
#
608619
EOF
609620

621+
# Watch for commits that been dropped by --cherry-pick
622+
if test t = "$PRESERVE_MERGES"
623+
then
624+
mkdir "$DROPPED"
625+
# drop the --cherry-pick parameter this time
626+
git rev-list $MERGES_OPTION --abbrev-commit \
627+
--abbrev=7 $UPSTREAM...$HEAD --left-right | \
628+
sed -n "s/^>//p" | while read rev
629+
do
630+
grep --quiet "$rev" "$TODO"
631+
if [ $? -ne 0 ]
632+
then
633+
# Use -f2 because if rev-list is telling this commit is not
634+
# worthwhile, we don't want to track its multiple heads,
635+
# just the history of its first-parent for others that will
636+
# be rebasing on top of us
637+
full=$(git rev-parse $rev)
638+
git rev-list --parents -1 $rev | cut -d' ' -f2 > "$DROPPED"/$full
639+
fi
640+
done
641+
fi
642+
610643
has_action "$TODO" ||
611644
die_abort "Nothing to do"
612645

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
#!/bin/sh
2+
#
3+
# Copyright (c) 2008 Stephen Haberman
4+
#
5+
6+
test_description='git rebase preserve merges
7+
8+
This test runs git rebase with preserve merges and ensures commits
9+
dropped by the --cherry-pick flag have their childrens parents
10+
rewritten.
11+
'
12+
. ./test-lib.sh
13+
14+
# set up two branches like this:
15+
#
16+
# A - B - C - D - E
17+
# \
18+
# F - G - H
19+
# \
20+
# I
21+
#
22+
# where B, D and G touch the same file.
23+
24+
test_expect_success 'setup' '
25+
: > file1 &&
26+
git add file1 &&
27+
test_tick &&
28+
git commit -m A &&
29+
git tag A &&
30+
echo 1 > file1 &&
31+
test_tick &&
32+
git commit -m B file1 &&
33+
: > file2 &&
34+
git add file2 &&
35+
test_tick &&
36+
git commit -m C &&
37+
echo 2 > file1 &&
38+
test_tick &&
39+
git commit -m D file1 &&
40+
: > file3 &&
41+
git add file3 &&
42+
test_tick &&
43+
git commit -m E &&
44+
git tag E &&
45+
git checkout -b branch1 A &&
46+
: > file4 &&
47+
git add file4 &&
48+
test_tick &&
49+
git commit -m F &&
50+
git tag F &&
51+
echo 3 > file1 &&
52+
test_tick &&
53+
git commit -m G file1 &&
54+
git tag G &&
55+
: > file5 &&
56+
git add file5 &&
57+
test_tick &&
58+
git commit -m H &&
59+
git tag H &&
60+
git checkout -b branch2 F &&
61+
: > file6 &&
62+
git add file6 &&
63+
test_tick &&
64+
git commit -m I &&
65+
git tag I
66+
'
67+
68+
# A - B - C - D - E
69+
# \ \ \
70+
# F - G - H -- L \ --> L
71+
# \ | \
72+
# I -- G2 -- J -- K I -- K
73+
# G2 = same changes as G
74+
test_expect_success 'skip same-resolution merges with -p' '
75+
git checkout branch1 &&
76+
! git merge E &&
77+
echo 23 > file1 &&
78+
git add file1 &&
79+
git commit -m L &&
80+
git checkout branch2 &&
81+
echo 3 > file1 &&
82+
git commit -a -m G2 &&
83+
! git merge E &&
84+
echo 23 > file1 &&
85+
git add file1 &&
86+
git commit -m J &&
87+
echo file7 > file7 &&
88+
git add file7 &&
89+
git commit -m K &&
90+
GIT_EDITOR=: git rebase -i -p branch1 &&
91+
test $(git rev-parse branch2^^) = $(git rev-parse branch1) &&
92+
test "23" = "$(cat file1)" &&
93+
test "" = "$(cat file6)" &&
94+
test "file7" = "$(cat file7)" &&
95+
96+
git checkout branch1 &&
97+
git reset --hard H &&
98+
git checkout branch2 &&
99+
git reset --hard I
100+
'
101+
102+
# A - B - C - D - E
103+
# \ \ \
104+
# F - G - H -- L \ --> L
105+
# \ | \
106+
# I -- G2 -- J -- K I -- G2 -- K
107+
# G2 = different changes as G
108+
test_expect_success 'keep different-resolution merges with -p' '
109+
git checkout branch1 &&
110+
! git merge E &&
111+
echo 23 > file1 &&
112+
git add file1 &&
113+
git commit -m L &&
114+
git checkout branch2 &&
115+
echo 4 > file1 &&
116+
git commit -a -m G2 &&
117+
! git merge E &&
118+
echo 24 > file1 &&
119+
git add file1 &&
120+
git commit -m J &&
121+
echo file7 > file7 &&
122+
git add file7 &&
123+
git commit -m K &&
124+
! GIT_EDITOR=: git rebase -i -p branch1 &&
125+
echo 234 > file1 &&
126+
git add file1 &&
127+
GIT_EDITOR=: git rebase --continue &&
128+
test $(git rev-parse branch2^^^) = $(git rev-parse branch1) &&
129+
test "234" = "$(cat file1)" &&
130+
test "" = "$(cat file6)" &&
131+
test "file7" = "$(cat file7)" &&
132+
133+
git checkout branch1 &&
134+
git reset --hard H &&
135+
git checkout branch2 &&
136+
git reset --hard I
137+
'
138+
139+
test_done

0 commit comments

Comments
 (0)