Skip to content

Commit f4b2c2f

Browse files
committed
Fix #296, Replace --first-parent with --ancestry-path
We used --first-parent for rev-list to avoid creating large tree. In some cases the first parent will not include the start..stop commits. Replacing this with --ancestry-path to get valid commits and also added an extra check to avoid using multiple paths.
1 parent f0ebc0d commit f4b2c2f

File tree

4 files changed

+112
-5
lines changed

4 files changed

+112
-5
lines changed

lib/git-subrepo

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -698,17 +698,30 @@ subrepo:branch() {
698698
local last_gitrepo_commit=
699699
local first_gitrepo_commit=
700700

701-
# TODO: Currently --first-parent avoids the branching
702-
# Should you create a more complex structure instead?
703701
o "Subrepo parent: $subrepo_parent"
704702
if [[ -n "$subrepo_parent" ]]; then
705703
local prev_commit=
704+
local ancestor=
706705
o "Create new commits with parents into the subrepo fetch"
707-
OUT=true RUN git rev-list --reverse --first-parent "$subrepo_parent..HEAD"
706+
OUT=true RUN git rev-list --reverse --ancestry-path "$subrepo_parent..HEAD"
708707
local commit_list="$output"
709708
for commit in $commit_list; do
710709
o "Working on $commit"
711710

711+
# Only include the commit if it's a child of the previous commit
712+
# This way we create a single path between $subrepo_parent..HEAD
713+
if [[ -n "$ancestor" ]]; then
714+
local is_direct_child=$(git show -s --pretty=format:"%P" $commit | grep "$ancestor")
715+
o "is child: $is_direct_child"
716+
if [[ -z "$is_direct_child" ]]; then
717+
o "Ignore $commit, it's not in the selected path"
718+
continue
719+
fi
720+
fi
721+
722+
# Remember the previous commit from the parent repo path
723+
ancestor="$commit"
724+
712725
o "Find out the .gitrepo reference"
713726
FAIL=false OUT=true RUN git config --blob \
714727
"$commit":"$subdir/.gitrepo" "subrepo.commit"
@@ -717,7 +730,7 @@ subrepo:branch() {
717730
o "Check for rebase"
718731
if git:rev-exists "$refs_subrepo_fetch"; then
719732
if ! git:commit-in-rev-list "$gitrepo_commit" "$refs_subrepo_fetch"; then
720-
error "Can't branch: '$refs_subrepo_fetch' doesn't contain $gitrepo_commit."
733+
error "Local repository does not contain $gitrepo_commit. Try to 'git subrepo fetch $subref' of add the '-F' flag to always fetch the latest content."
721734
fi
722735
fi
723736

test/branch-rev-list-one-path.t

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/usr/bin/env bash
2+
3+
set -e
4+
5+
source test/setup
6+
7+
use Test::More
8+
9+
clone-foo-and-bar
10+
11+
subrepo-clone-bar-into-foo
12+
13+
(
14+
cd $OWNER/foo
15+
branchpoint=$(git rev-parse HEAD)
16+
add-new-files bar/file1
17+
add-new-files bar/file2
18+
git checkout -b other $branchpoint
19+
add-new-files bar/file3
20+
add-new-files bar/file4
21+
add-new-files bar/file5
22+
git merge master
23+
) >& /dev/null || die
24+
25+
test-exists "$OWNER/foo/bar/file1" "$OWNER/foo/bar/file2" "$OWNER/foo/bar/file3" "$OWNER/foo/bar/file4" "$OWNER/foo/bar/file5"
26+
27+
is "$(
28+
cd $OWNER/foo
29+
git subrepo branch bar
30+
)" \
31+
"Created branch 'subrepo/bar' and worktree '.git/tmp/subrepo/bar'." \
32+
"subrepo branch command output is correct"
33+
34+
is "$(
35+
cd $OWNER/foo
36+
git rev-list subrepo/bar | wc -l
37+
)" \
38+
"6" \
39+
"We have only created commits for one of the paths"
40+
41+
done_testing
42+
43+
teardown

test/branch-rev-list.t

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/usr/bin/env bash
2+
3+
set -e
4+
5+
source test/setup
6+
7+
use Test::More
8+
9+
clone-foo-and-bar
10+
11+
subrepo-clone-bar-into-foo
12+
13+
(
14+
cd $OWNER/foo
15+
branchpoint=$(git rev-parse HEAD)
16+
add-new-files bar/file1
17+
# We push here to force subrepo to handle
18+
# histories where it's not first parent
19+
git subrepo push bar
20+
add-new-files bar/file2
21+
git checkout -b other $branchpoint
22+
add-new-files bar/file3
23+
add-new-files bar/file4
24+
add-new-files bar/file5
25+
git merge master
26+
) >& /dev/null || die
27+
28+
test-exists "$OWNER/foo/bar/file1" "$OWNER/foo/bar/file2" "$OWNER/foo/bar/file3" "$OWNER/foo/bar/file4" "$OWNER/foo/bar/file5"
29+
30+
# -F is needed for branch to fetch new information
31+
is "$(
32+
cd $OWNER/foo
33+
git subrepo -F branch bar
34+
)" \
35+
"Created branch 'subrepo/bar' and worktree '.git/tmp/subrepo/bar'." \
36+
"subrepo branch command output is correct"
37+
38+
is "$(
39+
cd $OWNER/foo
40+
git rev-list subrepo/bar | wc -l
41+
)" \
42+
"5" \
43+
"We have only created commits for one of the paths"
44+
45+
done_testing
46+
47+
teardown

test/branch.t

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,21 @@ before="$(date -r $OWNER/foo/Foo '+%s')"
2020

2121
save-original-state $OWNER/foo bar
2222

23+
# Make sure that time stamps differ
24+
sleep 1
25+
2326
is "$(
2427
cd $OWNER/foo
2528
git subrepo branch bar
2629
)" \
2730
"Created branch 'subrepo/bar' and worktree '.git/tmp/subrepo/bar'." \
2831
"subrepo branch command output is correct"
2932

30-
sleep 1
33+
3134
after="$(date -r $OWNER/foo/Foo '+%s')"
3235
assert-original-state $OWNER/foo bar
3336

37+
# Check that we haven't checked out any temporary files
3438
is "$before" "$after" \
3539
"No modification on Foo"
3640

0 commit comments

Comments
 (0)