Doing git submodule add
is just creating a ".git" file that points to a parent GIT folder containing the data. Example:
Why are submodules store in the parent and how can I prevent GIT from doing this? I want to keep a consistent structure like other modules I have, in which each project has their own ".git" folder sitting next to the where the project data is stored.
At the beginning submodules worked the way you described. But later Git developers decided to change to the current way of using .git
file (named gitlink) and push .git/
directory under superproject's .git/modules/
. To fix existing repositories they created git submodule absorbgitdirs
. So you can see they do all their best to do things the current way and there is no way to return to the original way of storing .git/
directory in the submodules. You can move it back manually and fix .git/config
. This is how I managed to do this for one submodule:
#! /bin/sh
set -e
# To the top-level directory of the current submodule
cd "`git rev-parse --show-toplevel`"
unset GIT_DIR
# If .git/ subdirectory is already here
test -d .git && exit 0
if ! test -f .git; then
echo "Error: Cannot find gitlink, aborting" >&2
exit 1
fi
# Fix core.worktree now
git config --unset core.worktree
read _gitdir gitpath < .git
unset _gitdir
rm .git
exec mv "$gitpath" .git
I failed to run it from git submodule foreach --recursive
because the command runs from top to bottom while my scripts can only be run from bottom to top (it doesn't fix children's .git
links).
Upd. This is recursive variant:
#! /bin/sh
# The script cannot be run with `git submodule foreach --recursive`
# because the command runs recursively from top to bottom
# while the command is required to be run from bottom to top
# because it doesn't fix childrens' gitlinks.
# So the script runs recursion itself;
# it can be run with `git submodule foreach` without `--recursive`.
set -e
START_DIR="`pwd`"
cd "`dirname \"$0\"`"
PROG_DIR="`pwd`"
cd "$START_DIR"
# To the top-level directory of the current submodule or the superproject
cd "`git rev-parse --show-toplevel`"
unset GIT_DIR
# If .git/ subdirectory is already here
test -d .git && exit 0
if ! test -f .git; then
echo "Error: Cannot find gitlink, aborting" >&2
exit 1
fi
if test -f .gitmodules; then
git submodule foreach "$PROG_DIR"/"`basename \"$0\"`"
fi
# Fix core.worktree now
git config --unset core.worktree
read _gitdir gitpath < .git
unset _gitdir
rm .git
exec mv "$gitpath" .git
Or may be you can install VERY old Git, clone with submodules in the old way, then use newer Git to work as usual.