409

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.

mrts
  • 16,697
  • 8
  • 89
  • 72
complez
  • 7,882
  • 11
  • 48
  • 56

7 Answers7

878
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.

drewag
  • 93,393
  • 28
  • 139
  • 128
  • 1
    How about recursive add submodule? "git submodule add FrameworkA.git" just pull files of FrameworkA. – complez Apr 16 '12 at 04:48
  • 2
    You can just do a "git submodule add blah" and then "git submodule update --init --recursive". – drewag Apr 16 '12 at 13:37
  • Is this different than my way below? – William Entriken Sep 26 '13 at 13:30
  • 4
    @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. – Mark Amery Feb 24 '15 at 14:06
  • 3
    @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. – drewag Feb 24 '15 at 16:53
56

The way I use is:

git submodule update --init --recursive
git submodule foreach --recursive git fetch
git submodule foreach git merge origin master
William Entriken
  • 37,208
  • 23
  • 149
  • 195
  • 6
    I worked with changing the last line to: `git submodule foreach git pull --ff-only origin master` – Gilad Peleg Oct 23 '14 at 07:43
  • 2
    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. – Michael Scott Asato Cuthbert Oct 02 '15 at 18:54
  • 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](https://stackoverflow.com/questions/19728933/continue-looping-over-submodules-with-the-git-submodule-foreach-command-after)https://stackoverflow.com/questions/19728933/continue-looping-over-submodules-with-the-git-submodule-foreach-command-after. – Fledgling Pidgeon May 23 '17 at 02:10
25

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'
Sebastien Varrette
  • 3,876
  • 1
  • 24
  • 21
  • I tryed to add this command in my [generic Makefile](https://github.com/Falkor/Makefiles/blob/devel/repo/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? – Sebastien Varrette Mar 19 '14 at 13:57
  • 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 submodule – Sanandrea May 03 '17 at 13:01
  • Also, I guess you need to figure out this comment https://stackoverflow.com/a/18008139/3383543 – Ahmad AlMughrabi Jul 04 '17 at 19:32
  • not having the recursive option means this only works if your submodules don't include submodules again. – erikbstack Nov 12 '17 at 08:20
  • This answer needs a warning for newbies: `reset --hard` and `clean -dfx`. – PLG Dec 29 '22 at 21:53
24

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'
mrts
  • 16,697
  • 8
  • 89
  • 72
  • 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 well – iomv Feb 18 '20 at 11:32
9

How about

git config --global submodule.recurse true

and forget it?

See the git book documentation.

Martin Thoma
  • 124,992
  • 159
  • 614
  • 958
Stefano Favero
  • 331
  • 3
  • 6
1

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.

Shubham Chaudhary
  • 47,722
  • 9
  • 78
  • 80
0

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

  • 2
    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. – joanis Mar 25 '22 at 14:33