Introducing Git Machete
by Paweł Lipski @plipski,
Mikołaj Kondratek @mkondratek,
Michał Piotrowski @mpiotrowski
Agenda
- Motivations
- Make things easier for reviewers: keep PRs small
- Make looking for the origin of changes easier: keep history linear
- Make VCS hassle-free: provide repo's bird's eye view + automate
- Git Machete IntelliJ Plugin
- How to install
- Status
- Edit .git/machete
- Rebase, push (force), pull, fast-forward
- Discover
- Slide-in, slide-out
-
Git Machete CLI
- git machete discover/status/traverse
Big PRs suck
Big PRs suck
Reviewers are unwilling to even begin the review
Reviewers are more likely to skip vital parts of the newly-added code
It's hard/impossible to keep entire context in memory during review
Big PRs suck
Especially wrong:
Mixing refactors, features and bugfixes in a single pull request
E.g. 80% changes in a PR are refactors but 20% are bugfix- or feature-related... mixed in between the refactor changes
Small PRs rock
Reviewers are more willing to begin the review
Reviewers are less likely to skip vital parts of the newly-added code
It's much easier to keep the entire context in memory during the review
Small PRs rock
Good practice: calling branches:
- feature/...
- refactor/...
- bugfix/...
- chore/...
Small PRs rock
Side effect: you'll end up with:
- more branches in general
- stacked PRs (feature/foo → bugfix/bar → develop)
Spoiler: there are tools to handle that ;)
Tangled history (kinda) sucks
Tangled history (kinda) sucks
Not really that much important in day-to-day work...
who cares about git history
Until it starts!
Usually already months into production deployment
Linear history (kinda) rocks
Linear history starts getting pretty important
when we actually do care:
- git revert: make new commit that undoes some existing commit(s)
- git bisect: binary search for the first offending commit
- generally: easily finding origin of code that introduced some issues and reverting those changes is waaay easier if you have linear history
Hotfixes: okay to use merge
Hotfixes: okay to use merge
What to do after applying the hotfix changes onto master?
Merge the hotfixed master into develop.
Alternative: rebase develop's history onto the hotfixed master?
NOPE! Doing so would desync commits recorded in merged PRs on GitHub (Bitbucket etc.) from the actual develop's history
Viewing repo state
piece by piece sucks
Collecting various pieces of data from git log, git branch, git status?
Viewing repo state
in one go rocks
This point applies to many other tools...
having a single dashboard with the overall big picture is better
than collecting pieces around multiple GUI panels/CLI commands
Example: Kubernetes Dashboard vs kubectl
Doing repeatable operations manually sucks
Automating repeatable operations rocks
If only there was a tool that:
- helps keep branches up to date even if (side effects of small PRs):
- there many of them
- they're occasionally stacked on one another
- promotes linear history but without strictly enforcing it in every case
- gives a bird's eye view of the repo
- automates common flows...
Git Machete Intellij Plugin
A complement of IntelliJ's VCS tool window
GitHub: VirtusLab/git-machete-intellij-plugin
(git logo... cut into half)
How to install
File Settings Plugins Git Machete
Where to find this plugin
Git tool window (Alt+9) 🡒 Git Machete tab
Where to find this plugin
... or just Ctrl+Alt+Shift+M
Git Machete status
Sync to parent status (edge color)
Branch name
Custom annotation
Sync to remote status
Git Machete status
Commits uniquely belonging to the branch
Sync to parent status
Green edge
- everything is fine: child branch is in-sync with its parent (every commit belonging to the parent, belongs also to the child branch)
Red edge
- rebase required: the child branch is out-of-sync with its parent (there are commits that belong to the parent but not to the child - branches are diverged)
Gray edge
- branch was merged: the tip of the child branch belongs to the history of the parent branch - is available from the parent branch
Custom annotation
Short text that describes the branch - a kind of comment. It can be anything (e.g. PR number).
Sync to remote status
untracked
- branch has no remote tracking branch set up
ahead of
- branch has a commit(s) not present on the remote
behind
- remote has a commit(s) not present in the local branch
Sync to remote status
diverged from
both remote and local branch have a commit(s) not present in the other branch
-
diverged from & older than
special case of "diverged from": the latest commit on the local branch is older than the latest commit on the remote branch
-
Lights... Camera... Actions!
Wait, git-machete guesses what branches to list... automagically?!
And what if I still want to change it?
Everything is kept in single plain text file with ultra-minimal syntax!
.git/machete
Lights... Camera... Actions!
Demo sub-agenda:
- Edit .git/machete
- Rebase, push (force), pull, fast-forward
- Discover
- Slide-in, slide-out
Fast-forward
In gitspeak, to fast-forward a branch means to update the branch pointer in such a way that its new pointed commit is a direct descendant of the prior pointed commit.
In other words, the new commit is a child, or grandchild, or grandgrandchild, ... of the old commit.
For CLI lovers! git-machete
For CLI lovers! git-machete
Installable via:
- pip (Python, OS-independent)
- brew (Mac OS)
- apt-get (Debian, Ubuntu, ...)
- snap (most Linuxes)
- AUR manager (Arch Linux)
- ...and others
For CLI lovers! git-machete
Fun fact: just put git-X executable on PATH,
and `git X` will become available - easiest plugin system ever
For CLI lovers! git-machete
Usually enough to use just the 3 subcommands:
git machete discover git machete status git machete traverse
Questions!
Introducing Git Machete
By plipski
Introducing Git Machete
- 10,642