How does git submodule add -b
work?
After adding a submodule with a specific branch, a new cloned repository (after git submodule update --init
(Git 2.22, Q2 2019, has introduced git submodule set-branch --branch aBranch --
Note that if you have an existing submodule which isn't tracking a branch yet, then (if you have git 1.8.2+):
Make sure the parent repo knows that its submodule now tracks a branch:
cd /path/to/your/parent/repo
git config -f .gitmodules submodule..branch
Make sure your submodule is actually at the latest of that branch:
cd path/to/your/submodule
git checkout -b branch --track origin/branch
# if the master branch already exist:
git branch -u origin/master master
(with 'origin' being the name of the upstream remote repo the submodule has been cloned from.
A git remote -v
inside that submodule will display it. Usually, it is 'origin')
Don't forget to record the new state of your submodule in your parent repo:
cd /path/to/your/parent/repo
git add path/to/your/submodule
git commit -m "Make submodule tracking a branch"
Subsequent update for that submodule will have to use the --remote
option:
# update your submodule
# --remote will also fetch and ensure that
# the latest commit from the branch is used
git submodule update --remote
# to avoid fetching use
git submodule update --remote --no-fetch
Note that with Git 2.10+ (Q3 2016), you can use '.
' as a branch name:
The name of the branch is recorded as
submodule.
in.branch .gitmodules
forupdate --remote
.
A special value of.
is used to indicate that the name of the branch in the submodule should be the same name as the current branch in the current repository.
But, as commented by LubosD
With
git checkout
, if the branch name to follow is ".
", it will kill your uncommitted work!
Use git switch instead.
That means Git 2.23 (August 2019) or more.
See "Confused by git checkout"
If you want to update all your submodules following a branch:
git submodule update --recursive --remote
Note that the result, for each updated submodule, will almost always be a detached HEAD, as Dan Cameron note in his answer.
(Clintm notes in the comments that, if you run git submodule update --remote
and the resulting sha1 is the same as the branch the submodule is currently on, it won't do anything and leave the submodule still "on that branch" and not in detached head state.)
To ensure the branch is actually checked out (and that won't modify the SHA1 of the special entry representing the submodule for the parent repo), he suggests:
git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; git switch $branch'
Each submodule will still reference the same SHA1, but if you do make new commits, you will be able to push them because they will be referenced by the branch you want the submodule to track.
After that push within a submodule, don't forget to go back to the parent repo, add, commit and push the new SHA1 for those modified submodules.
Note the use of $toplevel
, recommended in the comments by Alexander Pogrebnyak.
$toplevel
was introduced in git1.7.2 in May 2010: commit f030c96.
it contains the absolute path of the top level directory (where
.gitmodules
is).
dtmland adds in the comments:
The foreach script will fail to checkout submodules that are not following a branch.
However, this command gives you both:
git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; [ "$branch" = "" ] && git checkout master || git switch $branch' –
The same command but easier to read:
git submodule foreach -q --recursive \
'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; \
[ "$branch" = "" ] && \
git checkout master || git switch $branch' –
umläute refines dtmland's command with a simplified version in the comments:
git submodule foreach -q --recursive 'git switch $(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'
multiple lines:
git submodule foreach -q --recursive \
'git switch \
$(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'
Before Git 2.26 (Q1 2020), a fetch that is told to recursively fetch updates in submodules inevitably produces reams of output, and it becomes hard to spot error messages.
The command has been taught to enumerate submodules that had errors at the end of the operation.
See commit 0222540 (16 Jan 2020) by Emily Shaffer (nasamuffin).
(Merged by Junio C Hamano -- gitster -- in commit b5c71cc, 05 Feb 2020)
fetch: emphasize failure during submodule fetch
Signed-off-by: Emily Shaffer
In cases when a submodule fetch fails when there are many submodules, the error from the lone failing submodule fetch is buried under activity on the other submodules if more than one fetch fell back on
fetch-by-oid
.
Call out a failure late so the user is aware that something went wrong, and where.
Because
fetch_finish()
is only called synchronously byrun_processes_parallel,
mutexing is not required aroundsubmodules_with_errors
.
Note that, with Git 2.28 (Q3 2020), Rewrite of parts of the scripted "git submodule" Porcelain command continues; this time it is "git submodule set-branch" subcommand's turn.
See commit 2964d6e (02 Jun 2020) by Shourya Shukla (periperidip).
(Merged by Junio C Hamano -- gitster -- in commit 1046282, 25 Jun 2020)
submodule: port subcommand 'set-branch' from shell to C
Mentored-by: Christian Couder
Mentored-by: Kaartic Sivaraam
Helped-by: Denton Liu
Helped-by: Eric Sunshine
Helped-by: Đoàn Trần Công Danh
Signed-off-by: Shourya Shukla
Convert submodule subcommand 'set-branch' to a builtin and call it via
git submodule.sh
.