pko.ch

Polyglot hacker & Architect

Archive for January, 2012

Taming git

Saturday, January 28th, 2012

I’ve switched from mercurial to git some time ago and I’m not regretting it. In general, there’s no difference from what I’ve learned in Mercurial. It all boils down to one sentence:

Truly grok, love and take pride in your repo’s commit graph.

To achieve this, these are some of the key points I follow.

Understanding the tree

Decent graph visibility

To truly understand DSCMs, you have to completely grok what’s happening on you repo in terms of commits, yours or otherwise. I find a decent graphical view goes a log way. And we have a very good one built-in.

git log --graph --oneline --decorate --all

Try it!

If you really want to see all nodes, even those not reachable by a branch, try:
git log --graph --oneline --decorate --all $(git reflog | awk '{print $1}')

Have a sane branching model

Begin with git-flow’s model, but have git-workflow manpage in mind. Try it out. If it hurts, stop, think and, only then, act.

Building the tree

Learn to use the index

The index, or cache, or staging area (git should get its names strait) is a place where you put the hunks that should be in the next commit. Yes, hunks, not files. You can have a really fine-grained control over what goes into the index with git add --patch. Selective removal of the index? git reset -p. Selectively throw out stuff not indexed? git checkout -p.

Make your commits laser focused

You should commit early and commit often. They should do one thing and do it right, on the right place in the commit graph. Don’t be afraid of having a commit with a one line diff and a commit a message of “Whitespace.”.

This will make your history more browsable and understandable for other people. Your reviewers will buy you more drinks and you’ll thank yourself on the next time you have some serious merge/rebase conflicts.

Too many commits? Wish you could roll some of them into each other? Or maybe just re-order them? Use git rebase --interactive.

Forgot to include something in your last commit? Use git commit --amend.

Remember that public history must be immutable, atomic, and easy to follow. However, before you publish your commit, your private history is your own. It’s malleable, disposable and nobody’s business but your own!

Switch tasks fast

Is there something cramping you style you but you already have changes on you working copy? Use git stash, then go all out on your annoyance. When your done, checkout the right branch, and git stash pop.

Just remember that git stash won’t keep the untracked files. Add them to the index if you want to keep them.

Know when to merge or rebase

Merges should be meaningful. They convey a very strong message to others that says “I merged these two lines of thinking and made them compatible”. If you’re not merging lines of thinking, you shouldn’t be doing a merge. You should probably rebase.

Rebasing is the act of recreating a set of commits on top of a new node. If it helps you, think of it as “transplanting commits to a new place in the graph”.

Caveat: Pull tries to be your friend, but it’s just too eager to please

Don’t use git pull.

It’s meant to be a tool for syncing with upstream. It’s just a git fetch followed by a gratuitous git merge. Merges should be thought out. Fetches should not.

Handling upstream changes by hand can be laborious, though. So, use git pull --rebase. It’ll use rebase instead of merging your local history which will result in not having stupid auto-micro-merges.

To give your clone some rebase love, just do:
git config branch.autosetuprebase always
git b | cut -c3- | xargs -I= echo git config branch.=.rebase true

Honor public history

Don’t rebase public commits.

When you rebase, you’re creating new nodes and “forgetting” about the old ones. In your local clone, at least. In everybody else’s, the nodes are still there and they won’t be able to make sense of a bunch of duplicated nodes (not right away, at least). And they’ll have to do some (serious) commit gardening to put things back where they should be. That will be a lot of work, I can guaranty you.

So, in order to keep thing clean for everyone, don’t change stuff you’ve already published.

However, while your commits are not yet published, muck around at will! The aim is to provide a good new addition to the repo’s public history.

No rules beat practicality

These are just a set of guidelines. They’re meant to keep things clean and easy to understand for normal operation. If there’s any situation that really demands it, you can (and probably should) violate your own rules. Just be sure to have everybody involved and aware of your punctual actions and its impact.

Be happy

Source code management should make you happy. Both in the present and in the future. If you having too much pain figuring out what going on, committing and sharing your changes or make sense of the past, figure out what’s causing you such pain and how you could be doing things differently.

Remember, this tool is more than appropriate to handle big projects like the Linux kernel. They’re not in pain, and so shouldn’t you.

Powerful = Simple + Focused

Friday, January 27th, 2012

This guy says just that. I don’t find his conclusions all that groundbreaking. But I really loved his focus on “It’s a record store”.

I’m pretty sure that’s not there is to it being a success. He, disguisedly, says that curating your content is fundamental. And he’ll charge you for that.


Via A Better Mess