Skip to content

Commit 0c41f33

Browse files
committed
Merge branch 'nm/maint-conflicted-submodule-entries' into maint
* nm/maint-conflicted-submodule-entries: submodule: process conflicting submodules only once
2 parents df0a6ae + 313ee0d commit 0c41f33

File tree

3 files changed

+83
-9
lines changed

3 files changed

+83
-9
lines changed

Documentation/git-submodule.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,10 @@ status::
101101
currently checked out commit for each submodule, along with the
102102
submodule path and the output of 'git describe' for the
103103
SHA-1. Each SHA-1 will be prefixed with `-` if the submodule is not
104-
initialized and `+` if the currently checked out submodule commit
104+
initialized, `+` if the currently checked out submodule commit
105105
does not match the SHA-1 found in the index of the containing
106-
repository. This command is the default command for 'git submodule'.
106+
repository and `U` if the submodule has merge conflicts.
107+
This command is the default command for 'git submodule'.
107108
+
108109
If '--recursive' is specified, this command will recurse into nested
109110
submodules, and show their status as well.

git-submodule.sh

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,24 @@ resolve_relative_url ()
7272
#
7373
module_list()
7474
{
75-
git ls-files --error-unmatch --stage -- "$@" | sane_grep '^160000 '
75+
git ls-files --error-unmatch --stage -- "$@" |
76+
perl -e '
77+
my %unmerged = ();
78+
my ($null_sha1) = ("0" x 40);
79+
while (<STDIN>) {
80+
chomp;
81+
my ($mode, $sha1, $stage, $path) =
82+
/^([0-7]+) ([0-9a-f]{40}) ([0-3])\t(.*)$/;
83+
next unless $mode eq "160000";
84+
if ($stage ne "0") {
85+
if (!$unmerged{$path}++) {
86+
print "$mode $null_sha1 U\t$path\n";
87+
}
88+
next;
89+
}
90+
print "$_\n";
91+
}
92+
'
7693
}
7794

7895
#
@@ -427,6 +444,11 @@ cmd_update()
427444
module_list "$@" |
428445
while read mode sha1 stage path
429446
do
447+
if test "$stage" = U
448+
then
449+
echo >&2 "Skipping unmerged submodule $path"
450+
continue
451+
fi
430452
name=$(module_name "$path") || exit
431453
url=$(git config submodule."$name".url)
432454
update_module=$(git config submodule."$name".update)
@@ -770,6 +792,11 @@ cmd_status()
770792
name=$(module_name "$path") || exit
771793
url=$(git config submodule."$name".url)
772794
displaypath="$prefix$path"
795+
if test "$stage" = U
796+
then
797+
say "U$sha1 $displaypath"
798+
continue
799+
fi
773800
if test -z "$url" || ! test -d "$path"/.git -o -f "$path"/.git
774801
then
775802
say "-$sha1 $displaypath"

t/t7405-submodule-merge.sh

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ test_expect_success setup '
5656

5757
# History setup
5858
#
59-
# b
60-
# / \
61-
# a d
62-
# \ /
63-
# c
59+
# b
60+
# / \
61+
# init -- a d
62+
# \ \ /
63+
# g c
6464
#
6565
# a in the main repository records to sub-a in the submodule and
6666
# analogous b and c. d should be automatically found by merging c into
@@ -76,6 +76,8 @@ test_expect_success 'setup for merge search' '
7676
git add file-a &&
7777
git commit -m "sub-a" &&
7878
git branch sub-a) &&
79+
git commit --allow-empty -m init &&
80+
git branch init &&
7981
git add sub &&
8082
git commit -m "a" &&
8183
git branch a &&
@@ -101,7 +103,13 @@ test_expect_success 'setup for merge search' '
101103
git checkout -b sub-d sub-b &&
102104
git merge sub-c) &&
103105
git commit -a -m "d" &&
104-
git branch test b)
106+
git branch test b &&
107+
108+
git checkout -b g init &&
109+
(cd sub &&
110+
git checkout -b sub-g sub-c) &&
111+
git add sub &&
112+
git commit -a -m "g")
105113
'
106114

107115
test_expect_success 'merge with one side as a fast-forward of the other' '
@@ -176,6 +184,44 @@ test_expect_success 'merging should fail for changes that are backwards' '
176184
test_must_fail git merge f)
177185
'
178186

187+
188+
# Check that the conflicting submodule is detected when it is
189+
# in the common ancestor. status should be 'U00...00"
190+
test_expect_success 'git submodule status should display the merge conflict properly with merge base' '
191+
(cd merge-search &&
192+
cat >.gitmodules <<EOF &&
193+
[submodule "sub"]
194+
path = sub
195+
url = $TRASH_DIRECTORY/sub
196+
EOF
197+
cat >expect <<EOF &&
198+
U0000000000000000000000000000000000000000 sub
199+
EOF
200+
git submodule status > actual &&
201+
test_cmp expect actual &&
202+
git reset --hard)
203+
'
204+
205+
# Check that the conflicting submodule is detected when it is
206+
# not in the common ancestor. status should be 'U00...00"
207+
test_expect_success 'git submodule status should display the merge conflict properly without merge-base' '
208+
(cd merge-search &&
209+
git checkout -b test-no-merge-base g &&
210+
test_must_fail git merge b &&
211+
cat >.gitmodules <<EOF &&
212+
[submodule "sub"]
213+
path = sub
214+
url = $TRASH_DIRECTORY/sub
215+
EOF
216+
cat >expect <<EOF &&
217+
U0000000000000000000000000000000000000000 sub
218+
EOF
219+
git submodule status > actual &&
220+
test_cmp expect actual &&
221+
git reset --hard)
222+
'
223+
224+
179225
test_expect_success 'merging with a modify/modify conflict between merge bases' '
180226
git reset --hard HEAD &&
181227
git checkout -b test2 c &&

0 commit comments

Comments
 (0)