Shared repositories in Git

Hi guys! Since I finally finished my series about scrolled lists, I was able to get to work on my master thesis project. There is a lot to come up with, some new ideas and architecture, so there is not much going on in the code, but the whole storm in my head (and on my whiteboard – I guess I could write a whole post about whiteboards!). I created a new Unity project for the temporal history engine and I felt the urge to copy paste some of the scripts.

This was the moment when I realized that I could extract the mini GUI library that I wrote for the previous project, since it will be useful in all my future Unity projects. At Tabasco we use SVN and we already have some parts of the code that are to be shared across all game projects. That is accomplished using shared repositories. We can use and modify both the shared and non-shared parts freely, but when it comes to committing, shared parts have to be committed from the shared project. During the update, one pull downloads all the latest data, so this is really convenient.

As I am a big Git fan, I started looking for a Git-specific alternative and I found…

Git submodules

The exact same thing is possible thanks to the git submodules functionality, which lets us clone the other repository into our project, keeping its own git structure.

Preparations

So let’s see how it works. Firstly, I created a new repository on Github, that will only contain the GUI scripts that are reusable across projects (I already had this separated in the directory “Core”). I moved the scripts, committed them and pushed.

Adding a submodule to the project

The next step involved embedding this fresh new repository into my old one. This is done using the git submodule add command:

As the first argument we specify the location of our embedded repo, the second one specifies the target location for the files. When left blank, directory named after the repo would be created in the current directory.

This operation created also a .gitmodules file, which takes care of the submodules mapping. I committed changes to have my working directory clean.

Modifying submodule files

To see how this whole setup would behave, I made small changes in scripts contained in the submodule and the main repo. We can see that git status command distinguishes them clearly:

Notice that it only points out the sole fact that there are some changes, it doesn’t even specify in which files.

When I invoke ‘git add –-all . ‘ I can see that only the main repo files get staged. So from this level it’s not possible to mess up with the submodule files, what could be dangerous sometimes – we do not want some accidental changes to be pulled by other repositories that use our little library.

To commit my changes to the submodule, I need to navigate to the exact folder this repo is located in (tip: holding shift when clicking right mouse button in the folder in the File Explorator unlocks an option “Open console window here”). Listing changes behaves exactly as in an ordinary repository:

If we create a commit there, in the main repo we can see that information about modification changes:

Pushing submodule changes

Time to show the world our outstanding changes. We have two options of pushing commits in the submodules:

• Simply use git push from the submodule subfolder. Then, at the time of pushing changes in the main repository, we can make sure there aren’t any un-pushed changes in any submodules by running git push –recurse-submodules=check. In case we forget about some, we get a clear warning:

And that takes us to the other method…

• Use git push –recurse-submodules=on-demand – this command will try to push all of the changes. Firstly, it will ask for credentials to all of the repositories and then the pushes are performed:

Updating files

Simple git pull won’t work here, since the changes were in fact made in another repository. We can use the command git submodule update –-remote to pull all of the changes:

Summary

This information is sufficient for me to start using the submodules functionality. The more thorough (and much, much longer) tutorial can be found here. I advise you to take a look there, because there are some tricky parts for example concerning merging concurrent changes in the submodule files.

As always – if you find this post helpful and would like to get notified when future ones appear, like my fan page or follow me on Twitter. (｡◕‿◕｡)