Skip to content

Commit 315a84f

Browse files
roger-straingitster
authored andcommitted
subtree: use commits before rejoins for splits
Adds recursive evaluation of parent commits which were not part of the initial commit list when performing a split. Split expects all relevant commits to be reachable from the target commit but not reachable from any previous rejoins. However, a branch could be based on a commit prior to a rejoin, then later merged back into the current code. In this case, a parent to the commit will not be present in the initial list of commits, trigging an "incorrect order" warning. Previous behavior was to consider that commit to have no parent, creating an original commit containing all subtree content. This commit is not present in an existing subtree commit graph, changing commit hashes and making pushing to a subtree repo impossible. New behavior will recursively check these unexpected parent commits to track them back to either an earlier rejoin, or a true original commit. The generated synthetic commits will properly match previously-generated commits, allowing successful pushing to a prior subtree repo. Signed-off-by: Strain, Roger L <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent dd21d43 commit 315a84f

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

contrib/subtree/git-subtree.sh

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -231,12 +231,14 @@ cache_miss () {
231231
}
232232

233233
check_parents () {
234-
missed=$(cache_miss "$@")
234+
missed=$(cache_miss "$1")
235+
local indent=$(($2 + 1))
235236
for miss in $missed
236237
do
237238
if ! test -r "$cachedir/notree/$miss"
238239
then
239240
debug " incorrect order: $miss"
241+
process_split_commit "$miss" "" "$indent"
240242
fi
241243
done
242244
}
@@ -606,8 +608,20 @@ ensure_valid_ref_format () {
606608
process_split_commit () {
607609
local rev="$1"
608610
local parents="$2"
609-
revcount=$(($revcount + 1))
610-
progress "$revcount/$revmax ($createcount)"
611+
local indent=$3
612+
613+
if test $indent -eq 0
614+
then
615+
revcount=$(($revcount + 1))
616+
else
617+
# processing commit without normal parent information;
618+
# fetch from repo
619+
parents=$(git show -s --pretty=%P "$rev")
620+
extracount=$(($extracount + 1))
621+
fi
622+
623+
progress "$revcount/$revmax ($createcount) [$extracount]"
624+
611625
debug "Processing commit: $rev"
612626
exists=$(cache_get "$rev")
613627
if test -n "$exists"
@@ -617,14 +631,13 @@ process_split_commit () {
617631
fi
618632
createcount=$(($createcount + 1))
619633
debug " parents: $parents"
634+
check_parents "$parents" "$indent"
620635
newparents=$(cache_get $parents)
621636
debug " newparents: $newparents"
622637

623638
tree=$(subtree_for_commit "$rev" "$dir")
624639
debug " tree is: $tree"
625640

626-
check_parents $parents
627-
628641
# ugly. is there no better way to tell if this is a subtree
629642
# vs. a mainline commit? Does it matter?
630643
if test -z "$tree"
@@ -744,10 +757,11 @@ cmd_split () {
744757
revmax=$(eval "$grl" | wc -l)
745758
revcount=0
746759
createcount=0
760+
extracount=0
747761
eval "$grl" |
748762
while read rev parents
749763
do
750-
process_split_commit "$rev" "$parents"
764+
process_split_commit "$rev" "$parents" 0
751765
done || exit $?
752766

753767
latest_new=$(cache_get latest_new)

0 commit comments

Comments
 (0)