Here is a step by step solution for reproduction. This is how I make all my submodule workflows work.
The involved mininmal example repositories are linked here for those who are interested:
https://github.com/jankapunkt/submodule-main
https://github.com/jankapunkt/submodules-sub1
Part I - adding the submodule
Create a new bare repository, which will be our main dev repo. Let's call ist yourName/submodule-main
Create a second new repository with some folders and content, which will be our submodule repo. Let's call it yourName/submodules-sub1
Clone the sub1 repo, add some content and push it back to origin
git clone git@github:yourName/submodules-sub1.git
cd submodules-sub1/
# create some content
mkdir somefolder
touch HELLO.md
echo "yeehaw" > ./HELLO.md
# add, commit and push
git add somefolder/
git commit somefolder/HELLO.md -m "added some content"
git push origin master
# note the commit hash here:
# dbcc1ef..8293526 master -> master
Go back and delete the repo (or not, doesn't matter)
Clone the submodule-main
repo
cd ..
git clone git@github.com:yourName/submodule-main.git
- Add the
sub1
as submodule with tracking a specific branch (in our case master branch):
cd ./submodule-main/
git submodule add -b master git@github.com:jankapunkt/submodules-sub1.git ./submodules-sub1
Note, that the pattern is submodule add -b <branch> <repository> <path>
. The now created structure looks like this:
.
..
.git
.gitmodules
LICENSE
README.md
submodules-sub1
And .gitmodules
should contain
[submodule "submodules-sub1"]
path = submodules-sub1
url = git@github.yourName/submodules-sub1.git
branch = master
- Add / commit these changes
git add -A
git commit -a -m "sub1 submodule added"
git push origin master
Go check your repo on Github, it will contain an exact copy of the current development state of sub1
including the reference to the latest commit, for example:
submodules-sub1 @ 8293526
It should contain a complete copy / snapshot of the referenced commit of this submodule including all files and folders.
Part II - updating the submodule
Now you want to always update your main repo with the tracking state of the sub repo.
- go into the submodule directory and make some changes
cd submodules-sub1/somefolder/
touch FOO.md
echo "bar baz" > FOO.md
git add FOO.md
git commit FOO.md -m "added FOO.md"
- Push your state to the branch, which is tracked by the
submodule-main
repo
Now here are two cases that can happen. Enter git status
to see your current HEAD
position:
a - you are already tracking master
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
Great, you are already tracking the right branch, just git push origin master
b - you are in detached HEAD state (for example after submodule-main
did a submodules update
)
Now you need to make HEAD point to the right commit (I use some example hash here):
git log -1 # copy the commit hash, for example e6227de6b7042c06afa0062ec900386a817a058e
git checkout master
git reset --hard e6227de6b7042c06afa0062ec900386a817a058e
git push origin master
- Update main repo
Now you have updated the code in your sub1
directory but nothing has been updated in the main
yet. Therefore we also need to update the main
repo and point to the latest submodule commits:
cd ..
git status
you should see a notice about new commits:
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: submodules-sub1 (new commits)
no changes added to commit (use "git add" and/or "git commit -a")
Now you commit these changes, too and push all to your origin
:
git commit submodules-sub1/ -m "sub1 updated some folder content"
git push origin master
Note, that on your origin
there is not another commit pointed to in your main
repo:
submodules-sub1 @ e6227de
Part III - Cloning for your endusers
Assume your endusers want now clone a kind of "snapshot" where all submodules point to a certain commit on a certain branch (I really simplified this here using master
with the latest commits) they should just clone recursive and should be able to build immediately:
git clone git@github.com:jankapunkt/submodule-main.git --recurse-submodules
You can also verify this by entering the submodules-sub1
folder and enter git status
, which should now point to e6227de
:
HEAD detached at e6227de
nothing to commit, working tree clean
Used documentation is
https://git-scm.com/docs/git-submodule
https://git-scm.com/docs/git-clone