368

I have, in my naivety, set up a git submodule and treated it like a Subversion external - i.e. it's now full of changes that I've just realized haven't been committed or pushed anywhere.

Is there some easy way to commit/push the submodule changes back to the upstream repo? And what's the recommended technique in Git for doing simultaneous development on separate (but linked) repositories in this way?

1

5 Answers 5

586

A submodule is its own repo/work-area, with its own .git directory.

So, first commit/push your submodule's changes:

$ cd path/to/submodule $ git add <stuff> $ git commit -m "comment" $ git push 

Then, update your main project to track the updated version of the submodule:

$ cd /main/project $ git add path/to/submodule $ git commit -m "updated my submodule" $ git push 
Sign up to request clarification or add additional context in comments.

15 Comments

except that git appears to have placed the submodule into an anonymous branch at times...$ git.exe b -a * (no branch)
@rogerdpack - you're correct. Submodules usually end up on "no branch". You'll often need to check out some branch before adding/committing to your submodule.
even though this is marked as duplicate, +1 because your answer is clearer than the other
It's also worth noting that you may need to git checkout master after creating submodules from file trees within the github super project if you see HEAD detached at ... when you type git status.
This fixed it for me git push origin HEAD:master
|
77

Note that if you have committed a bunch of changes in various submodules, you can (or will be soon able to) push everything in one go (ie one push from the parent repo), with:

git push --recurse-submodules=on-demand 

git1.7.11 ([ANNOUNCE] Git 1.7.11.rc1) mentions:

"git push --recurse-submodules" learned to optionally look into the histories of submodules bound to the superproject and push them out.

Probably done after this patch and the --on-demand option:

--recurse-submodules=<check|on-demand|no>:: 

Make sure all submodule commits used by the revisions to be pushed are available on a remote tracking branch.

  • If check is used, it will be checked that all submodule commits that changed in the revisions to be pushed are available on a remote.
    Otherwise the push will be aborted and exit with non-zero status.
  • If on-demand is used, all submodules that changed in the revisions to be pushed will be pushed.
    If on-demand was not able to push all necessary revisions it will also be aborted and exit with non-zero status.

This option only works for one level of nesting. Changes to the submodule inside of another submodule will not be pushed.

3 Comments

this didn't work for me: I had to do:
git submodule foreach git push -u origin master
@rivanov What version of Git are you using?
12
$ git submodule status --recursive 

Is also a life saver in this situation. You can use it and gitk --all to keep track of your sha1's and verify your sub-modules are pointing at what you think they are.

1 Comment

can commit sub-module with tortoiseGit after executing this command.
5

You can treat a submodule exactly like an ordinary repository. To propagate your changes upstream just commit and push as you would normally within that directory.

3 Comments

For me this was the best answer. If you treat it like any other git repo, you don't need to memorize any new commands! Just cd into the submodule's directory and: git add -A git commit -m "some message" git push Then cd to the main repo and do the same.
...except that my ordinary repositories don't have detached heads.
Seems like this isn't quite complete. If you cd submod; git commit -am'New stuff'; git push that pushes the new commit to the submod's origin, but it doesn't record the new SHA in the parent project. The official docs don't even mention how to do this. I suspect it's (in parent project): git add submod; git commit -m'Updated submod'; git push.
1

Before you can commit and push, you need to init a working repository tree for a submodule. I am using tortoise and do following things:

First check if there exist .git file (not a directory)

  • if there is such file it contains path to supermodule git directory
  • delete this file
  • do git init
  • do git add remote path the one used for submodule
  • follow instructions below

If there was .git file, there surly was .git directory which tracks local tree. You still need to a branch (you can create one) or switch to master (which sometimes does not work). Best to do is - git fetch - git pull. Do not omit fetch.

Now your commits and pulls will be synchronized with your origin/master

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.