Software localization

Top 5 Tricks for Git You May Not Be Using Yet (Part 1)

In this short series of blog posts we would like to present some of the more advanced Git techniques we use at Phrase.
Software localization blog category featured image | Phrase

Git is a quite popular source code management system (SCM). Platforms like Github and Bitbucket offer great web-based collaboration tools, but it can also easily be hosted locally.

Basic Git Objects

To anyone new to Git: A Git project consists of basically three types of objects: blobs,trees and commits.

A blob is essentially just a version of a single file, identified by it’s SHA1 digest (short: hash).

A tree documents the structure and grouping of files and can contain other trees. It stores the specific file names and versions of files as well as sub-trees.

A commit is the top-level tree node together with information about the commit’s author and time.

Commits can be tagged with a name using Git tag and there are special tags pointing to the current state and history of a branch like HEAD or origin/master.

Read more about the Git objects in the Git Book.

Motivation: Commits As Communication

If you’re handling multiple feature branches, stuck in merge-hell or sick of merge-commits that reintroduce old bits of code maybe a bit of git rebase-jiu jitsu is for you.

The idea is to omit merge commits by just having fast-forward changes. The secret sauce is to keep changes and thereby keep merging-complexity to a low level.

For me, commits have meaning over time:

First they document coherent work steps at a pretty granular level. Later they become coherent units of new features or feature-changes like the idea of the insert-modus in vim, a commit can be a unit of change, thus becoming a means of communication.

This is why I do not particularly love commit messages that read “fix”, “fix fix” or “die, bug, die” … though I have to admit that I occasionally resort to those kind of messages for personal catharsis.

Trick #1: Changing History With Interactive Rebase

The following applies to working on a branch or un-pushed changes locally only: When the commit has survived some time it loses it’s individual value; it usually becomes part of a set of commits that form a feature.

When this is the case I do not care about the individual commit any longer.

It can be squashed (git-slang for combined) with other changes to form a coherent message like “Ticket-123 Users can now sign-up using an email”. This is what git rebase -i can be used for.

git rebase -i HEAD~4

This lets you rewrite the history after the commit HEAD~4 with is the 4th latest commit in your history.

It will open your $EDITOR (specified in env, e.g. export EDITOR=vim) with a list of the last for commits.

pick 7f365c5 adds a spec for a new feature

pick 155ae98 implements a change on the model

pick db1b02c improves integration spec

pick d8b86d5 fixes typo in feature

Usually we want to base a set of commits on one commit, change it’s message to reflect the newly combined changes and get rid of the clutter in our history (in the example HEAD~4). The next commit in the example 7f365c5 (HEAD~3), is the first one we may change. We can tell git what to do with the commit by exchanging pick with any other option like r for reword or f for fixup.

r 7f365c5 adds a spec for a new feature

f 155ae98 implements a change on the model

f db1b02c improves integration spec

f d8b86d5 fixes typo in feature

When saving the changed file a new editor window with the commit message of the first commit in the list opens up.

We can change the message to whatever reflects the content of the combined commits (e.g. “introducing new feature A”) and then save. The commit message in the history will change and the three following commits will be combined into the first one (fixup).

This will cause the content of the commit and therefore it’s tree and hash to change.

We just altered history (on our current branch) so be aware that only a force-push will bring these changes to remote, but this should only be done on branches nobody else has pushed to in the meantime (e.g. based their changes on the history of155ae98..d8b86d5 which have been moved to the newly rebased commit).

Rebasing is powerful and can be a meaningful tool for communication and grouping of changes, but practice using it first and find out if you like what it does.

Further Reading

Be sure to subscribe and receive all updates from the Phrase blog straight to your inbox. You’ll receive localization best practices, about cultural aspects of breaking into new markets, guides and tutorials for optimizing software translation and other industry insights and information. Don’t miss out!