Reputation: 6791
I am trying to write a script that checks out 'master' in all submodules.
Normally, after a clone, all submodules are in a detached state. I want them to be on a branch however. So my script visits each submodule and under certain conditions checks out a branch.
Roughly speaking, that comes down to say
git submodule foreach --recursive 'git checkout master'
After such a checkout I also try to fast-forward them. The submodule's HEAD (master) might no longer be equal to the recorded sha1 in the parent project. If that is the case, the script also does
git add path/to/submodule
git commit -m 'Automatic update of submodule'
in the parent (immediately following the 'git checkout master; git merge --ff-only' in the submodule).
That is... that would also commit anything that was added to the index already and I don't want that: I ONLY want to commit this 'add' of path/to/submodule.
I tried to solve this by wrapping the above in a git stash push/pop:
git stash save Automatic stash of parent project by update_submodules.sh
git add "$path"
git commit -m "Updating submodule reference to current HEAD of branch $submodule_branch of $name"
git stash pop
However, the git stash
puts all submodules in a detached state again! And the git stash pop
does NOT restore that :/
How can I achieve what I want?
EDIT
The answer of torek was used in the final update_submodules.sh
script
at line 47.
It should be called like this.
Upvotes: 1
Views: 201
Reputation: 488183
Use the otherwise rather specialized git commit --only
.
What git commit --only
does is:
HEAD
commit into that temporary index, so that HEAD
and this temporary index match;git add
the specified arguments to the temporary index;git add
-ed by the time git commit --only
finishes.So, the new commit—which is now HEAD
; the commit that was HEAD
is now HEAD~1
or HEAD^
(whichever syntax you prefer: both mean the same thing)—is exactly the same as the old one except for the files listed after --only
. If some stuff was staged, that same stuff is still staged. Meanwhile the (main) index is also now updated to account for the fact that the HEAD
commit has new versions of the specified files.
(In this case the "files" are just the gitlinks, or the one gitlink for the one submodule.)
1It actually creates two temporary index files. For the complete and gory details, see my answer to Calling git in pre-commit hook.
Upvotes: 2