git workree, quick intro ( simplify your git workflow! )
Tags: git, worktree, stash
Published: 2021-05-30 15:59:11

Here is a fast example of how to use `git worktree`, it's extremely helpful and at the same time extremely unpopular `git` feature.

Surprisingly it has been around for ages, but no one seems to know about, yet fall in love on first try!!!

I, personally discovered it from one of Guido's, tweets:
{% twitter 1379893622145871873 %}

## Problematic 

to present a solution, we have to understand the problem it tries to solve, before jumping to a solution. Here is a simple scenario:

You are trying to work on your own feature for some time. Meanwhile, a coworker writes to you, with a request to review his work, that he has done on a __separate__ branch of the same repo.

Most likely, your next steps would be:

**1** - save your work in `stash` with command

```bash
git stash save <name>
```

**2** - `checkout` to the branch that coworker wants you to review

```bash
git checkout feature-coworkers-branch
```

**3** - there might be a need to install the dependencies, with 
```bash
pip install -r req.txt
// or 
yarn 
```

**4** - after browsing though the branch, and finishing with the review, you would want to revert back to the branch that you have worker on

```bash
git checkout feature-your-old-branch
```

**5** - **HIDERANCE** 1: you have to find && __unstash__ your code. You can run, `git stash pop/apply`, in case the last stash that you have saved, is the one you need

you might need to run:
```bash
git stash list
```

```bash
git stash pop stash{0} 
// or 
git stash apply
```

> please note that git stash apply won't delete the stashed item from the stash list

to look up for just the right `stash`, saving stash with <name> helps a lot. But still sometimes, in a heat of the moment, while having multiple work processes saved in stash, we get lost, apply the the wrong `stash` and then another one... 


**6** - **HINDERANCE** 2: you might encounter a problem of dependency conflict. The dependencies that were installed in `feature-coworkers-branch`, might hinder your work, due to requiring different versions, demanding different configuration etc... The solution would be to delete/reinstall them, but that's once again an annoying process.

> Note: A different workflow, might be cloning a repo in a different folder, doing the review there and discarding it afterwards. But what about the time it would take to install all the dependencies? 


All in all, that's an uncomfortable situation to be in. We have encountered it frequently, it consumes our time and mental power.

Luckily, `git` have a better way

## Solution

`worktree` is wonderful alternative, let's try to follow the same steps using this feature.



**1** - While working on your feature, use `worktree` command to create a new folder/directory of the same repo, and specify which branch you want to start with
 
```bash
git worktree add ../repo_test feature-42-update-mat-view
# git worktree add <path> <optional:starting-branch-name>
```

and BOOM, now you are in a separate folder/directory, on a `feature-42-update-mat-view` branch.

**2** - Install all the dependencies necessary to check the work
```bash
pip install -r req.txt
// or 
yarn 
```  

**3** - Write to your colleague, remove `rm -rdf repo_test` / `git worktree remove ../repo_test` ( or keep it there ), and get back to folder containing your own work progress.

> If a working tree is deleted without using `git worktree remove`, then its associated administrative files, which reside in the repository (see "DETAILS" below), will eventually be removed automatically ...


That's it!!!

No need to `stash` the code, revert installed dependencies and dig through `stash list`.

This way is not only faster, but also, much less error prone! 
Having errorless `git` workflow is especially important to keep the concentration on your work.


## Tips && References

**1** - Official `git` [documentation](https://git-scm.com/docs/git-worktree) is very good

**2** - If you create a worktree with intention to make some experimental changes, pass `-d` flag.
```bash
git worktree add -d ../repo_test
``` 

this quote from `git worktree` [docs](https://git-scm.com/docs/git-clone#_description)

> For instance, `git worktree add -d <path>` creates a new working tree with a detached HEAD at the same commit as the current branch.

**3** - Another good workflow would be is to start off by cloning a `bare` repo. Then use `worktree add ...` and have a list of your __worktrees__ in a __bare__ repo.
```bash
git clone --bare url...
```

git [--bare](https://git-scm.com/docs/git-clone#Documentation/git-clone.txt---bare) docs