Introducing Git Machete

by Paweł Lipski @plipski,
Mikołaj Kondratek @mkondratek,
Michał Piotrowski @mpiotrowski

Agenda

  1. Motivations
    1. Make things easier for reviewers: keep PRs small
    2. Make looking for the origin of changes easier: keep history linear
    3. Make VCS hassle-free: provide repo's bird's eye view + automate
  2. ​Git Machete IntelliJ Plugin
    1. How to install
    2. Status
    3. Edit .git/machete
    4. Rebase, push (force), pull, fast-forward
    5. Discover
    6. Slide-in, slide-out
  3. Git Machete CLI
    1. 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:

  1. Edit .git/machete
  2. Rebase, push (force), pull, fast-forward
  3. Discover
  4. 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!

Made with Slides.com