Do up your branch before merge.
Tags: git, tutorial, productivity
Published: 2022-01-18 22:22:07

> Cover Image: _Puppy Bath Time!_ by pixel artist **Andrea Zevallos** - [@SazdxHikari](https://twitter.com/SazdxHikari)

---

_Finally! My feature is ready for review. Now I'm opening the PR_… but hold on!🚨📰
Ponder the question: _How does your branch look like?_

```log
$> git log --pretty=format:'%h - %s' main..feature/drag-n-drop-grid  
f6dec33 - chore: revert tsconfig 
ee409e7 - revert DragDropWrapper (recover prev. code) 
7dfcee2 - fix ci 6a84dd7 - testing 
d14ffee - new component <DragDropGridWrapper /> 
914cca3 - wip 
8796b3e - feat: replace internal library for <DragDropWrapper /> 
f6ad24c - chore: review .eslint + tsconfig 
7da219e - new dependency 'react-draggable-tags'
```

That '_WIP_' commit? sure I wasn't into writing a message; the '_fix-CI_' one? I didn't expect it to occur; the '_revert_' over there? yep that was causing too much trouble 🤷‍♀ .

> Development process has these steps back. You start coding with some idea in mind; maybe you change the approach while coding; maybe you add some extra - not 100% related - boy-scouting; maybe you reinforce the coverage of a piece you're to use, etc.

Thing is, final history might look better when merging it to master. **`git` allows us to change the past, and pretend you did nailed it from the beginning.**

All we need is ~~the Gem of Time~~

```bash
$> git rebase --interactive main
```

![Marvel's Dr. Strange practicing time control using an apple](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7cgtltf7klrukdnbef9e.jpg)

## Our example branch

Before messing up with time traveling, let's schematize our feature branch.

![Schema for our example branch as a graph](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5n3y52lmzloxjd2viwkc.png)

1. Add new dependency to the project
2. Unrelated change to `eslint` and `tsconfig` config files
3. Start the feature itself: change the internal implementation of a React component
4, WIP (continues commit #3)
5. Here we change the approach: instead of changing the existing component (prob. we'll mark it as deprecated at some point), we decided to create a brand new component.
6. Tests for the new component
7. Fix CI (continues commit #6)
8. We recover the original component (using `get reset`) keeping both components in the project.
9. Revert `tsconfig` change from commit #2 (prob. it was causing more noise than expected

## Baby Steps

### 1. Don't panic. 

Remember that once you've committed, you can't lose your work(\*).

You may save the reference (the hash) of the top commit. This can be used as a _panic-button_ any time to get back to the initial situation.

```bash
$> git reset --hard <ref>
```

> (\*) there could be extreme situations like loosing the hard drive or zombie apocalypse 🧟 but you get what I mean.

### 2. Start **squashing (s)** any '_WIP_' and '_Fix prev. commit_' to their parent.

![previous graph were we're squashing commits #4 & #7](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p98uwmfi3j215b7jd8th.png)

Change the word `pick` by `s` for those commits. In this example:

```bash
$» git rebase --interactive main
pick 7da219e new dependency 'react-draggable-tags' 
pick f6ad24c chore: review .eslint + tsconfig 
pick 8796b3e feat: replace internal library for <DragDropWrapper /> 
s 914cca3 wip 
pick d14ffee new component <DragDropGridWrapper /> 
pick 6a84dd7 testing 
s 7dfcee2 fix ci 
pick ee409e7 revert DragDropWrapper (recover prev. code) 
pick f6dec33 chore: revert tsconfig
```

When squashing (s), you'll be prompted for the resulting message. In this case we'll discard commit message #2 both times

![screenshot of the rebase console](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wsj81lfss0daylwyqlwa.png)

### 3. Place together (**move**) every related commit.

In this example, we're moving the top-most commit to be right after it's counterpart. Besides, we're squashing the testing commit to its parent.

![previous graph were we're squashing commits #4 & #7](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1xrs5qx693vqgc4km4qo.png)

![screenshot of the rebase console II](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bpo0crbdpav8mayezknj.png)

### 4. Keep squashing

Now that we have these 3 - let's call them -  'sections'. Seems fair that we can squash one last time.

![final schema where finally there are just 3 sections](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2vec4jdkd6yw1lhwixyr.png)

> Note: with `rebase` you may get merge conflicts (exactly the same way you face conflicts with git merge). 
> My recommendation is to keep focused on "_How will this code look like in the final picture?_"; pretend you did nailed it from the beginning.

### 5. Finishing touches 💅. Take the chance to **reword (r)** commit messages. 

Personally I use **Semantic Commit Messages**. But we can cover that at another time.

This is our branch after taking a bath 🧽. Much better right?

```bash
$> git log --pretty=format:'%h - %s' main..feature/drag-n-drop-grid
a3f5f33 - feat: new component <DragDropGridWrapper />
f6ad24c - chore: review .eslint
7da219e - chore: new dependency 'react-draggable-tags'
```

---

## TL;DR

1. Don't panic. Once you've committed, you can't lose your work. You may prepare a _panic-button_ copying the hash.
2. **Squash (s)** any "_WIP_" and "_Fix prev. commit_" to their parents.
3. Place together (**move**) every related commit. 
4. (If applicable) keep squashing.
5. **Reword (r)** commit messages.


> - Thanks for reading 💚.