Part 2: Stashing and Rebasing in Git
Tags: git, productivity
Published: 2020-03-20 12:37:21

> Note: This series assumes the reader is familiar with using the command line and has used basic git commands during development. The series aims to provide examples of using lesser known git commands that improve development experience and reduce friction during collaboration across the team.

Part 1 covered how to set up git for your project, so you can collaborate better. Part 2 is about `git stash` and `git rebase` - two commands I use regularly when collaborating on tasks.

## git stash
---
While working in a team, there might be situations where you'd have to temporarily put away your current work, to work on something of higher priority, and `git stash` helps you _stash_ your work away and clear your working directory.

It helps to understand about the three stages, that your changes are moved to and from in a git repository, before we dive into git stash.

![Diagram of git stages](https://dev-to-uploads.s3.amazonaws.com/i/vxepyz5hzx5ufmptc7gx.png)

1. When you checkout or make new changes they live on the working directory.
2. Changes you `git add` are moved to a staging area.
3. From there when `git commit` they are moved to the repository.

So in between all these stages, `git stash` pushes all the changes in the working directory to a special directory called stash.

### `git stash push [-m <message>]`

Imagine a scenario, where you started working on a feature, but you're not nearly ready to commit these changes, and your teammate asks you to work on a different feature branch, because it is of higher priority. 

To start off you'd need to clean your working directory, and save your existing changes somewhere safe.

`git stash push -m "Upgrading version"` does just that.

![Screenshot of git stash push command](https://dev-to-uploads.s3.amazonaws.com/i/ynij1par0i8lw763ejjl.png)

Notice how after running `git stash`, the working directory becomes clean, that's because all the changes have been pushed elsewhere. Let's take a look at it.

### `git stash list`

It's what it sounds like, this commands lists down all the changes you stashed. We've stashed one such change. Let's look at where they've been saved.

![Screenshot of git stash list command](https://dev-to-uploads.s3.amazonaws.com/i/1ryz5pfprav9yfkbidml.png)

`git stash show` summarises the stashed changes. `git stash show -p [<stash>]` shows the exact diff that is stashed.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/t9mazsgm5yoyi7rzkrb4.png)

### `git stash pop [<stash>]`

Let's find out how we can retrieve changes from a stash to the working directory. There are two ways to do this: `git stash pop` and `git stash apply`. `pop` removes the stash before applying it, `apply` does the same but doesn't remove the change set from the stash.

![Screenshot of git stash pop command](https://dev-to-uploads.s3.amazonaws.com/i/5kho5jwbgakx3b94se0k.png)

Notice how the stash is empty after popping.

### `git stash apply [<stash>]`

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4ttr9stktr7ns4gzogox.png)

The stash remains the same after using apply.

### `git stash drop [<stash>]`

Use this command when you want to delete an outdated stash from you list. 

_When you want to clear the entire list, use `git stash clear`._

### pro tips

1. Use `git stash` to temporarily put away your changes when checking out a new branch.
2. Ensure your working directory is clean before applying changes from stash.
3. `pop`, `apply` and `drop` take an optional `<stash>` parameter. If not provided, it defaults to 0, which is the latest stash.

## git rebase
---
`git rebase` applies your commits on top of another branch's tip. A diagram would explain this better.

![Diagram explaining what happens in git rebase](https://dev-to-uploads.s3.amazonaws.com/i/2sxa3dl6pnbvuuhp3a0e.png)

This command allows you to be able to move your commits, making this a very powerful command, used for different purposes. Let's look at a few scenarios.

### Conflict free merges

As we saw in [Part 1](https://dev.to/maybebored/part-1-setting-up-git-5819) of this series, teams that follow git, feature branches are merged onto the Development branch. To avoid conflicts during merge, we try to ensure that the HEAD of your feature branch is on top of the latest commit in the Development branch.

![Screenshot of git log of diverged branches before and after git rebase](https://dev-to-uploads.s3.amazonaws.com/i/p6k037vmbxg1w6okujv6.png)

Branch **feature** and branch **Development** have one commit each and therefore in git terms, have diverged. By rebasing **feature** on **Development**, all the commits of the **feature** branch will be _replayed_ on top of the latest commit in the **Development** branch.

Notice how after _rebasing_ the commit hash changes, this is because git creates new commits behind the screen, and stops pointing to the old commits.

Merging `feature_branch` to `Development` would now result in a fast-forward merge, which means there will be no conflicts to resolve during the merge. A bit more about [Git Merge] (https://www.atlassian.com/git/tutorials/using-branches/git-merge).

### Rewriting history

Git Rebase essentially allows for moving commits around. Since git commits are record of history, by moving them around we can indeed _rewrite history_.

Here's a quick overview of ways you can change history:

#### - _Pick_ or _drop_ commits.

You might have accidentally committed some changes. To undo that you can drop it from the history.

#### - _Squash_ commits together.

Consider a series of commits in which you fixed typos. Consider squashing all of them together to make your history look cleaner.

#### - _Edit_ or _reword_ commits.

Everyone loves meaningful and clean commit messages. Reword commits if you think it wouldn't make sense to your reviewer.

### pro tips

1. Use `git rebase` to sync your feature branch with the branch it will be merged into.
2. Interactive rebase (`git rebase -i`) requires basic vim usage. Check out this awesome [cheatsheet](https://devhints.io/vim) to get started.

---
In this post, we checked out `git stash` and `git rebase` and where to use them. Check out the [official documentation](https://git-scm.com/docs) for advanced usage and in some depth information.

Let me know if you'd like me to continue updating this series, with more commands I run into.