428

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.

1

7 Answers 7

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

5
  • 1
    How about recursive add submodule? "git submodule add FrameworkA.git" just pull files of FrameworkA.
    – complez
    Commented Apr 16, 2012 at 4:48
  • 2
    You can just do a "git submodule add blah" and then "git submodule update --init --recursive".
    – drewag
    Commented Apr 16, 2012 at 13:37
  • Is this different than my way below? Commented Sep 26, 2013 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
    Commented Feb 24, 2015 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
    Commented Feb 24, 2015 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
3
  • 6
    I worked with changing the last line to: git submodule foreach git pull --ff-only origin master Commented Oct 23, 2014 at 7: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. Commented Oct 2, 2015 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 linkstackoverflow.com/questions/19728933/…. Commented May 23, 2017 at 2:10
27

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'
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? Commented Mar 19, 2014 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
    Commented May 3, 2017 at 13:01
  • Also, I guess you need to figure out this comment stackoverflow.com/a/18008139/3383543 Commented Jul 4, 2017 at 19:32
  • not having the recursive option means this only works if your submodules don't include submodules again.
    – erikbstack
    Commented Nov 12, 2017 at 8:20
  • This answer needs a warning for newbies: reset --hard and clean -dfx.
    – PLG
    Commented Dec 29, 2022 at 21:53
27

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'
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 well
    – iomv
    Commented Feb 18, 2020 at 11:32
14

How about

git config --global submodule.recurse true

and forget it?

See the git book documentation.

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.

0

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

1
  • 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
    Commented Mar 25, 2022 at 14:33

Not the answer you're looking for? Browse other questions tagged or ask your own question.