I have in a folder a large number of projects that I cloned for quite some time; recently I moved this whole folder into one of my repos and would like to convert these cloned projects into submodules so that I can better update and control in the future. I've googled a lot on how to do this, but all the tutorials only talk about how to add submodules fresh. Anyone can help me?
Adding existing git repository as a submodule is the same as adding a new one.
- First make the folder that contains all your git repositories as itself a git repository with
git init
. - Use
git submodule add https//example.com/remoterepo ./localrepo
, where./localrepo
is your existing git repository.
- Note: You get the URL for
remoterepo
fromlocalrepo/.git/config
.
- Repeat the second step for all your existing repositories that you want to add as submodules.
- Now you can run
git submodule foreach git pull
to update all your subprojects.
You may want to write a small script to automate the second step if you have lots of submodules, which shouldn't be difficult.
#Edit The following is what I used for trying to reproduce the error mentioned in the comments. I triple checked the commands, and I still can't see the error:
git --version
mkdir submoduletest
cd submoduletest
git init --bare remote_repo_A
git init --bare remote_repo_B
git clone remote_repo_A local_repo_A
git clone remote_repo_B local_repo_B
cd local_repo_A
echo "test commit on repo B" >> test.txt
git add test.txt
git commit -m 'test commit message'
git push origin master
cd ../local_repo_B
echo "test commit on repo B" >> test.txt
git add test.txt
git commit -m 'test commit message'
git push origin master
cd ../local_repo_A
git clone ../remote_repo_B local_repo_B
git submodule add ../remote_repo_B ./local_repo_B
git submodule foreach git pull origin master
git add .
git ci -m 'we just added a submodule for remote_repo_B'
git submodule status
Use the following command to check current status of local_repo_A
, it has only two blob objects, one for 'test.txt' and another for the implicitly created '.gitmodules' file, nothing from remote_repo_B
are added to the index of local_repo_A
.
find .git/objects -type f | awk -F/ '{print $3$4}' | xargs -I {} git cat-file -t {} | grep blob
submodule
command or git in general. –
Aglow git init
is needed, simply git submodule add
will do, no git add .
is needed before executing the submodule command(which you most probably did in your test). –
Aglow git submodule add
will do" no it will not. I just tested it, multiple times to make sure I am not mistaken. If you have a git repository B cloned in another git repository A, then trying to make B a submodule with your answer WILL generate an error. You rolled back two approved edits? Wow thats very nice. Fine, you may not accept the error in your answer, you may roll back approved edits that only add value to answer, not brake it in either case, then you should welcome when I copy your answer and add add my edit. –
Raid To add many submodules, I wrote this simple loop:
for repo in vim/bundle/*
do
echo $repo
pushd $repo
url=$(git remote get-url $(git remote))
echo $url
popd
git submodule add $url ./$repo
done
Obvious limitations I didn't bother fixing:
- don't need to change directory, pretty sure you can pass the git directory as an argument to commands
git remote
actually returns all remotes, not just the current, so script will break if there are multiple
pushd
and popd
should be replacable by the -C <path>
option of git, i.e., git -C $repo submodule add $url ./$repo
. The second limitation should be solvable using for remote in $(git remote); do ...; done
where ...
is the url variable declaration, echo and submodule add. But as I didn't test it (yet), I won't edit the answer for this. –
Hairball I will add onto @neevek's answer, if you get the already exists in the index
error, then you can try this version:
Remove every "already cloned repository" from cache:
(Because there is already an object there that does not point to the repository as a submodule, and it has to be deleted from index first to prevent conflict. Your repositories' contents or index will not be deleted upon doing this)git rm --cached ./localrepo
Use
git submodule add https//example.com/remoterepo ./localrepo
, where./localrepo
is your existing git repository.- Note: You get the URL for
remoterepo
fromlocalrepo/.git/config
.
- Note: You get the URL for
- Repeat the second step for all your existing repositories that you want to add as submodules.
- Now you can run
git submodule foreach git pull
to update all your subprojects.
If you have lots of submodules, you may want to write a small script to automate the second step.
git rm --cached ./localrepo
This was missing for me in other answers. Otherwise I got '<rep>' already exists in the index
–
Setup © 2022 - 2024 — McMap. All rights reserved.