Red Hot Chili Python

(Git/Mercurial) Clone per feature workflow

«  Python double-call hack for mocking date/time   ::   Contents   ::   Psql и таблички с большим количеством полей  »

(Git/Mercurial) Clone per feature workflow

People usually do single clone of project, and then later do the branch-switching and stashing dances in time of development. I find it rather uncomfortable.

What I do is simply having a clone per feature. So my ~/workspace/ directory looks something like this:

myproj-1134-refactor-tests
myproj-1534-add-useful-stuff
myproj-12.0
myproj-13.0
myproj-1983-do-nice-things
myproj-master

And before I want to work on some feature, say, for ticket #9999, I would do:

➤ proj-clone myproj-9999-something-new-to-do master

Which would ask small script to make a directory myproj-9999-something-new-to-do for me, which would contain clone of project in master branch (you can branch-out to feature-branch then if you want).

Why is this better than stashing / branch switching

Reasons are that you don’t even have to exit your text editor (or even save your edits), or stopping your local webserver, or remove temporary files (like *.pyc if you’re doing python), or the stashing thing itself.

Personally I find it also better from “keep it simple” perspective.

If you’re in a middle of working on something, and you’re asked to put some small fix, you just do (if you’re already working on master) ➤ proj-clone myproj-master-tmp master, launch new editor and go fix your thing. Later you can just rm -rf the whole directory if it’s not needed.

The proj-clone script itself

You’ve noticed, that I didn’t just do hg clone or git clone, but rather called some proj-clone script. There’s a reason for that.

At glance, here’s how it looks like for git:

#!/bin/bash
if [ $# != 2 ] ; then
    echo "usage: proj-clone target_dir revision"
    exit 1
fi
cd proj-git
git pull
cd ..
git clone --local proj-git $1
cp proj-git/.git/config $1/.git/
cd $1
# I don't know how else do you clone
# with all origin heads being kept, sorry
git pull
# <- you can also do some project-specific bootstrapping here
cowsay $'Ok, it\'s ready!'

Note

This script looks like non-perfect, but I didn’t yet figured out how to make it efficient in git. Maybe you know.

First, you need to make a clone of your project to proj-git directory. Script goes to that directory and does git pull inside. Then it runs git clone proj-git $1 to make a clone. Reason why it’s doing local clone rather than remote clone is that Git and Mercurial build hard-links when they’re cloning locally, so you’re space is not increasing much.

Then, it copies .git/config file so that from now on your pulls and pushes are going to push remotely by default. And checks out the branch you provided in second argument.

You should also add some project-specific things. For my project it is creating an empty directory for test-data, copying settings and copying .emacs-project file.

For mercurial, script would look something like this:

#!/bin/bash
if [ $# != 2 ] ; then
    echo "usage: proj-clone target_dir revision"
    exit 1
fi
cd proj-hg
hg fetch
cd ..
hg clone proj-hg $1 --noupdate
cp proj-hg/.hg/hgrc $1/.hg/
# <- configuration and other bootstrapping here
cd $1
hg up -r $2
cowsay $'Oh mercurial, I miss you so much!'

Summarize

This approach may not fit your programming routine, but it definitely made my life happier. So I hope it will do so for more people.

«  Python double-call hack for mocking date/time   ::   Contents   ::   Psql и таблички с большим количеством полей  »

blog comments powered by Disqus