WARNING! This article has been written a long time ago. It may no longer represent the current views of the author!

Notes: Git

DISCLAIMER: this is not meant to be coherent post. Sorry. Just notes for future reference. There will probably be some future updates here.

I sometimes (more like all the time) need to work with git repositories. Here is a collection of references to tricks/useful pieces of information that I have learned over the years. The tidbits below might be useful to know, in general. They are also things that I don't necessarily use everyday, but needed at some point in time to solve my problems, and it is by far easier for me to find them here than to look for them somewhere on the Internet for those solutions.

Git aliases to work with a smile on the face

Some of my favourite aliases to have on hand:

[alias]
    lg =  log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset) --all'

The git lg command now prints a compact & tree-like structure out of the commit history, like this:

*   0a91cf0 - (5 months ago) merge: branch 'lr/no-libnm-glib' - Lubomir Rintel
|\  
| * eb93480 - (5 months ago) gitlab: align the gitlab-ci file with other VPN plugins - Lubomir Rintel
| * 98e0166 - (5 months ago) gitlab: fix a comment - Lubomir Rintel
| * a265457 - (5 months ago) Revert "gitlab-ci: add scheduled pipeline to triage inactive issues and MRs" - Lubomir Rintel
| * a83c45b - (5 months ago) build: bump required libnma version - Lubomir Rintel
| * 57af29e - (5 months ago) all: drop libnm-glib version - Lubomir Rintel
* | 47cfa8b - (5 months ago) build: replace intltool with gettext - Lubomir Rintel
* | 792f11a - (5 months ago) build: deal with some autoconf warnings - Lubomir Rintel
* | 3d1dde6 - (5 months ago) ChangeLog: drop - Lubomir Rintel
* | 0a78083 - (5 months ago) Update Indonesian translation - Andika Triwidada
|/  
* bc34433 - (5 months ago) Update Polish translation - Piotr Drąg

Good approach to structuring the repository

One of the very first things I have learned - "A successful Git branching model" by Vincent Driessen. Highly recommended read.

How to merge a single file on multiple branches

Here's the description of the problem - given N release branches (e.g major supported versions), merge changes from one file without changing irrelevant information AND without loosing sanity.

So, for example, after working on some feature-better-schwiftifying branch, we can patch the changes to relevant branches (version-{7,8,9}.x), where we have connected by diverging code. (I am not saying that this is a good approach to development. I want to present quite useful feature of Git.)

git checkout version-8.x
git checkout --patch feature-better-schwiftifying -- schwifty.py

After applying merging relevant hunks we can commit the changes on the branch version-8.x and move along to other branches.

Move wrongly created commits to the right branch

Have you commited something only to discover that …sigh… it was the wrong branch? Here's an useful snippet to the rescue!

git branch newbranch      # Create a new branch, containing all current commits
git reset --keep HEAD~3   # Move master back by 3 commits (Make sure you know how many commits you need to go back)
git checkout newbranch    # Go to the new branch that still has the desired commits
# Warning: after this it's not safe to do a rebase in newbranch without extra care.'

Squash git commits using rebase

Let's say you have a repository with a similar commit history:

git lg

* 0000006 - (6 days ago) Fix typo in template for bulbulator - Jakub Olczyk (HEAD, origin/master, master, fix-bulbulator)
* 0000005 - (8 days ago) Enable tootinator for changes in bulbulator - Jakub Olczyk
* 0000004 - (12 days ago) Start work on bulbulator - Jakub Olczyk
* 0000003 - (8 weeks ago) Debuzz the fizz - Frodo Baggins
* 0000002 - (3 months ago) Foo barr - John Wick
* 0000001 - (3 months ago) Init - Jon Doe

Now you want to squish the first 3 commits. To do that you can use 2 approaches:

git rebase -i HEAD~3 # here we specify the number of commits we want to

or

git rebase -i 0000003

Later the commits will be squashed via interactive choice presented by git. The usually useful options are pick and fixup.