I just reproduced the issue with git 2.9.0
All you have to do at the end to get back a clean master is:
git submodule update
That will reset the submodule to its master
value, and .git/modules/example-sub/HEAD
will have the right value
You would have the same issue when you checkout again otherbranch
.
The right gitlink (special entry in the index) will be checked out.
But the .git/modules/example-sub/HEAD
won't be changed right away.
In both cases, that is because checkout only modify the gitlink, not the content of the submodule.
Only a git submodule update
will actually check out the content of the submodule to its recorded gitlink SHA1.
That way, if you had work in progress in the submodule, they are not wiped out by a checkout in the parent repo.
Here is my own experiment:
C:\Users\vonc\prog\git\tests>mkdir subm
C:\Users\vonc\prog\git\tests>cd subm
Let's create two repos, each with one commit:
C:\Users\vonc\prog\git\tests\subm>git init s
Initialized empty Git repository in C:/Users/vonc/prog/git/tests/subm/s/.git/
C:\Users\vonc\prog\git\tests\subm>git init p
Initialized empty Git repository in C:/Users/vonc/prog/git/tests/subm/p/.git/
C:\Users\vonc\prog\git\tests\subm>cd s
C:\Users\vonc\prog\git\tests\subm\s>git commit --allow-empty -m "first s commit"
[master (root-commit) d11bd81] first s commit
C:\Users\vonc\prog\git\tests\subm\s>cd ..\p
C:\Users\vonc\prog\git\tests\subm\p>git commit --allow-empty -m "first p commit"
[master (root-commit) 10a7044] first p commit
Let's add s
as a submodule of p
(the parent repo)
C:\Users\vonc\prog\git\tests\subm\p>git submodule add -- ../s
Cloning into 'C:/Users/vonc/prog/git/tests/subm/p/s'...
done.
C:\Users\vonc\prog\git\tests\subm\p>git st
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitmodules
new file: s
C:\Users\vonc\prog\git\tests\subm\p>git commit -m "add p"
[master aa33ba9] add p
2 files changed, 4 insertions(+)
create mode 100644 .gitmodules
create mode 160000 s
Now let's modify the s
repo, adding a new commit to its master
branch
C:\Users\vonc\prog\git\tests\subm\p>cd ..\s
C:\Users\vonc\prog\git\tests\subm\s>git commit --allow-empty -m "second s commit"
[master 81e4800] second s commit
C:\Users\vonc\prog\git\tests\subm\s>gl
* 81e4800 - (HEAD -> master) second s commit (1 second ago) <VonC>
* d11bd81 - first s commit (3 minutes ago) <VonC>
Let's create a new branch in the parent repo
C:\Users\vonc\prog\git\tests\subm\s>cd ..\p
C:\Users\vonc\prog\git\tests\subm\p>git commit --allow-empty -m "second s commit"
C:\Users\vonc\prog\git\tests\subm\p>git checkout -b branch
Switched to a new branch 'branch'
Let's update the submodule, and add it to the new branch branch
:
C:\Users\vonc\prog\git\tests\subm\p>git submodule update --remote
remote: Counting objects: 1, done.
remote: Total 1 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (1/1), done.
From C:/Users/vonc/prog/git/tests/subm/s
d11bd81..81e4800 master -> origin/master
Submodule path 's': checked out '81e48007afc90aceca16d884d0fdc34074121732'
C:\Users\vonc\prog\git\tests\subm\p>git st
On branch branch
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: s (new commits)
no changes added to commit (use "git add" and/or "git commit -a")
C:\Users\vonc\prog\git\tests\subm\p>git add .
C:\Users\vonc\prog\git\tests\subm\p>git commit -m "update s to latest master"
[branch 271a4fb] update s to latest master
1 file changed, 1 insertion(+), 1 deletion(-)
C:\Users\vonc\prog\git\tests\subm\p>cat .git\modules\s\HEAD
81e48007afc90aceca16d884d0fdc34074121732
C:\Users\vonc\prog\git\tests\subm\p>gl
* 271a4fb - (HEAD -> branch) update s to latest master (26 seconds ago) <VonC>
* f86aab2 - (master) second s commit (2 minutes ago) <VonC>
* aa33ba9 - add p (3 minutes ago) <VonC>
* 10a7044 - first p commit (4 minutes ago) <VonC>
It I checkout master
, the right submodule SHA1 is checked out, but the content of the submodule is not yet changed.
C:\Users\vonc\prog\git\tests\subm\p>git checkout master
M s
Switched to branch 'master'
C:\Users\vonc\prog\git\tests\subm\p>cat .git\modules\s\HEAD
81e48007afc90aceca16d884d0fdc34074121732
C:\Users\vonc\prog\git\tests\subm\p>git st
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)
modified: s (new commits)
no changes added to commit (use "git add" and/or "git commit -a")
If I were to switch back to the branch branch
, the status would be clean (that is because the content of the submodule s
matches its recorded gitlink SHA1)
C:\Users\vonc\prog\git\tests\subm\p>git checkout branch
Switched to branch 'branch'
C:\Users\vonc\prog\git\tests\subm\p>git st
On branch branch
nothing to commit, working directory clean
But on master
, I need a submodule update
to reset the content of the submodule s
to its SHA1:
C:\Users\vonc\prog\git\tests\subm\p>git checkout master
M s
Switched to branch 'master'
C:\Users\vonc\prog\git\tests\subm\p>git submodule update
Submodule path 's': checked out 'd11bd8132971a18e3e7cd19984cc6ce106478087'
C:\Users\vonc\prog\git\tests\subm\p>cat .git\modules\s\HEAD
d11bd8132971a18e3e7cd19984cc6ce106478087
C:\Users\vonc\prog\git\tests\subm\p>git st
On branch master
nothing to commit, working directory clean
The same issue would appear when I checkout branch
:
C:\Users\vonc\prog\git\tests\subm\p>
C:\Users\vonc\prog\git\tests\subm\p>git checkout branch
M s
Switched to branch 'branch'
C:\Users\vonc\prog\git\tests\subm\p>git st
On branch branch
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: s (new commits)
no changes added to commit (use "git add" and/or "git commit -a")
C:\Users\vonc\prog\git\tests\subm\p>git show s
commit 271a4fb6bf79e2524f98dfbd505b2876b0c173a8
Author: VonC <vonc@laposte.net>
Date: Sat Jul 9 06:52:57 2016 +0200
update s to latest master
diff --git a/s b/s
index d11bd81..81e4800 160000
--- a/s
+++ b/s
@@ -1 +1 @@
-Subproject commit d11bd8132971a18e3e7cd19984cc6ce106478087
+Subproject commit 81e48007afc90aceca16d884d0fdc34074121732
Again, a git submodule update
would reset the content of the submodule s
to the SHA1 recorded in branch branch
of the parent repo.