<!-- .slide: data-background="https://source.unsplash.com/842ofHC6MaI" -->
<!-- .slide: data-background-opacity="0.3" -->
# GIT SHIT DONE
---
### Who is this talk for?
- devs with (chronic) git pain
- all git users really
- you
---
<!-- .slide: data-background="https://source.unsplash.com/52QSSGA8Ej0" -->
##### Takeaway #1
Commits record state, not changes!
---
### Wait a second...
- <span style="color: grey; font-family: monospace; font-size: 95%;">git show</span> clearly shows me a diff
- <span style="color: grey; font-family: monospace; font-size: 95%;">git rebase</span> talks about applying commits
- what about <span style="color: grey; font-family: monospace; font-size: 95%;">git cherry-pick</span>?
---
### Commits, but simplified
- metadata such as author & message
- one or more parents (merge commits)
- filesystem state: trees and blobs
---
### Commands, but simplified
- diffs are always calculated
- commands often expand <span style="color: grey; font-family: monospace; font-size: 95%;">id</span> to mean <span style="color: grey; font-family: monospace; font-size: 95%;">id~..id</span>
---
### Rebasing, but simplified
- rebasing means running
```bash
git format-patch id~..id
git apply
```
- sequentially for each commit
- onto the target or the previous result
---
<!-- .slide: data-background="https://source.unsplash.com/0nOP5iHVaZ8" -->
##### Takeaway #2
Commits are referenced by different pointers
<br/>
##### (have a read some time: <span style="color: black; font-family: monospace; font-size: 85%;">man gitrevisions</span>)
---
### What's on the Menu:
- branch and ref names such as <span style="color: grey; font-family: monospace; font-size: 95%;">origin/main</span>
- <span style="color: grey; font-family: monospace; font-size: 95%;">@</span> or <span style="color: grey; font-family: monospace; font-size: 95%;">HEAD</span>
- generational selectors
- <span style="color: grey; font-family: monospace; font-size: 95%;">~</span> selects the previous generation
- <span style="color: grey; font-family: monospace; font-size: 95%;">^n</span> selects the n'th parent
- <span style="color: grey; font-family: monospace; font-size: 95%;">~3</span> == <span style="color: grey; font-family: monospace; font-size: 95%;">^1^1^1</span>
---
### What's on the Menu:
- commit message selectors
- <span style="color: grey; font-family: monospace; font-size: 95%;">:/api</span>, <span style="color: grey; font-family: monospace; font-size: 95%;">:/^test</span>, <span style="color: grey; font-family: monospace; font-size: 95%;">:/!-feat</span>
- time and history based selectors
- <span style="color: grey; font-family: monospace; font-size: 95%;">main@{yesterday}</span>
- this is what's managed by <span style="color: grey; font-family: monospace; font-size: 95%;">git reflog</span>!
---
### Try those some time
```cpp
# edit last two commits
git rebase -i @~~
# look at your week so far (independent of commit time!)
git log main@{last monday}..
# graph some commits, add common parents and mark dupes
git log --graph --boundary --cherry-mark main...feature
# fixup the last commit that starts with test
git commit --fixup :/^test
```
---
<!-- .slide: data-background-opacity="0.3" -->
<!-- .slide: data-background="https://source.unsplash.com/-G1yhU1Ej-9A" -->
##### Takeaway #3
Review feedback does not need to be a single odd commit
<br/>
---
### Reviews and Atomic Commits
- Fixup allows us to add requested changes to the correct commit
- Autosquash those during <span style="color: grey; font-family: monospace; font-size: 95%;">rebase -i</span> (it's a config option)
- [git absorb](https://github.com/tummychow/git-absorb) determines the fixup targets automatically!
---
### Absorbing Commits
1. Given a change <span style="color: grey; font-family: monospace; font-size: 95%;">A</span>, calculate a patch <span style="color: grey; font-family: monospace; font-size: 95%;">B</span> for <span style="color: grey; font-family: monospace; font-size: 95%;">@~..@</span>
2. Apply onto <span style="color: grey; font-family: monospace; font-size: 95%;">@~</span>
- first <span style="color: grey; font-family: monospace; font-size: 95%;">A</span>, then <span style="color: grey; font-family: monospace; font-size: 95%;">B</span>
- first <span style="color: grey; font-family: monospace; font-size: 95%;">B</span>, then <span style="color: grey; font-family: monospace; font-size: 95%;">A</span>
3. Equal results? <span style="color: grey; font-family: monospace; font-size: 95%;">A</span> and <span style="color: grey; font-family: monospace; font-size: 95%;">B</span> **commute**
- reset <span style="color: grey; font-family: monospace; font-size: 95%;">@</span> to <span style="color: grey; font-family: monospace; font-size: 95%;">@~</span> and goto 1.
4. Different results? Fixup commit <span style="color: grey; font-family: monospace; font-size: 95%;">x</span>, next change
---
### Thank you! :rocket:
{"breaks":true,"contributors":"[{\"id\":\"c3e679b3-a002-4886-9b37-c13c2bd251fa\",\"add\":7307,\"del\":4636}]","title":"Git Shit Done","description":"Practical Git for devs.","showTags":"false","slideOptions":"{}"}