'Git push automatically update all submodules

I searched and searched for an automatically way of updating(synchronizing) all submodules when pushing.

I have the main project, e.g: test

Another project, e.g: test1

Inside test I have 'added' submodule called test1 -> which links to outside project test1. OK, all good.

So I will clone my main project TEST, it will come with test1 submodule empty. I will run git submodule init and git submodule update --remote --recursive to bring me the latest from test1.

All good! Now I have the latest revision(of files / and files ) of submodule test1 on my local copy.

Now, I'm modifying something in test1 locally and I want to push it back. When I hit: Git branch -a on test1 submodule, I have something like this:

$ git branch -a
* (HEAD detached from f417982)
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

OK, I will checkout to master and merge between master and revision number to include my 'modifications' in test1 master branch.

So I MERGED and now it asks me for push. OK, I will PUSH. The files are updated(pushed) ONLY in test1 project, I want them to be automatically updated also in test/test1 submodule...

Am I doing something wrong? Thank you.

git


Solution 1:[1]

I'm not sure how familiar you are with git submodules, so I will explain general behavior first, since it might be helpful for other readers as well.

You have two separate repositories, test and test1.
test1 is added as submodule to test.

This leads to the following situation:

  • test knows about test1
  • test1 does not know about test
  • You and other developers can commit to test1 without having test checked out.
  • test1 has its own git history and commits, running git status in the test repo folder will show different reuslts, than in the test1 subfolder.
  • You can not commit to two repos at once and share a commit.

So in order to update something the submodule test1 and use it in the main repo test you have to do the following steps:

  1. Make you adjustments in the submodule an commit.
    Make sure you are in the submodule's folder.
  2. Run git status in you main repo.
    It should say modified: test1 (new commits)
  3. Commit and push this modification in your main repo test.

Further explanation:

  • Your commit in step 1 only adjusts the history of your test1 repo.
  • Since it is a submodule of test, the main repo will show a local modification, because it checks that something changed.
  • The main repo test only has a pointer to a certain commit of the submodule test1.
  • The local pointer is update whenever you change the HEAD of you submodule.
  • The make sure other developer update their pointer (and change their submodule's HEAD) you have to push the updated pointer, as described in step 3.

Hope this helps.


Update: If you have submodule test1 checked out twice, e.g. in (a) test/test1 and (b) test1-alone and make modifications to (b), the steps are a bit different:

  1. Fetch or pull test/test1 to get the changes pushed in test1-alone.
  2. Make sure HEAD of test/test1 points to the desired commit.
  3. Run git status in you main repo.
    It should say modified: test1 (new commits)
  4. Commit and push this modification in your main repo test.

The last two steps are the same as above.
In general:

  1. Adjust HEAD of your submodule (make sure it points to a pushed commit).
  2. Commit updated pointer in you main repo.

Update 2: If you have submodule test1 checked out twice, e.g. in (a) test/test1 and (b) test1-alone and make modifications to (a), the steps are a bit different:

  1. Commit and push your changes in test/test1.
  2. fetch or pull remote changes in test1-alone

This has nothing to do with the submodule behavior. It's exactly the same behavior, as if you would check out test1 in two different locations, like folderA/test1 and folderB/test1

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1