Skip to content

Commit 501770e

Browse files
iveqygitster
authored andcommitted
Move git-dir for submodules
Move git-dir for submodules into $GIT_DIR/modules/[name_of_submodule] of the superproject. This is a step towards being able to delete submodule directories without loosing the information from their .git directory as that is now stored outside the submodules work tree. This is done relying on the already existent .git-file functionality. When adding or updating a submodule whose git directory is found under $GIT_DIR/modules/[name_of_submodule], don't clone it again but simply point the .git-file to it and remove the now stale index file from it. The index will be recreated by the following checkout. This patch will not affect already cloned submodules at all. Tests that rely on .git being a directory have been fixed. Signed-off-by: Fredrik Gustafsson <[email protected]> Mentored-by: Jens Lehmann <[email protected]> Mentored-by: Heiko Voigt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent abc0682 commit 501770e

File tree

3 files changed

+149
-7
lines changed

3 files changed

+149
-7
lines changed

git-submodule.sh

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,49 @@ module_clone()
122122
path=$1
123123
url=$2
124124
reference="$3"
125+
gitdir=
126+
gitdir_base=
127+
name=$(module_name "$path")
128+
base_path=$(dirname "$path")
125129

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

135170
#

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

t/t7408-submodule-reference.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ git commit -m B-super-added'
4343
cd "$base_dir"
4444

4545
test_expect_success 'after add: existence of info/alternates' \
46-
'test `wc -l <super/sub/.git/objects/info/alternates` = 1'
46+
'test `wc -l <super/.git/modules/sub/objects/info/alternates` = 1'
4747

4848
cd "$base_dir"
4949

@@ -66,7 +66,7 @@ test_expect_success 'update with reference' \
6666
cd "$base_dir"
6767

6868
test_expect_success 'after update: existence of info/alternates' \
69-
'test `wc -l <super-clone/sub/.git/objects/info/alternates` = 1'
69+
'test `wc -l <super-clone/.git/modules/sub/objects/info/alternates` = 1'
7070

7171
cd "$base_dir"
7272

0 commit comments

Comments
 (0)