Git sub-module tutorial
- 1 Intro
- 2 Create an "official" OMP application repository
- 3 Create pkp library repository
- 4 Add the pkp-lib as a sub-module to the omp project
- 5 Clone (fork) "official" projects
- 6 Create local development repositories
- 7 Start to develop locally
- 8 Another developer joins the team
- 9 Interact with other developers
At PKP we make use of git sub-modules to integrate our cross-application PKP library into applications like OMP. If you follow the steps in this tutorial you'll have some of the most important situations covered that occur when developing PKP applications with git. This is, however, not a beginners' tutorial for git. You should already know how to pull and push from/to rempote repositories. You should also have a good idea of branching and committing changes.
To start, please create a directory somewhere that you can use to generate your test repositories in. You'll need various repositories so make sure that your working directory is initially empty.
We use the following repositories:
- As many of our community developers still do not use git we will maintain the option to check-out PKP stable maintenance branches from CVS. Changes to the stable branches will be committed to our CVS repository and from there they'll be pushed to the "official" git repositories on an hourly basis. We maintain one "official" git repository per PKP application and one for the PKP library.
- Every PKP developer maintains one personal public fork of each of these repositories on github.com
- Every PKP developer maintains local repository clones on his own computer for development
Developers use the master branch to track changes to the "official" repositories that come in through CVS. They use "topic branches" for their own development and for communication with each other. Developers will never publish changes to their master branches.
In our example we create all repositories locally so that you can expect them. We assume that you want to work with the OMP application. That is why we call our main repository "omp". The repository for the PKP library which we will integrate as a sub-module into OMP is called "pkp". The "topic branch" will be named "modal" as an example. You'll call your own topic branches depending on the contents of the change-set you wish to implement.
In our example Mary and Juan are two developers that want to exchange code via their repositories. Please exchange the names for your own!
Create an "official" OMP application repository
First we will create a repository that represents our "official" application repository and we insert some initial test content:
mkdir omp cd omp git init echo "official omp project a-content" >omp-a.txt echo "official omp project b-content" >omp-b.txt git add . git commit -m "commit initial official omp project content" . cd ..
Create pkp library repository
In this step we'll create a second repository that represents the official version of the PKP library.
mkdir pkp-lib cd pkp-lib git init echo "official pkp-lib project a-content" >pkp-lib-a.txt echo "official pkp-lib project b-content" >pkp-lib-b.txt git add . git commit -m "commit initial official pkp-lib project content" . cd ..
Add the pkp-lib as a sub-module to the omp project
Please make sure that in the code below you change "/absolute/path/to" to your absolute working directory path.
cd omp git submodule add "/absolute/path/to/omp" pkp-lib git commit -a -m "added pkp-lib as sub-module to omp application" cd ..
Now you have two "official" repositories that represent the repositories PKP maintains at gitub.com to track CVS modules. Next we'll switch to the perspective of Juan who wants to develop code in OMP and the PKP library.
Clone (fork) "official" projects
Juan bare clones both official projects. These repositories represent Juan's personal public remote repositories that he'll usually maintain on github to share his code with other PKP developers.
git clone --bare omp juan.public.omp.git git clone --bare pkp-lib juan.public.pkp-lib.git
Create local development repositories
Juan now creates a local copy of his public omp repository to develop in. He points his sub-module to his public pkp-lib repository so that his changes don't get pushed to the official pkp-lib repository.
git clone juan.public.omp.git/ juan cd juan git submodule init
The submodule init command will create a .git folder within the pkp-lib folder. But it will not yet pull contents from the remote repository. Before Juan can do this he has to point his sub-module to his own fork of the official PKP library.
Juan now edits .git/config and changes the submodule url to
Then he'll download the contents of his public repository to his local repository and great his topical development branches. We use "modal" as a development branch. You may use any other expression that indicates what you're currently developing.
git submodule update git branch modal git checkout modal cd pkp-lib git checkout master git branch modal git checkout modal cd .. git commit -a -m "commit switch to new topical development branch in sub-module" cd ..
Start to develop locally
Juan starts to develop in his local repository, then he publishes his changes
cd juan echo "line inserted in omp project by juan" >>omp-a.txt git commit -a -m "juan edited file in omp project" cd pkp-lib echo "line inserted in pkp-lib by juan" >>pkp-lib-a.txt git commit -a -m "juan edited file in pkp-lib" git push origin modal # always commit sub-module first! See pitfalls below. cd .. git push origin modal cd ..
You can check that the change in the sub-module has been published to Juan's remote repository and not to the official one although .gitmodules still points to the official repository.
Another developer joins the team
Now Mary joins the development team, repeats the setup steps and makes changes to other files (otherwise we get trivial merge conflicts which have nothing to do with our sub-module tutorial).
git clone --bare omp mary.public.omp.git git clone --bare pkp-lib mary.public.pkp-lib.git git clone mary.public.omp.git/ mary cd mary git submodule init
Mary now edits .git/config and changes the submodule url to
Then she pulls the library and makes her own changes:
git submodule update git branch modal git checkout modal cd pkp-lib git checkout master git branch modal git checkout modal cd .. git commit -a -m "commit switch to new topical development branch in sub-module" cd .. cd mary echo "line inserted in omp project by mary" >>omp-b.txt git commit -a -m "mary edited file in omp project" cd pkp-lib echo "line inserted in pkp-lib by mary" >>pkp-lib-b.txt git commit -a -m "mary edited file in pkp-lib" git push origin modal cd .. git push origin modal cd ..
So far so good - now comes the interesting part: Juan and Mary start to share change-sets between themselves.
Interact with other developers
Mary pulls changes published by Juan
cd mary git pull ../juan.public.omp.git modal cd pkp-lib git pull ../../juan.public.pkp-lib.git modal cd .. git commit -a -m "need to commit the changed sub-module ref" cd ..
Mary publishes the changes received from Juan to her personal online repository
cd mary/pkp-lib git push origin modal cd .. git push origin modal cd ..
Mary makes another change to the file Juan changed and publishes her change
cd mary echo "line by mary in omp on top of juan's change" >>omp-a.txt git commit -a -m "mary's change in omp project" cd pkp-lib echo "line by mary in pkp-lib on top of juan's change" >>pkp-lib-a.txt git commit -a -m "mary's change in pkp-lib" git push origin modal cd .. git push origin modal cd ..
Juan pulls everything that Mary has changed (original change + change on top of Juan's change)
cd juan git pull ../mary.public.omp.git modal cd pkp-lib git pull ../../mary.public.pkp-lib.git modal cd .. git commit -a -m "need to commit the changed sub-module ref again" cd ..
Now Juan pushes all consolidated changes to his own repository.
cd juan/pkp-lib git push cd .. git push cd ..
That's it for a start with sub-modules. Hope you enjoyed our tutorial. You may now move on to []
See: Please see the articles "Pitfalls with Sub-modules" and "Git Submodule Tutorial" for for pitfalls to avoid when working with sub-modules. There are some situations in which you may loose local changes from sub-modules or make your remote repository unusable.