Git status with submodule shows “new commits”

git

If I have a project with submodules, make changes in the submodule, and then commit those changes, the main project will show "new commits" on that submodule.

However, if I "git pull" and update my local project, and in the pull comes a change in the submodule commit, "git status" will also show "new commits".

I'm confused that "new commits" can either mean "you have local changes you need to commit", or "you have been updated with a new reference that you need to update".

It seems like "new commits" can tell you two totally opposite things.

Is there a better way to know from the top level if you have changes you need to push, vs you have a new reference you need to update to?

Best Answer

I think what you're seeing is something like this:

$ git status
On branch master
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:   sub (new commits)

no changes added to commit (use "git add" and/or "git commit -a")

To make sense of that, you need to know that when you put a submodule in your project that git tracks not just where it was cloned from but also the most recent (or chosen) commit ID of that submodule (i.e., its HEAD). On checkout, it makes sure to grab that particular version of the submodule; if it didn't, you could wind up with an incompatible version of a submodule when checking out an old version of your code.

Git is telling you that the HEAD commit ID of the submodule has changed, and that you can commit that change to the parent project. If you do a git diff, you'll see the changed commit ID (your IDs will of course be different):

$ git diff
diff --git a/sub b/sub
index d67371f..07bc855 160000
--- a/sub
+++ b/sub
@@ -1 +1 @@
-Subproject commit d67371f7485a97dd4d00802619f93a0cb4d2df16
+Subproject commit 07bc855dd4d958783a686241b911aead1d73ca3c

It doesn't matter why the submodule's checked out HEAD commit ID changed; both pulling a new version of the submodule (via, e.g., git pull in the submodule directory) or by locally committing in the submodule directory do the same thing — change the submodule HEAD commit ID by adding more commits — as far as the parent project is concerned.

Related Question