Efficient Git Workflow pt. 1

Oleg Codes
6 min readApr 27, 2021

--

In these series of articles it is explained, how to use git efficiently when working on your own and as a member of a team.

The article covers useful commands and subtle rules of managing commits, as well as gives a brief overview on the most used merging processes, and how to utilise them when working as a team.

Efficient Git Workflows is a series of 3 articles, and this article is part 1.
Links to the other parts will be added as soon as they are released.

Preface

Working in a such fast-paced industry as SoftwareEngineering, quick learning and being able to use tools efficiently are paramount. If you ask a Designer or an Illustrator about what makes up a professional in their field, they, most probably, mention knowledge of controls of their digital work tools.

Same goes for Software Engineers: having commands and shortcuts on the tips of their fingers differentiates a real professional from an amateur.

About Git

Git is a version control system which is mainly adopted in Software Engineering for storing code and its changes. Currently (2021) it is a de-facto standard in the industry.

Article Structure

Numerous books and great tutorials already cover functionality Git. However, many of them cover too much or too little.

On the contrary, this article follows the Pareto Principle: it provides 20% of knowledge, which potentially yield 80% of the results. It will be most useful for people with some prior knowledge of git and SE who are looking to enhance and deepen their knowledge.

Part 1: Starting Work

First part is all about working on your own commits and having a tidy commit history. Your best friends at this stage are: git log , git commit , and git status .

Rule 1: Summary Line ~< 72 Characters

The rule is aimed to improve readability of the commit messages, when browsing history of a git repository.

Other sources would suggest to applying 50/72 rule, which stands for 50 character limit for the summary and maximum of 72 characters per line of the description.

The reason for the 50 character limit is that online hosting platforms such as Github or Gitlab would cut off a long summary making it impossible to understand the purpose of a commit message without opening it separately. Here is how long commit message might look:

This is a very long commit line which would be cutoff approxim…

The actual character limit for Gitlab or Github is around 70 characters, so there is no need to push your commit messages to the 50 character limit anymore.

The other issue with long summary lines is that they would be pushed to a newline in a typically sized terminal window:

$ git log --onelinebd51fcc Add installation instructions to README.md
225d222 Add auth to UserController methods
bba7f71 If you read other articles you might find information about 50/72 rule, which stands for 50 character limit for the summary and maximum 72 characters per line of the description. Also I like to eat sushi for lunch.
956a44c Improve performance of the BlackBox
87007bd Upgrade Symfony to v5.2

Rule 2: What — Now, Why — Later

Having a short summary line from Rule 1 asks for a followup question: Where and how to explain the change of the committed code?

If we look at the example from the previous Rule, the commit messages explain what has been done, which makes sense when you have a quick look at the changes:

$ git log --oneline956a44c Improve performance of the BlackBox

When it comes to explaining why a certain change has been made it is useful to put such details in the commit on the next line, separating summary and details with one empty line:

$ git logcommit 956a44ca43cd10c9920bd31902e3f834871b936d
Author: Oleg Shchelkunov <oleg.shchelkunov@example.com>
Date: Tue Dec 1 16:10:18 2020 +0100
Improve performance of the BlackBoxBlackBox class was suffering from memory leaks
due to inefficent GC collection in the main
loop. More details can be found in a research
ticket RD-123
Closes XX-000

Rule 3: Imperative over Declarative

Our purpose as an author of a commit is to let other people understand what has been done and (if required) why it has been done.

There are multiple ways of structuring a sentence (or a commit message) whilst conveying its meaning. Some of these ways could be more verbose and less understandable than others.

A commit message about adding a feature to a UsersController class can be written in multiple ways:

$ git log --oneline956a44c Added feature flags function to UsersController
225d222 Adding feature flags function to UsersController
87007bd Add feature flags function to UsersController

Any of the aforementioned commits conveys same message to the reader, whilst the latter is easier (and faster) to read.

Rule 4: Useful Commit Messages

Let’s have a look at a typical pull request commit history:

$ git log --onelinec6579b0 Fix typo
8c071c4 Codestyle Fixes
a4b1970 Update tests
78649b4 Optimisations.

The issue with such history is that after such some time passed there would be little to none value of such commit messages for anybody trying to understand the history of the code.

The rule of thumb here: place yourself in the future, and it should be possible, at least vaguely, to understand what this commit is all about. If it is not possible there is not much value in such a commit.

Revised commit examples:

$ git log --onelinec6579b0 // merged with previous commit
8c071c4 // merged with previous commit
a4b1970 Add performance tests to UserController list method
78649b4 Remove unnecessary database calls in BlackBox prefetch

As you can see, only two commits left. The codestyle change and type fixes are now a part of another, useful commit.

The only reason to have code style or typography error fixes as separate commits is when such work is being carried out on purpose, and not as part of another change.

Rule 5: Atomic Commits

No doubt that dealing with large changes in commits are harder than small ones. It is also hard to describe what was done in a commit if such a commit incorporates many changes.

$ git log --oneline78649b4 Added second rule, changing SomeClass.
bba7f71 XX-00 Add date range picker, MyEnterpriseClass was also updated, add some other things and laso I like to eat sushi for lunch with some green tea.

There are couple of things to consider:

  • If a commit message summary has a word and, then consider splitting a commit into two or more commits. This might not be easy if two changes are in the same file but learning to work on one topic and make an atomic commit needs a bit of practice and discipline.
  • Every commit message should be a working increment: you should be able to deploy such change. If your commit is a job half done, it makes sense to rethink your approach to writing the code. It does not mean that every commit message must be deployable, but at least a build should not fail.

The previous example can be rewritten as following:

$ git log --oneline78649b4 Add second git worklow rule
956a44c Fix SomeClass failing when null value is passed
bba7f71 Add date range picker to user list page
bd51fcc Extract veryImportantMethod from MyEnterpriseClass.

Summary

In this article we have learned:

  • How to make your own commits to be well structured and readable

The author would gladly appreciate if you drop a couple of lines on how your team works and which small things make difference in your team.

Happy coding!

Next in Series

  • Part 2: TBA
  • Part 3: TBA

--

--