Skip to content

Commit efc5fb6

Browse files
committed
Merge branch 'fg/submodule-git-file-git-dir'
* fg/submodule-git-file-git-dir: Move git-dir for submodules rev-parse: add option --resolve-git-dir <path> Conflicts: cache.h git-submodule.sh
2 parents 27c0f76 + 501770e commit efc5fb6

10 files changed

+244
-67
lines changed

Documentation/git-rev-parse.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ print a message to stderr and exit with nonzero status.
180180
<args>...::
181181
Flags and parameters to be parsed.
182182

183+
--resolve-git-dir <path>::
184+
Check if <path> is a valid git-dir or a git-file pointing to a valid
185+
git-dir. If <path> is a valid git-dir the resolved path to git-dir will
186+
be printed.
183187

184188
include::revisions.txt[]
185189

builtin/rev-parse.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,14 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
468468
return 0;
469469
}
470470

471+
if (argc > 2 && !strcmp(argv[1], "--resolve-git-dir")) {
472+
const char *gitdir = resolve_gitdir(argv[2]);
473+
if (!gitdir)
474+
die("not a gitdir '%s'", argv[2]);
475+
puts(gitdir);
476+
return 0;
477+
}
478+
471479
if (argc > 1 && !strcmp("-h", argv[1]))
472480
usage(builtin_rev_parse_usage);
473481

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ extern const char *get_git_namespace(void);
439439
extern const char *strip_namespace(const char *namespaced_ref);
440440
extern const char *get_git_work_tree(void);
441441
extern const char *read_gitfile(const char *path);
442+
extern const char *resolve_gitdir(const char *suspect);
442443
extern void set_git_work_tree(const char *tree);
443444

444445
#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"

git-submodule.sh

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,49 @@ module_clone()
128128
quiet=-q
129129
fi
130130

131-
if test -n "$reference"
131+
gitdir=
132+
gitdir_base=
133+
name=$(module_name "$path")
134+
base_path=$(dirname "$path")
135+
136+
gitdir=$(git rev-parse --git-dir)
137+
gitdir_base="$gitdir/modules/$base_path"
138+
gitdir="$gitdir/modules/$path"
139+
140+
case $gitdir in
141+
/*)
142+
a="$(cd_to_toplevel && pwd)/"
143+
b=$gitdir
144+
while [ "$b" ] && [ "${a%%/*}" = "${b%%/*}" ]
145+
do
146+
a=${a#*/} b=${b#*/};
147+
done
148+
149+
rel="$a$name"
150+
rel=`echo $rel | sed -e 's|[^/]*|..|g'`
151+
rel_gitdir="$rel/$b"
152+
;;
153+
*)
154+
rel=`echo $name | sed -e 's|[^/]*|..|g'`
155+
rel_gitdir="$rel/$gitdir"
156+
;;
157+
esac
158+
159+
if test -d "$gitdir"
132160
then
133-
git-clone $quiet "$reference" -n "$url" "$path"
161+
mkdir -p "$path"
162+
echo "gitdir: $rel_gitdir" >"$path/.git"
163+
rm -f "$gitdir/index"
134164
else
135-
git-clone $quiet -n "$url" "$path"
136-
fi ||
137-
die "$(eval_gettext "Clone of '\$url' into submodule path '\$path' failed")"
165+
mkdir -p "$gitdir_base"
166+
if test -n "$reference"
167+
then
168+
git-clone $quiet "$reference" -n "$url" "$path" --separate-git-dir "$gitdir"
169+
else
170+
git-clone $quiet -n "$url" "$path" --separate-git-dir "$gitdir"
171+
fi ||
172+
die "$(eval_gettext "Clone of '\$url' into submodule path '\$path' failed")"
173+
fi
138174
}
139175

140176
#
@@ -426,6 +462,9 @@ cmd_update()
426462
--recursive)
427463
recursive=1
428464
;;
465+
--checkout)
466+
update="checkout"
467+
;;
429468
--)
430469
shift
431470
break
@@ -458,7 +497,19 @@ cmd_update()
458497
fi
459498
name=$(module_name "$path") || exit
460499
url=$(git config submodule."$name".url)
461-
update_module=$(git config submodule."$name".update)
500+
if ! test -z "$update"
501+
then
502+
update_module=$update
503+
else
504+
update_module=$(git config submodule."$name".update)
505+
fi
506+
507+
if test "$update_module" = "none"
508+
then
509+
echo "Skipping submodule '$path'"
510+
continue
511+
fi
512+
462513
if test -z "$url"
463514
then
464515
# Only mention uninitialized submodules when its
@@ -480,11 +531,6 @@ Maybe you want to use 'update --init'?")"
480531
die "$(eval_gettext "Unable to find current revision in submodule path '\$path'")"
481532
fi
482533

483-
if ! test -z "$update"
484-
then
485-
update_module=$update
486-
fi
487-
488534
if test "$subsha1" != "$sha1"
489535
then
490536
subforce=$force

setup.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -812,3 +812,10 @@ const char *setup_git_directory(void)
812812
{
813813
return setup_git_directory_gently(NULL);
814814
}
815+
816+
const char *resolve_gitdir(const char *suspect)
817+
{
818+
if (is_git_directory(suspect))
819+
return suspect;
820+
return read_gitfile(suspect);
821+
}

t/t7400-submodule-basic.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,10 +362,10 @@ test_expect_success 'update --init' '
362362
git submodule update init > update.out &&
363363
cat update.out &&
364364
test_i18ngrep "not initialized" update.out &&
365-
! test -d init/.git &&
365+
test_must_fail git rev-parse --resolve-git-dir init/.git &&
366366
367367
git submodule update --init init &&
368-
test -d init/.git
368+
git rev-parse --resolve-git-dir init/.git
369369
'
370370

371371
test_expect_success 'do not add files from a submodule' '

t/t7403-submodule-sync.sh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,9 @@ test_expect_success '"git submodule sync" should update submodule URLs' '
5656
git pull --no-recurse-submodules &&
5757
git submodule sync
5858
) &&
59-
test -d "$(git config -f super-clone/submodule/.git/config \
60-
remote.origin.url)" &&
59+
test -d "$(cd super-clone/submodule &&
60+
git config remote.origin.url
61+
)" &&
6162
(cd super-clone/submodule &&
6263
git checkout master &&
6364
git pull

t/t7406-submodule-update.sh

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,7 @@ test_expect_success 'submodule update exit immediately in case of merge conflict
408408
test_cmp expect actual
409409
)
410410
'
411+
411412
test_expect_success 'submodule update exit immediately after recursive rebase error' '
412413
(cd super &&
413414
git checkout master &&
@@ -442,4 +443,110 @@ test_expect_success 'submodule update exit immediately after recursive rebase er
442443
test_cmp expect actual
443444
)
444445
'
446+
447+
test_expect_success 'add different submodules to the same path' '
448+
(cd super &&
449+
git submodule add ../submodule s1 &&
450+
test_must_fail git submodule add ../merging s1
451+
)
452+
'
453+
454+
test_expect_success 'submodule add places git-dir in superprojects git-dir' '
455+
(cd super &&
456+
mkdir deeper &&
457+
git submodule add ../submodule deeper/submodule &&
458+
(cd deeper/submodule &&
459+
git log > ../../expected
460+
) &&
461+
(cd .git/modules/deeper/submodule &&
462+
git log > ../../../../actual
463+
) &&
464+
test_cmp actual expected
465+
)
466+
'
467+
468+
test_expect_success 'submodule update places git-dir in superprojects git-dir' '
469+
(cd super &&
470+
git commit -m "added submodule"
471+
) &&
472+
git clone super super2 &&
473+
(cd super2 &&
474+
git submodule init deeper/submodule &&
475+
git submodule update &&
476+
(cd deeper/submodule &&
477+
git log > ../../expected
478+
) &&
479+
(cd .git/modules/deeper/submodule &&
480+
git log > ../../../../actual
481+
) &&
482+
test_cmp actual expected
483+
)
484+
'
485+
486+
test_expect_success 'submodule add places git-dir in superprojects git-dir recursive' '
487+
(cd super2 &&
488+
(cd deeper/submodule &&
489+
git submodule add ../submodule subsubmodule &&
490+
(cd subsubmodule &&
491+
git log > ../../../expected
492+
) &&
493+
git commit -m "added subsubmodule" &&
494+
git push
495+
) &&
496+
(cd .git/modules/deeper/submodule/modules/subsubmodule &&
497+
git log > ../../../../../actual
498+
) &&
499+
git add deeper/submodule &&
500+
git commit -m "update submodule" &&
501+
git push &&
502+
test_cmp actual expected
503+
)
504+
'
505+
506+
test_expect_success 'submodule update places git-dir in superprojects git-dir recursive' '
507+
mkdir super_update_r &&
508+
(cd super_update_r &&
509+
git init --bare
510+
) &&
511+
mkdir subsuper_update_r &&
512+
(cd subsuper_update_r &&
513+
git init --bare
514+
) &&
515+
mkdir subsubsuper_update_r &&
516+
(cd subsubsuper_update_r &&
517+
git init --bare
518+
) &&
519+
git clone subsubsuper_update_r subsubsuper_update_r2 &&
520+
(cd subsubsuper_update_r2 &&
521+
test_commit "update_subsubsuper" file &&
522+
git push origin master
523+
) &&
524+
git clone subsuper_update_r subsuper_update_r2 &&
525+
(cd subsuper_update_r2 &&
526+
test_commit "update_subsuper" file &&
527+
git submodule add ../subsubsuper_update_r subsubmodule &&
528+
git commit -am "subsubmodule" &&
529+
git push origin master
530+
) &&
531+
git clone super_update_r super_update_r2 &&
532+
(cd super_update_r2 &&
533+
test_commit "update_super" file &&
534+
git submodule add ../subsuper_update_r submodule &&
535+
git commit -am "submodule" &&
536+
git push origin master
537+
) &&
538+
rm -rf super_update_r2 &&
539+
git clone super_update_r super_update_r2 &&
540+
(cd super_update_r2 &&
541+
git submodule update --init --recursive &&
542+
(cd submodule/subsubmodule &&
543+
git log > ../../expected
544+
) &&
545+
(cd .git/modules/submodule/modules/subsubmodule
546+
git log > ../../../../../actual
547+
)
548+
test_cmp actual expected
549+
)
550+
'
551+
445552
test_done

0 commit comments

Comments
 (0)