How to Work Efficiently With Git ?
Tags: git, productivity
Published: 2022-06-07 09:06:05

Git is a tool, and like any tool, there is a big difference between using it and using it properly. I will describe in this article the workflow I’m using in my day-to-day developer’s job.

## Starting to Work on a Ticket

When I start working on a Bug, on a User Story, on a Task or on whatever, I always start by checkout a branch containing my name, a short description of the issue and ticket number. It looks like :

```
git checkout -b tan/fix-event-crash-MIC-1831 origin/master
```

## Saving my work

After a few minutes or a few hours, depending on the complexity of the task, I end up to commit my modifications. I rarely use command line for commit, but use git gui instead:

```
git gui
```

And I systematically push my branch, also with git gui push button. This has 2 advantages:

- If I screw up my repos, I can still reset on the last time I pushed by branch.
- If my computer crash for any reason, I have a backup of my work.
I also use gitk a lot to see current status of my branch:

```
gitk
```

![gitk](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5y8859i4z2aj3ye0udg0.png)

Here I can see that I’m based on _master_, thanks to the _remote/origin/master_ label. I have 3 commits in my branch and my branch is currently pushed, thanks to the _remotes/origin/tan/feat2_ label being the same as local _tan/feat2_. So my work is saved.

I really commit/push A LOT. I push several times a day, and sometime up to several times per minutes for very short modifications.

## Retrieving Others’ Work

I regularly rebase my branch on current master to retrieve other’s work and address conflicts as soon as possible.

```
git fetch
git rebase origin/master
```

Note that I rebase, and not merge master into my branch. I want my history to be linear, and the only merge points that appear in history are merged of feature branches into the master branch.

## Always Push at the End of the Day

Whatever the status of my code, I always commit my work at the end of the day and push it. I never know what can happen. If I’m in a draft state, I just put everything in a commit and prefix commit message with “WIP”:

![gitk](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0hyw3fob7bckpr0j3gv3.png)

## Modifying the Yesterday’s WIP Commit

After a good night, I wake up and wonder what the hell I was doing yesterday. I clean up my mess and want to do a clean commit. But I commit an ugly “WIP” commit yesterday. Here comes the awesome “Amend Last Commit” git gui checkbox:

![git gui](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a8kph2qpnzbwik0gkv2n.png)

This checkbox let you modify the last commit, rewrite commit message, stage/unstage files etc… So I really have no reasons to not commit a WIP work.

## Interactive Rebase

I often do intermediates WIP commit, to explore a path until it leads to something concrete. I also frequently do small dumb fixes or typo correction that should go on older commit. To avoid having a lot of intermediate commits that goes back and forth, I practice interactive rebase. Interactive rebase is a wide topic. You can have a look [here](https://www.sitepoint.com/git-interactive-rebase-guide/) to have more details.

In the example below, while fixing a crash, I fix a typo in documentation I previously wrote. To indicate it, I prefix the commit message with an _f_ for _fixup_. I would like this commit to be squashed with the 2nd add doc commit, and then I would like to squash the _WIP_ commits with the _fix feat 1_ commit.

![gitk](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2z8ya95vjafmiou1bseb.png)

To do so, I do an interactive rebase:

```
git rebase -i origin/master
```

And go from this:

![interactive rebase](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kpln2ne432ytszd9hcgd.png)
 
to this:

![interactive rebase](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nkx8fz0a78xammmajxbg.png)

Now my branch is clean, I can publish the merge request and ask for review.

![gitk](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vl8gnjv9bn5sa3fia1y1.png)
 
## Conclusion

This workflow is well adapted to Trunk based development, but can also be used for any [git branching models](https://dev.to/tandrieu/an-overview-of-some-git-branching-models-3ilj). The most important points are:

- **Rebase** your branch on master instead of merging master in your branch.
- **Always push your work**, even draft and work in progress branches.
- **Learn interactive rebase**.