logo

My twisted Git workflow ⛏

Recently I took a lot of interest in Golang. I was listening to the GO TIME podcast — GoLand IDE and managing Gopher Slack and there was a lot of chatter about IDEs vs. editors. What sparked my interest was the discussion around working with Git from the command line vs. using the IDEs built-in tools. This is what motivated me to write about the workflow I have with Git.

It’s neither new nor unique, but I figured it might help some people decide what tools to use and when, while working with Git.

I’ve been working with Git since 2012 — not a long time, compared to other people — and I’ve been through all the ups and downs. From messing up whitespace on a huge project and re-committing everything to the repository because of autocrlf, to committing code to the client’s repository using my personal email address, swearing in commit messages, losing a week’s worth of work because I was treating Git as I treated SVN, I did a lot of stupid things. I also learned a lot. Here are a couple of things I learned.

Branch naming convention

There’s no magic here. For the past 3 years I’ve consistently used the following convention on client projects — if they didn’t already use one.

type-of-work/TICKET_ID-short-task-description

I kinda stole the naming convention from the Angular Commit Message Guideline which I also use for commit messages.

For the type of work, I have only 4 types: feature, bug, docs and chore. I also tend to introduce infrastructure for tasks that touch dockerfiles or other infrastructure-oriented files.

The TICKET_ID is also something very important. I’m very religious about it because most of the Git services have some sort of integration with the issue tracker of choice. So if the client is using an external issue tracker, using ticket ids in the branch name helps a ton. It adds an extra layer of transparency for business, they’re able to see that tasks are being worked on, pull requests are open and closed, and so on. Actually, the biggest benefit for using ticket ids is actually related to code reviews.

For example, the current client uses the BitBucket and Jira combo. It’s very useful to click on a ticket in Jira, that’s in the “Code review” column, click on the pull request link attached to the ticket, and go straight to the open PR in BitBucket and review the changes. Conversely, once I’m done with the review, assuming there are no changes required, I can click on the Jira ticket id in the branch name/PR description, which opens a modal with the Jira ticket. I can then change its status to “Ready for QA” and assign it to the proper person.

Here’s a practical example: feature/MBS-44-add-facebook-login.

Merge Request/Pull Request practices

Nothing fancy here, as well. Most Git services today offer a custom link in the command line, when you push your changes that when you click automatically tell the system to create a PR for you and pre-populate it with details from your branch name and commit messages.

The only difference here is that instead of separating everything with slashes and dashes I only use slashes. So a pull request message for the previous branch would look like this: Feature/MBS-44/Add Facebook login. Having the ticket id in the pull request title serves the same purposes I mentioned in the branch naming convention section.

Commit messages

For this part, I’m more freeform, in the sense that I’m not too religious about using the Angular Commit Message Guidelines exclusively. Most of the times, my commit messages are structured as such, with the addition of the ticket id in commit messages as well. This is mostly due to the fact that I recommend every commit to be tied to a issue tracker card, so work is 100% transparent. It also helps if you squash commits before you merge, when you pull changes into the master branch.

But there are times when a single, descriptive commit message, that doesn’t adhere to the above style guide is all I need, so I go for that instead.

The command line

Ah, the dreaded command line. Alongside Vim, the command line makes more victims than the avian flu! Not actually true, I just made this up, but here’s something to partially support my claims.

When I started using Git, I learned to use it straight from the command line. This is why I can’t go full time with any of the editor/IDE built-in Git management tools. It just feels like I’m lacking control.

I use the command line whenever I have to do some merge/rebase that is prone to generate multiple conflicts, empty commits, etc. Like I said, it’s all about being in control of things. If I don’t know what commands are being executed behind the scenes, and in what order, then I just run them by hand.

I also resort to conflict resolution by directly editing the files, in Vim, or whatever editor I have open at that time, if I feel that it’s easier for me to do so.

The editor/IDE Git integration

The first thing I use the built-in Git integration of my editor is the diff. If I have many changes or conflicts to review and resolve, I jump into the editor and pop open the diff tool. If I’m clear on what happens and I don’t have any second thoughts about the correctness of what I’m about to do, then I will also resolve the conflicts right there and then. Otherwise, I will switch to the command line to carry the task through to completion.

GitHub Desktop

The only reason I use this tool is to commit specific lines of code in a given file. Let’s say I work on a file and modify 3 functions. I want to create three separate commits, one for each function. Although the command-line syntax for committing what Git calls “hunks” is very easy to use — git commit -p — the experience of picking the code to stage is not quite right. I know I have a proclivity for overcomplicating things, but one thing I dislike is to clutter my memory with useless things. I consider staging hunks from the command line to be useless.

Putting it all together

The conclusion I drew from 6 years of using Git and making mistakes along the way is that you shouldn’t focus on a single tool to do the job. Use your tools for what they’re good at. Is your IDE’s Git integration amazing at diffs and conflict resolution but sucks at committing individual lines? Use GitHub desktop, it’s free and it works well!

Use the right tool for the right job. Get it done! Move to the next one. Repeat.

Resources

I’ll only add what I think is the best resource to understand Git. I keep recommending it since 2013: git - the simple guide. Enjoy!

Cheers!

Photo credits: Dennis JarvisDSC07672 - Coal Face

Copyright (c) 2023 Adrian Oprea. All rights reserved.