Skip to content

Commit 68f8ff8

Browse files
roger-straingitster
authored andcommitted
subtree: improve decision on merges kept in split
When multiple identical parents are detected for a commit being considered for copying, explicitly check whether one is the common merge base between the commits. If so, the other commit can be used as the identical parent; if not, a merge must be performed to maintain history. In some situations two parents of a merge commit may appear to both have identical subtree content with each other and the current commit. However, those parents can potentially come from different commit graphs. Previous behavior would simply select one of the identical parents to serve as the replacement for this commit, based on the order in which they were processed. New behavior compares the merge base between the commits to determine if a new merge commit is necessary to maintain history despite the identical content. Signed-off-by: Strain, Roger L <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 315a84f commit 68f8ff8

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

contrib/subtree/git-subtree.sh

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -541,14 +541,32 @@ copy_or_skip () {
541541
nonidentical=
542542
p=
543543
gotparents=
544+
copycommit=
544545
for parent in $newparents
545546
do
546547
ptree=$(toptree_for_commit $parent) || exit $?
547548
test -z "$ptree" && continue
548549
if test "$ptree" = "$tree"
549550
then
550551
# an identical parent could be used in place of this rev.
551-
identical="$parent"
552+
if test -n "$identical"
553+
then
554+
# if a previous identical parent was found, check whether
555+
# one is already an ancestor of the other
556+
mergebase=$(git merge-base $identical $parent)
557+
if test "$identical" = "$mergebase"
558+
then
559+
# current identical commit is an ancestor of parent
560+
identical="$parent"
561+
elif test "$parent" != "$mergebase"
562+
then
563+
# no common history; commit must be copied
564+
copycommit=1
565+
fi
566+
else
567+
# first identical parent detected
568+
identical="$parent"
569+
fi
552570
else
553571
nonidentical="$parent"
554572
fi
@@ -571,7 +589,6 @@ copy_or_skip () {
571589
fi
572590
done
573591

574-
copycommit=
575592
if test -n "$identical" && test -n "$nonidentical"
576593
then
577594
extras=$(git rev-list --count $identical..$nonidentical)

0 commit comments

Comments
 (0)