Git update submodules recursively
Asked Answered
O

7

423

My project struture

ProjectA
-FrameworkA (submodule)
--Twig (submodule of FrameworkA)

How I can update submodules recursively? I already tried some git commands (on ProjectA root)

git submodule foreach git pull origin master

or

git submodule foreach --recursive git pull origin master

but cannot pull files of Twig.

Overarch answered 16/4, 2012 at 3:38 Comment(1)
How about git-deep?Grimbly
P
911
git submodule update --recursive

You will also probably want to use the --init option which will make it initialize any uninitialized submodules:

git submodule update --init --recursive

Note: in some older versions of Git, if you use the --init option, already-initialized submodules may not be updated. In that case, you should also run the command without --init option.

Ponderable answered 16/4, 2012 at 4:24 Comment(5)
How about recursive add submodule? "git submodule add FrameworkA.git" just pull files of FrameworkA.Overarch
You can just do a "git submodule add blah" and then "git submodule update --init --recursive".Ponderable
Is this different than my way below?Greaves
@Irineau The note about already-initialized submodules not being updated if --init is used does not match my experiences on Git 2.2.2. I see both top-level and nested submodules that have already been initialized getting the correct commit checked out when I use git submodule update --init --recursive, and I think the claim that you need to run the command with and without --init is simply wrong. Unless somebody can either show evidence that this is the behaviour or demonstrate that it's changed between versions and was once true, I plan to edit it out altogether.Carpeting
@MarkAmery, I remember this being a problem in some version of git that I cannot remember. I just tested it in 1.9.3 and the problem does not seem to exist anymore. I updated the answer to refer to a vague "older versions". If anyone can specify which version changed this behavior, that would be great.Ponderable
G
57

The way I use is:

git submodule update --init --recursive
git submodule foreach --recursive git fetch
git submodule foreach git merge origin master
Greaves answered 26/9, 2013 at 13:28 Comment(3)
I worked with changing the last line to: git submodule foreach git pull --ff-only origin masterAkim
I also would add --recursive to the last line: "git submodule foreach --recursive git merge origin master" otherwise you can get a dirty submodule when it itself has updated a submodule.Orlantha
Been looking for this for the past three hours. Thank you sir. To add to this, you can also use these commands for committing, such as: git submodule foreach --recursive 'git commit -a | :'. The : makes it loop regardless of result. See link#19729433.Arterio
G
26

As it may happens that the default branch of your submodules are not master (which happens a lot in my case), this is how I automate the full Git submodules upgrades:

git submodule init
git submodule update
git submodule foreach 'git fetch origin; git checkout $(git rev-parse --abbrev-ref HEAD); git reset --hard origin/$(git rev-parse --abbrev-ref HEAD); git submodule update --recursive; git clean -dfx'
Gwyngwyneth answered 3/12, 2013 at 23:17 Comment(5)
I tryed to add this command in my generic Makefile yet I'm still stucked to make GNU Make ignore the interpretation of the $(...) sequence, despite it's presence within simple quotes. Anybody have an idea?Gwyngwyneth
Your command is what I needed thank you! But I get: Entering 'Core' fatal: ambiguous argument 'origin/HEAD': unknown revision or path not in the working tree. where Core is the submoduleShorthanded
Also, I guess you need to figure out this comment https://mcmap.net/q/12635/-how-can-i-reconcile-detached-head-with-master-originDaylong
not having the recursive option means this only works if your submodules don't include submodules again.Mokpo
This answer needs a warning for newbies: reset --hard and clean -dfx.Mcphee
M
25

In recent Git (I'm using v2.15.1), the following will merge upstream submodule changes into the submodules recursively:

git submodule update --recursive --remote --merge

You may add --init to initialize any uninitialized submodules and use --rebase if you want to rebase instead of merge.

You need to commit the changes afterwards:

git add . && git commit -m 'Update submodules to latest revisions'
Morry answered 22/1, 2018 at 13:56 Comment(1)
This, I thought I was doing something wrong but your answer confirmed to me that git submodule update --remote my-dir/my-submodule works just as wellAcred
T
12

How about

git config --global submodule.recurse true

and forget it?

See the git book documentation.

Teno answered 18/7, 2022 at 8:54 Comment(0)
M
3

You can add the following to your Makefile:

submodule:
    git submodule update --init --recursive
    git submodule foreach 'git fetch origin; git checkout $$(git rev-parse --abbrev-ref HEAD); git reset --hard origin/$$(git rev-parse --abbrev-ref HEAD); git submodule update --recursive; git clean -dfx'

Then you can simple run make submodule everytime you want to update submodules.

Mun answered 9/3, 2022 at 23:59 Comment(0)
R
0

I had one submodule causing issues (the 'fatal:...' that Sanandrea reported, above). Navigated to the submodule and used 'git clean -dfx' resolved it.

Roller answered 25/3, 2022 at 14:25 Comment(1)
If you're adding new information, could you complete your answer once you've fully solved the issue? "trying to use same" leaves me unsure whether this is an answer or just a comment.Edelstein

© 2022 - 2024 — McMap. All rights reserved.