Update a submodule to the latest commit
Asked Answered
A

9

449

I have a project A which is a library and it is used in a project B.

Both projects A and B have a separate repository on github BUT inside B we have a submodule of A.

I edited some classes on the library, which is in the repo A, I pushed on the remote repo, so the library (repo A) is updated.

These updates do not reflect on the "reference" (the submodule) the submodule refers to a previous commit.... what should I do in order to update the submodule on git?

Ahouh answered 19/11, 2011 at 2:3 Comment(1)
First do: git submodule update --remote --merge to make sure the submodules point to the most recent hash (valid after git 1.8). Then commit the pointer to the new hash of your submodules by committing the submodules: git add proj/submodule then git commit -m 'adding new submodule' my favorite answer is this one: https://mcmap.net/q/80383/-update-a-submodule-to-the-latest-commitNeoplatonism
W
570

Enter the submodule directory:

cd projB/projA

Pull the repo from you project A (will not update the git status of your parent, project B):

git pull origin master

Go back to the root directory & check update:

cd ..
git status

If the submodule updated before, it will show something like below:

# Not currently on any branch.
# Changed but not updated:
#   (use "git add ..." to update what will be committed)
#   (use "git checkout -- ..." to discard changes in working directory)
#
#       modified:   projB/projA (new commits)
#

Then, commit the update:

git add projB/projA
git commit -m "projA submodule updated"

UPDATE

As @paul pointed out, since git 1.8, we can use

git submodule update --remote --merge

to update the submodule to the latest remote commit. It'll be convenient in most cases.

Win answered 19/11, 2011 at 2:26 Comment(14)
BTW, if you are not the owner of the submodule, you can just do git submodule update when someone else updated the projA(you'll get a new commit id).Win
i own the submodule main repo(proj A) but i am a committer in the proj B.Ahouh
@Win After the commit, how does one push it to the remote? Is it just git push ?Christyna
@Christyna right, and the full cmd is git push <remote> <branch>, e.g. git push origin dev.Win
git submodule update only works without flags when a commit has been pulled (in proj B) that updates the refs to the submodule(s) in question (proj A). To update proj B to reference the HEAD of the remote tracking branch for proj A, you'll want to do git submodule update --remote --merge as shown in Paul Hatcher's answer below.Tick
I am not sure if I am doing something wrong. I did git submodule update --remote --merge I went to github but they git sub repos are still pointing to the wrong commit. How to I have github also point to the right commit? Also, how do I check that the local ones are pointing to the right commit?Neoplatonism
you also have to do a git add . then a git commit -m 'msg updating submodules' I believe.Neoplatonism
@CharlieParker yeah, it's correct if only the submodule updated. But if there're some other files modified, they all will be added, which is not suit for the submodule updating commit msg. That's why I wrote git add projB/projA explicitly. ;)Win
@Win apologies for the second question. Is git submodule update --remote --merge suppose to do everything? like do I still need to cd to the submodules pull and commit? It seems that git submodule update --remote --merge does nothing for me. When I cd into the submodules it shows old commits.Neoplatonism
@CharlieParker Generally yes, git submodule update --remote --merge will update the submodule to the latest remote commit (no need to cd to the submodules to pull again). But I'm not quite sure about this option, I still prefer using the cd way to make sure the updating result is what I want (I'll check the log history). u can leave ur question below @paul's answer, I think he'll have a better experience on this option. ;)Win
Hi @Win ! Thanks for your kind help. I am having a strange issue where no matter what I do (either I cd to the dir and do the pull or do the git submodule update etc) I cannot update one of my submodules. To resolve this I thought of two things that would help me 1) how do I force the submodule to tell me the gitlink/hash it really is pointing to? I've tried cding then git status but that doesn't seem to help. 2) is there a way to force the submodule to pull from the most recent gitlink of the original repo? Thanks for your time and fun attitude :)Neoplatonism
I think my issues were resolved after reading #11358582 with git submodule update --init. To get the latest hashes git submodule status worked. That will give you the whole hash so just read the beginning when comparing the local submodudles with github submodule hashes. Thanks again!Neoplatonism
@CharlieParker I'm glad u've figured it out. :)Win
Update only one submodule: git submodule update --remote --merge <path-to-submodule>Respirator
E
201

Since git 1.8 you can do

git submodule update --remote --merge

This will update the submodule to the latest remote commit. You will then need to add and commit the change so the gitlink in the parent repository is updated:

First, git add it

git add project/submodule_proj_name

then git commit it

git commit -m 'gitlink to submodule_proj_name was updated'

the git push it

git push

And then push the changes as without this, the SHA-1 identity the pointing to the submodule won't be updated and so the change won't be visible to anyone else.

Elo answered 11/2, 2017 at 11:36 Comment(4)
Even though I do git commit everyone else is still not seeing it. On branch master Your branch is up-to-date with 'origin/master'. Changes not staged for commit: modified: SubmoduleA (new commits) modified: SubmoduleB (new commits)Endocarp
Have you done a "git push" after your commit, bear in mind commit just changes your local repository, you have to push it out to the remote for everyone else to see itElo
Missing from this answer (but noted in other answers below): the updated submodule(s) need to be staged with git add before committing.Borroff
@Borroff I feel that everyone who is at the point where they are working on submodules would understand that. This is the only post that helped me out, thanks very much.Neumeyer
H
50

If you update a submodule and commit to it, you need to go to the containing, or higher level repo and add the change there.

git status

will show something like:

modified:
   some/path/to/your/submodule

The fact that the submodule is out of sync can also be seen with

git submodule

the output will show:

+afafaffa232452362634243523 some/path/to/your/submodule

The plus indicates that the your submodule is pointing ahead of where the top repo expects it to point to.

simply add this change:

git add some/path/to/your/submodule

and commit it:

git commit -m "referenced newer version of my submodule"

When you push up your changes, make sure you push up the change in the submodule first and then push the reference change in the outer repo. This way people that update will always be able to successfully run

git submodule update

More info on submodules can be found here http://progit.org/book/ch6-6.html.

Haffner answered 19/11, 2011 at 2:19 Comment(1)
If you don't see a + when you run git submodule, make sure you've initialized and imported the submodules. The commands for that are git submodule init and git submodule update, respectively.Norvin
Z
23

Single line version

git submodule foreach "(git checkout master; git pull; cd ..; git add '$path'; git commit -m 'Submodule Sync')"
Zirconium answered 20/10, 2014 at 6:31 Comment(0)
B
8

Solution 1

To make it simple.

Ran this command to get the latest of the submodule:

git submodule update --remote --merge

or 

git submodule update --remote

now, we need to update the reference in our parent repo, that can be done using this command:

git add <<submodulesfoldername>>

note: <> == name of my sub module folder git add sub-modules (remember to commit and push with your code, the reference of the latest commit would have been added)

enter image description here

Solution 2

If the above solution doesn't pull the latest, Try This:

git submodule update --init --recursive
Bolster answered 11/7, 2022 at 8:50 Comment(0)
S
7

None of the above answers worked for me.

This was the solution, from the parent directory run:

git submodule update --init;
cd submodule-directory;
git pull;
cd ..;
git add submodule-directory;

now you can git commit and git push

Squish answered 23/11, 2020 at 11:15 Comment(1)
Your answer was close compared with the previous, except for this: added submodule sometimes is not point to a branch, you dont need to add the submodule on each modificationDap
B
4

A few of the other answers recommend merging/committing within the submodule's directory, which IMO can become a little messy.

Assuming the remote server is named origin and we want the master branch of the submodule(s), I tend to use:

git submodule foreach "git fetch && git reset --hard origin/master"

Note: This will perform a hard reset on each submodule -- if you don't want this, you can change --hard to --soft.

Blocker answered 25/4, 2019 at 21:30 Comment(0)
M
1

My project should use the 'latest' for the submodule. On Mac OSX 10.11, git version 2.7.1, I did not need to go 'into' my submodule folder in order to collect its commits. I merely did a regular

git pull --rebase 

at the top level, and it correctly updated my submodule.

Metronymic answered 19/6, 2016 at 1:2 Comment(0)
G
0

Andy's response worked for me by escaping $path:

git submodule foreach "(git checkout master; git pull; cd ..; git add \$path; git commit -m 'Submodule Sync')"
Gilus answered 4/7, 2018 at 15:11 Comment(1)
Likely the reason why @Andy Webov's answer didn't require escaping was because they used single quotes around path, eg. '$path'Jobye

© 2022 - 2024 — McMap. All rights reserved.