Working with Git submodules

Posted by Mikael Nordberg on October 11th, 2010
In our current project we’re using some shared libraries that we have developed as open source. These libraries are something that we upgrade on a regularly basis, so referencing the built assembly would add some pain when, for example, a bug is found in a library.
What we really want is to include the shared projects source code and be able to add all changes back to their own repositories. Git submodules lets us do just that.
This is the structure of our main_project
/
/lib
/lib/nhibernate
/lib/log4net
/lib/.....
/src
/src/main_project
/src/main_project_classlibrary
/src/.....

From main_project all assemblies are referenced from the /lib folder.

Our shared projects are configured to look for it’s references in ../lib which will be equal to /lib for the main_project.
To add a shared project to our main_project we do:
git submodule add git@github.com/frontwalker/NullReference.Data.git src/NullReference.Data
This will add the NullReference.Data project into /src/NullReference.Data folder. But what if NullReference.Data is updated with some breaking changes? Do we need to update and recompile our main_project? Only if we want the new features!
The submodule that is added to our main project is added with the exact version that the project was in at the given time when it was added as a submodule. So if NullReference.Data was added at version 1.23 it will stay at that version in main_project until we decide to update it even if NullReference.Data it self is updated from another project.

Cloning a tree with submodules

To clone the main_project you do it as you normally would with the “git clone” command. But when opening one of the folders for a submodule you will find out that they contain no files at all. Git doesn’t automatically fetch all your submodules when you clone a project, so you need to “init” and “update” for the submodules before you can use them.
git submodule init
git submodule update

You only need to do this once or if someone adds another submodule.
Alot of information about the command is found in the documentation and I also found this blog post from “mathie” very helpful.

You can check out our NullReference libraries on GitHub.

More on git – Permission denied

Posted by Jens Pettersson on August 23rd, 2010

In the last post I wrote about getting Permission denied while merging and today Daniel got the same error when pulling from our remote master. This was caused due to a locked file and the pull stopped after a couple of files which resulted in those files being left as “untracked files” on our master, which isn’t correct.

This was solved by doing a

§ git clean -f –d

This stands for “-force” and “remove untracked directories”.

After this you can do a new pull. If it stills fails, use

§ git reset HEAD --hard

and then use clean again if you have to.

//J

Git merge error – Permission denied

Posted by Jens Pettersson on August 20th, 2010

Today when I wanted to merge my branch (after the “pull –> rebase dance” I wrote about yesterday) I got the following error:

error: git checkout-index:
unable to create file src/ProjectName/ClassName.cs (Permission denied)

If I just retried the merge I got another error and if I looked in my local master I didn’t see my branch’s commit messages either. If I did a git status I saw some of my files from my branch, but not all of them as untracked files. I couldn’t go back to my other branch either due to the untracked files in my master.

The solution? Well, it turned out that a

§ git checkout my_branch -f

did the trick. The –f stands for “force” so it just discarded all my untracked changes in master and I was back on track. Now the merge worked again because the file probably wasn’t locked anymore.

Not sure why the file was locked and by what, but this workaround did enable me to merge and later push my changes correctly to github.

//J

That’s how we roll (git) in the Shire!

Posted by Jens Pettersson on August 19th, 2010

This post is about how we try to use git in our current project. At the moment we’re three coders involved and we’re pretty early in this project.

Yesterday I was working on my local branch with a couple of features while the others pushed some changes to our remote master wich I wanted to have in my branch. This is how I did it:

First, I made sure I had the latest version on my local master:

§ git pull

Then I did a rebase onto my feature branch:

§ git rebase master my_branch

The following message from git is pretty self explanatory on what’s happening:

First, rewinding head to replay your work on top of it…

Applying: My first commit message

Applying: My second commit message

Applying: Frodo was here!!1!

After that I merged my branch with my local master and then pushed it to github. Of course I didn’t have to push it, but it wouldn’t been nice to loose a days work if something had happened.

We could also have used remote branches for this, but it doesn’t feel necessary at this point.

Feel free to drop us a comment on how you use git in your projects! We aren’t claiming that this is the best way to go, it just works for us right now.

Shire out!

//J


Copyright © 2010 NullReference. Web hosting.