Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to revert a Git Submodule pointer to the commit stored in the containing repository?

I have a git submodule in my main git repo. As I understand it, the main repo stores a SHA value (somewhere...), pointing to the specific commit of the submodule that it is "linked to".

I went in to my submodule and typed git checkout some_other_branch. I have no idea which commit I came from.

I would like to revert that pointer so that the main repo and the submodule are in sync again.

My first (probably naive) instinct was to say git reset --hard - that seems to work for everything else. To my surprise, it did not work for this scenario.

So I've figured out that I can type git diff, note the SHA ID that the submodule pointer used to have, and then head into the submodule and git checkout [SHA ID]... but surely there must be an easier way?

As I'm still learning about git submodules, please feel free to correct my terminology if there are words for concepts that I don't know.

like image 674
Smashery Avatar asked Oct 24 '11 22:10

Smashery


People also ask

How do I change a submodule to a specific commit?

Use the git submodule update command to set the submodules to the commit specified by the main repository. This means that if you pull in new changes into the submodules, you need to create a new commit in your main repository in order to track the updates of the nested submodules.

Where is git submodule commit stored?

It is stored in Git's object database directly. The tree object for the directory where the submodule lives will have an entry for the submodule's commit (this is the so-called "gitlink").

How to reset all submodules to initial commit in Git?

In such cases, we may want to reset all submodules to the initial commit. Method 1: Reset git submodules using foreach command This method is fast because it loops each submodule and runs git reset --hard within each modules. The command is as follows.

What does revert do in Git?

The git revert command follows this principle: it introduces a new commit to the commit history whose sole purpose is to undo the changes of a targeted commit. Importantly, this means that the existing commit history prior to the newly added “undo” commit, including the original error commit, is preserved.

What is merging submodule changes in Git?

Merging Submodule Changes. If a merge commit exists in the submodule directory that contains both commits in its history, Git will suggest it to you as a possible solution. It sees that at some point in the submodule project, someone merged branches containing these two commits, so maybe you’ll want that one.

How to revert a commit in Git?

The first commit that's described there is the last commit created. Then you can copy from there the alphanumerical name and use that in the revert command. You can also use the reset command to undo your last commit.


2 Answers

To change the commit that a submodule points to, you need to checkout that version in the submodule, then go back to the containing repo, add and commit that change.

Or, if you want the submodule to be on the version the top repo points to, do git submodule update --recursive. Add --init if you've just cloned.

Also, git submodule without a submodule command will show you the commit you are pointing to. There will be a - or a + in front of the commit if it's not in sync.

If you look at a tree with a submodule in it, you can see that the submodule is marked as a commit as opposed to the rest that are blobs or trees.

to see what a particular commit points wrt to submodules you can:

git ls-tree <some sha1, or branch, etc> Submodule/path

you can then see the commit or anything else if you like by passing that into log, etc (the git-dir option at the git command level allows you to skip having to cd down to the submodule):

git --git-dir=Submodule/path log -1 $(<the above statement>)
like image 21
Adam Dymitruk Avatar answered Oct 12 '22 23:10

Adam Dymitruk


You want to update your submodule so it is in sync with what the parent repository believes it should be. This is what the update command is for:

From the submodule manpage:

Update the registered submodules, i.e. clone missing submodules and
checkout the commit specified in the index of the containing
repository. This will make the submodules HEAD be detached unless
--rebase or --merge is specified or the key submodule.$name.update
is set to rebase or merge.

Run this and all should be well:

git submodule update --init

You can add the --recursive flag as well to recurse through all submodules.

like image 55
Brian Riehman Avatar answered Oct 13 '22 01:10

Brian Riehman