Git Patter Issue

Git is great, I have about 100 repos, but I do still find issues that I would like to talk about.

This particular issue is about particular patterns, in particular the pattern where a change is a single commit...

This document is still a work in progress...

Single Commit

The pattern which is a single change is a single commit is quite common. Even before projects used version control, and specifically distributed version control, patches where submitted to the gate keeper. And effectively that patch was a feature or bug fix.

Git allows this to be done easily and distributed. Projects have a gate keeper will pull commits that could be hundreds of lines long, possibly even 1000s.

The point of a commit is that it is a thing - maybe a bug fix, maybe a new feature or enhancement.

There is many advantages to this model:

  • Testing - one major ability is to use bisect
  • The history/log is meaningful and practically becomes your change log

But there is a few things that I miss...

Problems

Remote backup

My bug fix may take days, perhaps even weeks. Where do I backup to? Normally I would just 'push' to a repository, possibly even my local 'bak' repository I usually attach.

But that only works if I commit.

Local backup

By committing regularly, you keep all changes. If you accidentally delete that file, you can get it back. What if you just accidentally deleted a section of code, and didn't notice for a few days.

My model is to commit very regularly, often multiple times in an hour.

Moving computers

I work on multiple computers. This is pretty normal, sometimes like me people moving between laptop and desktop, others that have to move to special machines for testing (e.g. testing off site, or in the field).

Collaboration

We work across computers, across the world, we often can't have a shared disk todo collaborative or agile development. Easy way to work around this is to use a VCS to share and some form of real time communication (IRC, Jabber, Skype ...).

However you might commit something that does not even compile. This would break the one time commit. Even if it does compile, it is probably not a complete fix.

Decision making

By committing regularly (see Local backup) I keep my decision making. Those changes can be important for finding out why something was done.

Fix / Clean up as you go

Good development technique, especially agile development, suggests that you fix up and clean up code as you go. If you see a missing comment, fix it. If you find a spelling mistake fix it. Maybe you just wanted to clean up white space or unnecessary compiler directives.

Transactions

In a shared repository, such as SVN, each time someone commits, that is it forever. This has lots of down sides, but also one up side. It is a transaction, there forever. But with GIT, you can overwrite changes, changing history. So transactions are lost.

Solutions

Branch Feature / Task

One model is to:

  • Branch for your feature / bug / change - really any logical thing
  • Commit as often as you like, but use sensible short messages
  • push anywhere you have, backup
  • push / pull from a shared location
  • rebase, mostly squash when you are happy with what you have
  • finally this new single commit can be pulled by the gatekeeper

Advantages:

  • Fixes most problems, specifically backup, local backup, and even some collaboration

Disadvantages:

  • You will need to force your push
  • Rebase will break anyone you share / collaborate with - so do this step in collaboration
  • Doesn't solve the "Fix / Clean up as you go"
  • Doesn't solve "Decision making"

Another way to squash feature branch into another branch

  • git merge --squash <feature_branch>

See also / References