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?

  • Could you include the exact messages you're seeing? Normally git status is pretty clear about which branches have new commits, but it sounds like it isn't on your machine.
    – derobert
    Commented Aug 28, 2019 at 15:28
  • 1
    example: repo "main" has submodule "sub". I make changes in "sub", commit and push them into "sub" origin. 'git status' on "main" shows "new commits" on "sub". The other case: 'git pull' on "main" pulls in a new commit reference for "sub". 'git status' on "main" shows "new commits" on "sub". "new commits" shows up for two very different cases: one tells me i need to "add", "commit", and "push". The other case tell me i need to "git submodule update".
    – patrick h
    Commented Aug 28, 2019 at 15:38
  • While your answer asks a different question, the title matched what I was looking for, and your comment answered my question. To update local submodule with new reference, use git submodule update.
    – Marko
    Commented Feb 19 at 12:49

2 Answers 2


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.

  • This addresses the 1st case i mentioned where i make changes to "SUB" and "main" now tells me it has "new commits". However, case 2, if someone else were to change "sub" and commit it to "main", I do a pull, now "git status" says "new commits", which if i wasn't paying close attention i would think that i'd have to add and commit my current "sub", when thats not the case, what i really need to do is "git sub update" to get the pulled changes. Or is there a better way to tell the difference tween "your sub is ahead and you need to add", and "your sub is behind and you need to update".
    – patrick h
    Commented Aug 28, 2019 at 17:20
  • 2
    If you just want to set your submodules back to the state they are represented in from the top level repository you can run git submodule update --init --recursive.
    – mfurseman
    Commented May 20, 2022 at 10:35

Comment from mfurseman is the best solution, as far as I know:

git submodule update --init --recursive

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .