rebase--interactive: fix parent rewriting for dropped commits
`rebase -i -p` got its rev-list of commits to keep by --left-right and --cherry-pick. Adding --cherry-pick would drop commits that duplicated changes already in the rebase target. The dropped commits were then forgotten about when it came to rewriting the parents of their descendents, so the descendents would get cherry-picked with their old, unwritten parents and essentially make the rebase a no-op. This commit adds a $DOTEST/dropped directory to remember dropped commits and rewrite their children's parent as the dropped commit's possibly-rewritten first-parent. Signed-off-by: Stephen Haberman <stephen@exigencecorp.com> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:

committed by
Junio C Hamano

parent
c82efafcfa
commit
faae853ca6
@ -37,6 +37,7 @@ DONE="$DOTEST"/done
|
||||
MSG="$DOTEST"/message
|
||||
SQUASH_MSG="$DOTEST"/message-squash
|
||||
REWRITTEN="$DOTEST"/rewritten
|
||||
DROPPED="$DOTEST"/dropped
|
||||
PRESERVE_MERGES=
|
||||
STRATEGY=
|
||||
ONTO=
|
||||
@ -179,8 +180,12 @@ pick_one_preserving_merges () {
|
||||
|
||||
# rewrite parents; if none were rewritten, we can fast-forward.
|
||||
new_parents=
|
||||
for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -f2-)
|
||||
pend=" $(git rev-list --parents -1 $sha1 | cut -d' ' -f2-)"
|
||||
while [ "$pend" != "" ]
|
||||
do
|
||||
p=$(expr "$pend" : ' \([^ ]*\)')
|
||||
pend="${pend# $p}"
|
||||
|
||||
if test -f "$REWRITTEN"/$p
|
||||
then
|
||||
new_p=$(cat "$REWRITTEN"/$p)
|
||||
@ -193,7 +198,13 @@ pick_one_preserving_merges () {
|
||||
;;
|
||||
esac
|
||||
else
|
||||
new_parents="$new_parents $p"
|
||||
if test -f "$DROPPED"/$p
|
||||
then
|
||||
fast_forward=f
|
||||
pend=" $(cat "$DROPPED"/$p)$pend"
|
||||
else
|
||||
new_parents="$new_parents $p"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
case $fast_forward in
|
||||
@ -599,6 +610,28 @@ first and then run 'git rebase --continue' again."
|
||||
#
|
||||
EOF
|
||||
|
||||
# Watch for commits that been dropped by --cherry-pick
|
||||
if test t = "$PRESERVE_MERGES"
|
||||
then
|
||||
mkdir "$DROPPED"
|
||||
# drop the --cherry-pick parameter this time
|
||||
git rev-list $MERGES_OPTION --abbrev-commit \
|
||||
--abbrev=7 $UPSTREAM...$HEAD --left-right | \
|
||||
sed -n "s/^>//p" | while read rev
|
||||
do
|
||||
grep --quiet "$rev" "$TODO"
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
# Use -f2 because if rev-list is telling this commit is not
|
||||
# worthwhile, we don't want to track its multiple heads,
|
||||
# just the history of its first-parent for others that will
|
||||
# be rebasing on top of us
|
||||
full=$(git rev-parse $rev)
|
||||
git rev-list --parents -1 $rev | cut -d' ' -f2 > "$DROPPED"/$full
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
has_action "$TODO" ||
|
||||
die_abort "Nothing to do"
|
||||
|
||||
|
Reference in New Issue
Block a user