Git submodule shows new commits, submodule status says nothing to commit

It's because Git records which commit (not a branch or a tag, exactly one commit represented in SHA-1 hash) should be checked out for each submodule. If you change something in submodule dir, Git will detect it and urge you to commit those changes in the top-level repoisitory.

Run git diff in the top-level repository to show what has actually changed Git thinks. If you've already made some commits in your submodule (thus "clean" in submodule), it reports submodule's hash change.

$ git diff
diff --git a/src/repo b/src/repo
index b0c86e2..a893d84 160000
--- a/src/repo
+++ b/src/repo
@@ -1 +1 @@
-Subproject commit b0c86e28675c9591df51eedc928f991ca42f5fea
+Subproject commit a893d84d323cf411eadf19569d90779610b10280

Otherwise it shows -dirty hash change which you cannot stage or commit in the top-level repository. git status also claims submodule has untracked/modified content.

$ git diff
diff --git a/src/repo b/src/repo
--- a/src/repo
+++ b/src/repo
@@ -1 +1 @@
-Subproject commit b0c86e28675c9591df51eedc928f991ca42f5fea
+Subproject commit b0c86e28675c9591df51eedc928f991ca42f5fea-dirty

$ git status
On branch 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)
  (commit or discard the untracked or modified content in submodules)

    modified:   src/repo (untracked content)

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

To update which commit records should be checked out for the submodule, you need to git commit the submodule in addition to committing the changes in the submodule:

git add src/repo

I just ran into this same class of problem, and I was able to use the solution offered by @AugustinAmenabar in the comments section of the accepted answer. My setup was a bit more complex, so I added the --recursive flag to bring all dependencies up to date.

git submodule update --recursive src/repo


None of the answers here solve my problem.

I am documenting/sharing here what worked for me. Hoping it helps someone else.

Initially my submodule was at commit A (at the time of adding submodule to main repo), then I checked out a branch (let us call it new-submodule-branch) and made commits B and C to it and pushed it to remote (github.com)

Post this, my main repo started showing

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   <submodule_name> (new commits)

If, from the main repo root, I ran git submodule update --remote --init --recursive, it kept reverting my submodule's HEAD in detached state to commit A

So then I set the branch value as new-submodule-branch in <MainRepo>/.gitmodules as follows

[submodule "<submodule_name>"]
    path = <submodule_name>
    url = [email protected]:ProProgrammer/<submodule_name>.git
    branch = new-submodule-branch

post this, when I ran git submodule update --remote --init --recursive, it would no longer revert my submodule's HEAD in detached state to commit A however it still kept showing the annoying

    modified:   <submodule_name> (new commits)

So far, I was following the official git reference for submodules, now I decided to do some more Googling, and I stumbled an article titled Getting git submodule to track a branch, this clearly said

You have to go and update that submodule commit reference to the latest code in the remote branch to avoid this

So finally, I did what I was trying to avoid:

git add <submodule_name>
git commit --amend --no-edit # I combined this with the previous commit where I added the 'branch' value in .gitmodules

If you want to see what this looks like once pushed to remote (github.com in my case), you can see this exact commit here

Tags:

Git