'git submodule foreach checkout supermodule branch
Consider a git repository Foo/, which has submodules bar1/ and bar2/.
Each of these has the same branches: 1 & 2.
I enter the supermodule, and I want to update the supermodule to contain the most recent commits from bar1 and bar2's origin. I've already init'd and updated the supermodule, so there's working trees in bar1 and bar2, but they are in a detached state. I can do the following:
cd foo;
git checkout 1
git submodule foreach git checkout 1
git pull
Now, what bugs me is repeating the branch identifier. Can I do something like "git submodule foreach git checkout $CURRENT_BRANCH_ID"? Is there a better alternative?
Solution 1:[1]
A submodule is always by default in detached HEAD mode.
You can make each submodule follow a branch.
See "How to make an existing submodule track a branch".
cd /path/to/your/parent/repo/Foo
git config -f .gitmodules submodule.bar1.branch branch1
git config -f .gitmodules submodule.bar2.branch branch2
Then all you need to do is:
git submodule update --remote
That will update each submodule to the latest of their respective upstream branch (fetch + checkout).
Solution 2:[2]
The code
Here is the script that I mentioned in my comment:
function checkout_branch_not_refs() {
for line in $(git config --list | awk -F'[.=]' '/submodule.*branch/ {print $2","$4}'); do
IFS=',' read -r submodule branch <<< "$line"
if ! [ -d "$submodule" ]; then
echo "Cannot switch branch to '$branch' for submodule '$submodule'"
continue
fi
pushd "$submodule" && git switch "$branch" && popd
done
}
to be used like
checkout_branch_not_refs
git submodule foreach git pull
Explanation of differences
Original answer
git submodule update --remote
does exactly what you ask of it. It updates the submodule by looking at the remote. The remote is configured in .gitmodules
. The update --remote
command looks for the submodule.<submodule_name>.branch
key & checks out that commit directly.
ASCII art:
HEAD ------------\
\
V
remote branch --> Commit
My answer
checkout_branch_not_refs
This command will checkout the branch itself. HEAD
-> Branch
-> commit
.
ASCII art:
HEAD --> local branch --> Commit
It is a prerequisite to this answer to understand the difference between a local branch and a remote branch. That's the answer to why we have to run git pull
in the submodule after.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Community |
Solution 2 | Ari Sweedler |