Back

Explore Courses Blog Tutorials Interview Questions
+4 votes
2 views
in DevOps and Agile by (19.4k points)
edited by

I have a project with a Git submodule. It is from ssh://... URL, and is on commit A. Commit B has been pushed to that URL, and I want the submodule to retrieve the commit and change to it.

Now, my understanding is that git submodule update should do this, but it doesn't. It doesn't do anything (no output, success exit code). Here's an example:

$ mkdir foo

$ cd foo

$ git init .

Initialized empty Git repository in /.../foo/.git/

$ git submodule add ssh://user@host/git/mod mod

Cloning into mod...

user@host's password: hunter2

remote: Counting objects: 131, done.

remote: Compressing objects: 100% (115/115), done.

remote: Total 131 (delta 54), reused 0 (delta 0)

Receiving objects: 100% (131/131), 16.16 KiB, done.

Resolving deltas: 100% (54/54), done.

$ git commit -m "Hello world."

[master (root-commit) 565b235] Hello world.

 2 files changed, 4 insertions(+), 0 deletions(-)

 create mode 100644 .gitmodules

 create mode 160000 mod

# At this point, ssh://user@host/git/mod changes; submodule needs to change too.

$ git submodule init

Submodule 'mod' (ssh://user@host/git/mod) registered for path 'mod'

$ git submodule update

$ git submodule sync

Synchronizing submodule url for 'mod'

$ git submodule update

$ man git-submodule 

$ git submodule update --rebase

$ git submodule update

$ echo $?

0

$ git status

# On branch master

nothing to commit (working directory clean)

$ git submodule update mod

$ ...

I've also tried git fetch mod, which appears to do a fetch (but can't possibly, because it's not prompting for a password!), but git log and git show deny the existence of new commits. Thus far I've just been rm-ing the module and re-adding it, but this is both wrong in principle and tedious in practice.

2 Answers

+5 votes
by (27.5k points)

Run this from your project parent directory:

$ git submodule update --init

If you have recursive submodules run:

$ git submodule update --init --recursive

But when you have local changes in the local submodule directory sometimes this still doesn't work while the submodule is being updated.

Again, most of the time the local change might not be the one you want to commit. It can happen due to a file deletion in your submodule, etc. If that's the case, do a reset in your local submodule directory and in your project parent directory, run again:

$ git submodule update --init --recursive

+6 votes
by (62.9k points)

The git submodule update command actually tells git that you simply want your submodules to each check out the commit already mentioned in the index of the superproject.

If you want to update your submodules to the most recent commit available from their remote, you'll try this directly within the submodules.

So in summary:

# Get the submodule initially

git submodule add ssh://bla submodule_dir

git submodule init

# Time passes, submodule upstream is updated

# and you now want to update

# Change to the submodule directory

cd submodule_dir

# Checkout desired branch

git checkout master

# Update

git pull

# Get back to your project root

cd...

# now the submodules are in the state you wanted, so

git commit -am "Pulled down update to submodule_dir"

Or, if you're a busy person:

git submodule foreach git pull origin master

Related questions

Browse Categories

...