How to only update specific git submodules?
Asked Answered
I

6

120

So, updating all my submodules is done by running

git submodule foreach 'git pull origin master'

How do I update a specific submodule, located in say bundle/syntastic, without updating any other submodules?

Incorrupt answered 24/5, 2013 at 6:27 Comment(3)
With Git .213 (Q2 2017), you will be able to consider git clone --recurse-submodules="bundle/syntastic". See my answer below.Olmstead
@Olmstead : this checkout the submodule version linked, it doesnot upated it to HEAD of master as git submodule foreach 'git pull origin master' does.Skip
@Skip Good point: there was a config setting missing in [my (now edited) answer](https://mcmap.net/q/13593/-how-to-only-update-specific-git-submodules.Olmstead
A
101

I end up there by searching how to update specific submodule only, which means for me, updating a submodule to the ref pointed by its super-repo. Which is not the question nor the answer but only the title.

So in a hope of helping some others like me the answer to the question title is :

git submodule update <specific path to submodule>

which will put this submodule in the state of the ref commited in the super-repo.

Aerology answered 27/3, 2015 at 10:2 Comment(2)
This was the answer I was looking for, but (as mentioned) this is not an answer to the OP. Maybe someone with more power than me could transform this into an answer to the right question (and possibly change the title of this question to prevent confusion).Praxiteles
For anyone who it may help: this accepts multiple paths, if you want to update multiple submodules in one go. --depth 1 is nice too if you don't need the full history of that submodule, it gets only the needed commit.Principle
S
60

From the git submodule documentation

--remote This option is only valid for the update command. Instead of using the superproject’s recorded SHA-1 to update the submodule, use the status of the submodule’s remote-tracking branch. The remote used is branch’s remote (branch..remote), defaulting to origin.

In order to update a specific submodule you can use :

git submodule update --remote <path to the submodule>

In your case, it should be :

git submodule update --remote bundle/syntastic
Skip answered 1/9, 2016 at 19:9 Comment(2)
The order matters BTW. Ie, this will NOT work: git submodule update <path to the submodule> --remotePaulson
It also seems to matter from where you run it. Eg, if you're dealing with a repo that has nested submodules, you need to execute this from the directory that uses the submodule you're trying to target, not within or outside of it regardless of absolute pathing.Paulson
C
42

Actually the proper syntax is:

$ git clone <remote.git>
$ cd <remote>
$ git submodule update --init -- <specific relative path to submodule>
Coronado answered 17/7, 2015 at 8:30 Comment(0)
T
26

If you've just cloned a repo with submodules, you can clone a specific submodule with:

git submodule update --init submoduleName

This will clone the version of that submodule from the repo reference, from there you can cd into the submodule and pull whatever branches you need.

Trembles answered 11/9, 2015 at 17:25 Comment(1)
This command clone the version of the submodule referenced by the repo, it doesnot update the submodule with its HEAD of master.Skip
O
4

How do I update a specific submodule, located in say bundle/syntastic, without updating any other submodules?

With Git 2.13 (and the help of submodule.<name>.update config setting):

git clone --recurse-submodules="bundle/syntastic"
git config submodule.syntastic.update "git pull origin master"

The second line (to be executed only once) is needed because the clone --recurse-submodules[=<pathspec] command is equivalent to running git submodule update --init --recursive <pathspec> immediately after the clone is finished.
And that would only checkout the submodule at its gitlink recorded SHA1, not at the latest remote origin/master SHA1.
By adding the submodule.<name>.update config setting, you ensure that the selective clone of the submodule will be followed by an update, only for that submodule.


As part of the Git 2.13 (Q2 2017) "active submodule" feature (see "Ignore new commits for git submodule"), you have this commit bb62e0a from Brandon Williams (bmwill):

clone: teach --recurse-submodules to optionally take a pathspec

Teach clone --recurse-submodules to optionally take a pathspec argument which describes which submodules should be recursively initialized and cloned.
If no pathspec is provided, --recurse-submodules will recursively initialize and clone all submodules by using a default pathspec of ".".
In order to construct more complex pathspecs, --recurse-submodules can be given multiple times.

This also configures the 'submodule.active' configuration option to be the given pathspec, such that any future invocation of git submodule update will keep up with the pathspec.

Additionally the switch '--recurse' is removed from the Documentation as well as marked hidden in the options array, to streamline the options for submodules. A simple '--recurse' doesn't convey what is being recursed, e.g. it could mean directories or trees (c.f. ls-tree).
In a lot of other commands we already have '--recurse-submodules' to mean recursing into submodules, so advertise this spelling here as the genuine option.

So the git clone --recursive man page now reads:

--recurse-submodules[=<pathspec]:

After the clone is created, initialize and clone submodules within based on the provided pathspec.

If no pathspec is provided, all submodules are initialized and cloned.

Submodules are initialized and cloned using their default settings.
The resulting clone has submodule.active set to the provided pathspec, or "." (meaning all submodules) if no pathspec is provided.
This is equivalent to running git submodule update --init --recursive immediately after the clone is finished. This option is ignored if the cloned repository does not have a worktree/checkout (i.e. if any of --no-checkout/-n, --bare, or --mirror is given)

Example from the t/t7400-submodule-basic.sh test:

git clone --recurse-submodules="." \
          --recurse-submodules=":(exclude)sub0" \
          --recurse-submodules=":(exclude)sub2" \
          multisuper multisuper_clone

That would clone and update every submodules, except sub0 and sub2.


Bonus, with Git 2.22 (Q2 2019) "git clone --recurs" works better.

See commit 5c38742 (29 Apr 2019) by Nguyễn Thái Ngọc Duy (pclouds).
(Merged by Junio C Hamano -- gitster -- in commit 2cfab60, 19 May 2019)

parse-options: don't emit "ambiguous option" for aliases

Change the option parsing machinery so that e.g. "clone --recurs ..." doesn't error out because "clone" understands both "--recursive" and "--recurse-submodules" to mean the same thing.

Initially "clone" just understood --recursive until the --recurses-submodules alias was added in ccdd3da ("clone: Add the --recurse-submodules option as alias for --recursive", 2010-11-04, Git v1.7.4-rc0).
Since bb62e0a ("clone: teach --recurse-submodules to optionally take a pathspec", 2017-03-17, Git v2.13.0-rc0) the longer form has been promoted to the default.

But due to the way the options parsing machinery works this resulted in the rather absurd situation of:

$ git clone --recurs [...]
error: ambiguous option: recurs (could be --recursive or --recurse-submodules)

Add OPT_ALIAS() to express this link between two or more options and use it in git-clone.

Olmstead answered 16/4, 2017 at 19:37 Comment(1)
this checkout the submodule version linked, it doesnot upated it to HEAD of master as git submodule foreach 'git pull origin master' does.Skip
S
0

The solution that worked best for me is as follows:

git submodule --recursive --remote <path-to-submodule-directory>

I found this solution upon reading this very useful article

Suffragette answered 27/3, 2023 at 21:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.