finik.net
Dmitry Fink
Dmitry Fink
Oct 24th
As much as I love GIT, there are several design decisions that make my everyday work really difficult. One of such design flaws is making the repository and the working folder tightly coupled. It is a serious problem for every developer who is frequently switching between several product/topic branches of the same project.
Git gives you two options to deal with this:
As I quickly learned both solutions were not very practical for what I was doing. As a linux kernel developer in a company that actually ships multiple linux based products, I eventually found myself working and supporting several product branches, sometimes based on different versions of the kernel. One branch could be plain vanilla kernel.org kernel based on 2.6.32, another one could be an old product running of 2.6.24 with tons of additional architecture specific code that came from a vendor, etc. Both approaches had very serious drawbacks:
I’m not going to take credit for the method I am going to show you, I wasn’t the one who came up with it, Ed, one of the guys on my team did. Ed actually developed whole set of useful scripts for kernel development involving frequent switching between product branching, but the part about branching and multiple working folders is applicable to other projects as well, so that’s what I want to share with you.
Actually the trick is quite trivial, we use our knowledge of git internals and unix symbolic links to achieve what we want. All we wanted is to have one repository and multiple working folders associated with it, so lets do just that. That is how our final folder structure will look like:
project
+-.repo
+-.git
+-branches
+-config
+-description
+-HEAD
+-hooks
+-objects
+-info
+-packed-refs
+-refs
+-branchA
+-.git
+-branches -> ../../.repo/.git/branches
+-config -> ../../.repo/config
+-description
+-HEAD
+-index
+-hooks -> ../../.repo/hooks
+-objects -> ../../.repo/objects
+-info -> ../../.repo/info
+-packed-refs -> ../../.repo/packed-refs
+-refs -> ../../.repo/refs
+-branchB
+-branchC
...
etc
We created one wrapper “project” folder, one master GIT repository in .repo and a bunch of branchX folders. Each one of these folders is a legal GIT folder by itself, however it doesn’t keep its own config and objects/refs repositories, it links to the one in .repo instead. It does keep a private local version of HEAD, index (staging area) and the whole working folder. Every manipulation on the database performed in any of the branch folders is immediately visible in others (commits, branches, tags, remote changes), context switching is just a matter of changing folders now.
This is how we initialize this structure for the first time time:
mkdir .repo pushd .repo git init git remote add origin git://some.remote.url.../project.git git fetch origin popd newfolder.sh branchA pushd branchA git checkout -b branchA origin/branchA popd newfolder.sh branchB pushd branchB git checkout -b branchB origin/branchB popd
The script we used to automate creation of a new working folder (newfolder.sh). We can call it as many times as we want an whenever we need to create a new folder.
if [ "$1" == "" ]; then echo "Need to specify target." return fi TARGET=$1 mkdir $TARGET pushd $TARGET git init pushd .git for i in branches config hooks info objects refs packed-refs ; do rm -rf $i ln -sf ../../.repo/.git/$i $i done popd # .git popd # $TARGET
Enjoy! I find this method very useful already, but I’ll be glad to hear some feedback since I am sure someone will come up with a way to polish it and make it even better.
Update 10/25/01: I wrote the post yesterday, and today I accidentally found out that the trick described above for a while has been a part of a standard git distribution and can be found in contrib/workdir/git-new-workdir
Oct 19th
Of all tyrannies, a tyranny sincerely exercised for the good of its victims may be the most oppressive. It would be better to live under robber barons than under omnipotent moral busybodies. The robber baron’s cruelty may sometimes sleep, his cupidity may at some point be satiated; but those who torment us for our own good will torment us without end for they do so with the approval of their own conscience.
– C.S. Lewis
Sep 16th
Impressive! Why does army put so much focus on training guys taking apart and rebuilding stuff? When I have my own army (buahahaha!) part of my bootcamp training will be solving Rubik’s cube in under 30 seconds.