Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to see which commit a git submodule points at

As far as I know, if you add a submodule in git then it points to a certain commit in that submodule.

Is there any way to see which commit a submodule is pointing at without checking it out?

like image 453
gitaarik Avatar asked Dec 18 '13 10:12

gitaarik


People also ask

Where does git store submodule commit?

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 can I see my commit details?

`git log` command is used to view the commit history and display the necessary information of the git repository. This command displays the latest git commits information in chronological order, and the last commit will be displayed first.

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.

Can git submodule point to branch?

You can set the submodule to track a particular branch (requires git 1.8. 2+), which is what we are doing with Komodo, or you can reference a particular repository commit (the later requires updating the main repository whenever you want to pull in new changes from the module – i.e. updating the commit hash reference).


2 Answers

As the other answers explain, you can use two commands:

  • git submodule status, or
  • git ls-tree HEAD, taking only the lines where the second column is commit (if you have awk you can use git ls-tree HEAD | awk '$2 == "commit"').

However, these commands give different results!

What's the difference?

  • git submodule status always reports the current status (as the name suggests), that is, the commit that is currently checked-out. The hash that you see here is the same that you'd see by going into the submodule's directory1 and checking the latest commit (with git log or git rev-parse HEAD)
  • git ls-tree HEAD shows the target status, which is not necessarily the current one. If you want to update your submodules so that they correspond to the specified version, you have to use git submodule update.

What can cause the current and target status to differ?

The typical situation in which they differ is when you git checkout another branch/tag/commit, or you use git pull to update your current branch. Both these commands will cause HEAD to be updated to the corresponding commit. Now, if this commit specifies that your submodule has to use a different version, git submodule status will still show the old one, but the target shown by git ls-tree HEAD will already be the new one.

Is there a simpler way of noticing that they are out of sync?

Check the output of git submodule status. As the manual explains, if there's a + before the hash, it means that the currently checked-out version and the target one are different.

How do I bring them back in sync?

By running git submodule update: the new submodule will be loaded, and both commands will indicate the same commit.

Example

For example, let's say that in our repo we have a submodule called base.
The output of git submodule status is (notice the +):

+059ca6c4940813aa956e8668cb0af27efa189b22 base (release-1.2)

And the output of git ls-tree HEAD is

160000 commit fbc447ef9468def36cf4089094d6960cc51618b3 base

As we can see, the hashes are different. In fact, the + had already informed us.

Now, if we type git submodule update, it says:

Submodule path 'base': checked out 'fbc447ef9468def36cf4089094d6960cc51618b3'

And now all the commands we can use (git submodule status, git ls-tree HEAD, and git log from inside base) indicate fbc447ef9468def36cf4089094d6960cc51618b3, and there's no + in front of it in the output of git submodule status. If we run git submodule update again, nothing happens, as everything is already up to date, and there isn't even any output.


1: You have to be careful when you check the commit of a submodule, because it's tricky: to find the last commit that was made in submodule base you can't use git log base, you have to enter that directory (cd base) and then run git log from there. The reason is that the first command lists the commits of the "main" repository which set a new version of the submodule, and these commits are completely independent from those that were made inside the submodule.

like image 184
Fabio says Reinstate Monica Avatar answered Oct 05 '22 20:10

Fabio says Reinstate Monica


A more straight-forward command would be:

git submodule status

like image 45
Vitor Vanacor Avatar answered Oct 05 '22 20:10

Vitor Vanacor