Git submodule workflow – commit/push/pull

Table of Content

If you haven’t done already, have a thorough read through There are quite a few caveats, and I will refer back to this page. If you try to work with submodules without reading this, you will give yourself a headache very quickly.

My approach follows this tutorial, with a few added extras:

Once you have your superproject initialised (e.g. git init && git remote add origin ...), start adding your submodules like so:

git submodule add git:// extension
git submodule init
git submodule update

Check that your .gitmodules file reflects this addition, e.g.

[submodule "extension1"]
        path = extension
        url = git://

Switch to your submodule directory (i.e. cd extension). Run:

git fetch #I use fetch here - maybe you can use pull?
git checkout -b somebranchname #See the Git-Tools-Submodules link above for an explanation of why you need to branch

I made a change here to README.txt so I could commit it (also so I would have a record of what I was doing in this commit), then commited the module to apply the branch (still within the submodule directory):

git add .
git commit -a -m "Branching for extension submodule"

Now go into the superproject (i.e. cd ..). You will also need to commit here (if you look at the git submodule page I mentioned it explains why this is necessary):

git status #will show you that your submodule has been modified
git commit -a -m "Commiting submodule changes from superproject"

Now we can recusively push our projects like so if required:

git push --recurse-submodules=on-demand

You will need to run through the above steps once for all your submodules.

Once you have done this for all your submodules and started making changes you want to commit and push, you can use:

git submodule foreach 'git add .' #recursively add files in submodules

Unfortunaly I haven’t found a way to recursively commit without using something like git-slave(anyone?), so you then need to go into each submodule directory and run a regular commit for the files you just added. In the superproject:

git status #tells you that `extension` submodule has been modified
cd extension
git commit -a -m "Commiting extension changes in superproject edit session"

Once the submodule is commiting, you’ll also need to commit the superproject (again), so:

cd ..
git add .
git commit -a -m "Altered extension submodule"
git status #should now show 'working directory clean', otherwise commit other submodules in the same manner

This can get slightly annoying (because you end up committing twice), but once you’re aware of it it’s actually not so bad (as it forces you to check what you’re committing in each project). Just my opinion – if you’ve isolated some of your superproject’s functionality into submodules, it should work in isolation from the rest of your projects anyway (so commiting them at different times while annoying is not the end of the world).

Now we can push once more…

git push --recurse-submodules=on-demand

If you then descend into your submodule and try and push again, you’ll find it won’t do anything as the latest commit has already been pushed.

Cloning (or using a remote origin) for a superproject can also be quite confusing – such as the need to run git submodule update twice after git submodule init. Read the ‘Cloning a Project with Submodules’ section of

Something that caught me out when cloning my superproject was getting the latest changes for the submodules. See Git – easy way pull latest of all submodules

My variant of this is to use a ‘development’ branch for checked out submodules (but you can call it whatever you want) and then use this in the superproject:

git submodule foreach git pull origin development

When I set this up I also swap to the branch I want to push my changes to on the checked out submodule like so:

cd extension
git checkout -b development #This will tell you this is a new branch, but I believe this means a new branch of the local git repository - this will get pushed to the 'development' branch
#Make your changes, commit etc.

I can confirm that when I follow the above steps, changes to the submodules in a clone/remote origin project (when pushed) showed up in other clones/remote origins of the same project (not forgetting that last submodule pull command).

I hope that was of some use to you.

Нижче наведені специфічні моменти які можуть стати у нагоді.

Додаємо наш модуль у Composer Autoload (link)

    "autoload": {
        "psr-0": {
            "YourNamespace\\YourSubmodule\\": "lib/your-private-git-repo/src"

Далі оновлюємо Composer

php composer.phar update
Таким чином Composer файли додані в конфіг також будуть додані в autoload.

Все готово: зараз ваший submodule автоматично буде доданий у autoload Composer’a.

See more:


Leave a Reply

Your email address will not be published. Required fields are marked *