I have spent a lot of time in reading and trying out git submodules. But I have really given up.
My problem:
I am cloning a git repository as a submodule. So, I do
git submodule add -b master url localpath
The repository starts downloading and a corresponding entry is made in the .gitmodules file. git submodule status shows the latest commit.
So far so good.
During the development, it was found out that the HEAD commit in the submodule has a bug. So, the commit should be changed from master to some commit id.
So, I changed the commit id ( 7 aplhanumeric ) in the .gitmodule file from branch = master
branch = <commitid> -> .gitmodule file
And did
git submodule update --remote
The error is
Fatal: Need a single revision
Unable to find current origin/ revision in submodule path
I also tried
git submodule foreach git pull
so that it will pull the commit id, but it simply returns with
Entering name_of_the_submodule
Already up to date.
Can anyone please help me?
P.S: I have already gone through many tutorials and question and answers. So if you want to downvote this for fun, then please first point to an answer and I will delete this post.
In order to update an existing Git submodule, you need to execute the “git submodule update” with the “–remote” and the “–merge” option. Using the “–remote” command, you will be able to update your existing Git submodules without having to run “git pull” commands in each submodule of your project.
Submodules are very static and only track specific commits. Submodules do not track git refs or branches and are not automatically updated when the host repository is updated. When adding a submodule to a repository a new . gitmodules file will be created.
You can fix it by: either committing or undoing the changes/evolutions within each of your submodules, before going back to the parent repo (where the diff shouldn't report "dirty" files anymore). To undo all changes to your submodule just cd into the root directory of your submodule and do git checkout .
Initialize the repository's submodules by running git submodule init followed by git submodule update . Change into the submodule's directory. In this example, cd lib/billboard . The submodule repositories added by git submodule update are “headless”.
I am answering my own question, after a little bit of research, that might be helpful to the others:
It is a big pain to understand git submodules, but once you get it, everything starts making sense !
The following post shows:
Adding submodules
git submodule add -b
The entry in .gitmodules ( name, path, url, branch ) downloads the respective submodule by
git submodule update --init
This does three important thing, the first two of which are hidden from the user:
updates .git/config with an extra entry ( submodules )
downloads a repository in bare form under .git/modules. That means, there is .git inside a .git.
checks out the git submodule from the .git/modules into the parent directory.
Now, on Day 2, the commiter, who commited the submodule realises, that he should change the submodule to some other commit and not the HEAD. So, he would go to his local repository and then go the submodule path and then checkout the commit that he wants by simply invoking
git checkout <hash>
cd <parent dir>
git submodule status
At this point, the git submodule status still does not shows the new hash. The new hash will only be visible when the changes are staged. Now, the commiter, just needs to stage ( add ), commit and push the changes, so that it is visible to all the other developers.
Updating the added submodule
On Day 3, the other developers, would update their repository by just invoking the command
git pull # this is to get the latest commit of the parent git repository.
git submodule update --force # update the submodule with latest hash
Basically, here the point is simple: The submodule does not react until and unless it is told to do so. Just doing git pull, wont update the git submodule. The developers can continue to work on their local submodules and not sync them to the one on the server "forever". The submodule update would happen on explicitly invoking the git submodule update command.
Removing submodule
Now, on Day4, the committer, decides to remove the git submodule completely. Here the steps are also not simple, because there is nothing called git submodule rm that should have been equivalent to git submodule add. This can be done only and only if the following sequence is followed:
git submodule deinit submodulename
this deletes the .git/config entry.
this clears the submodule directory !! You will see nothing in the submdoule directory after this command.
But the contents of the submodule are still available under .git/modules
Hence a git status -u here will still show that Everyting is upto date !
So show the removals,
git rm submodulepath
At this point git status will return that .gitmodules has been changed ( the submodule has been deleted ) and the submodule path has been deleted. Commit and push the changes.
Updating with removed submodule
On Day5, the developers want to delete the submodules "automatically" like it did with git submodule update. So they do first a git pull, which succesfully removes all indices to the git submodules
git submodule status # shows nothing
BUT, the .git/config still contains valid submodule entry and the submodule folder is there with all its contents and the bare repository under .git/submodules ! There is no command to delete them. All of them must be explicitly removed via hand..( Please correct me if I am wrong )
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With