My Git & GitHub workflow - an efficient yet messy setup

I think my main goal with this blog post is to get help making sense and minimizing the amount of tools I'm using for Git and GitHub 🆘

There are all these great tools out there but there's always something missing, unnecessary friction or something that's possible but requires way too much effort.

Git is a complex tool that offers a lot and maybe to make sense of it we need a lot of tools.

The unix philosophy of having many tools where each does one thing and does it well could work here, but I find that many of the tools I use overlap. I have to keep using all of them as each one has an esoteric and specialized use-case.

Maybe some reader can help me make sense of this jungle of tools and simplify it.

TLDR; List of the Tools I'm Using

  • git aliases
  • lazygit - my main workflow of adding and comitting changes
  • tig - for viewing git log across different branches more easily
  • Graphite - to work with stacked PRs
  • gh-dash - to easily view PRs/Issues from repos I care about
  • Neovim plugins
    • advanced-git-search.nvim - to browse a file's history and search the log
    • diffview.nvim - to solve merge conflicts, compare branches inside neovim etc.
    • gh-addressed.nvim - to go over my PR's comments and fix them
    • gh-blame.nvim - to show me the PR that changed the current line
    • gitlinker - to copy links to GitHub of the current file
    • gitsigns - for working with git hunks (reverting, committing etc), inline git blame,
    • octo.nvim - for reviewing PRs
    • [vim-fugitive] - mainly for git blame
  • Raycast - to search code on GitHub (a shortcut to open https://github.com/search?type=code&q=""$1"
  • fish abbreviations and functions

All of these tools configurations can be found in my dotfiles repo.

I'm just going to list how I use each tool now :)

The Git CLI

For my full git config check it out on GitHub

Lazygit

My main workflow revolves around using lazygit.

I have it bound to CMD+G in tmux so that I can always globally open it, quickly add files by hitting a and commiting them with c.

lazygit|700

Tig

I often find myself needing to see how different branches relate to each other and for that I use tig.

It helped me tremendously when at a previous company I wanted to migrate away from poly-repos into one big monorepo. The migration was made possible in part by utilizing tig to make sure the git history was kept intact.

There's probably a lot more to tig that I'm not utilizing.

Stacked PRs with Graphite

I really love working with stacked PRs.

That's the methodology I used when working in Facebook. It has some really great benefits like staying unblocked by not waiting for a review and helps with writing smaller PRs.

For a while I've been using Graphite to work like this. Graphite has a great blog article about it if you want to learn more.

After I started my new role at Komodor I found this doesn't work well under the SOC2 compliance framework.

This framework basically assures potential customers that they're buying into a serious company that follows the best security guidelines and won't leak their data etc.

Unfortunately, this also means worse developer experience. One of the rules is that a PR must always be approved and that each new commit dismisses old approvals, requiring it to be stamped again.

That meant I could no longer use Graphite to split my PRs as it uses force pushes. These force pushes dismiss any approval I had. These were mainly happening when I rebased a stack on top of main, without any real changes being made.

I still find myself using Graphite' though for quickly checking out branches with an FZF-like interface: ![[gco.gif|800]]

gh-dash

I use gh-dash to easily view PRs/Issues from repos I care about.

I really don't like GitHub's https://github.com/pulls page. It barely gives me the info I need, so I wrote gh-dash to solve that issue.

As with lazygit I have gh-dash bound to CMD+Shift+G in tmux so I can globally get to it (see my tmux config)

With it:

  • I can quickly go between viewing my work related PRs, my personal projects etc.
  • I set up the C hotkey to quickly review a PR in neovim
  • I often use the w hotkey to watch a PRs status checks and notify me when they're done

What I'd like to add:

  • A richer view for a PR - similar to the full page on GitHub.
  • A way to approve PRs - should be easy
  • The ability to quickly toggle is:archived on off

gh-dash image

Neovim Setup

  • diffview.nvim - to solve merge conflicts, compare branches inside neovim etc.
  • gh-blame.nvim - to show me the PR that changed the current line !
  • gitlinker - to copy links to GitHub of the current file. I used this extensively in writing this blog post for linking to my code.
  • gitsigns - for working with git hunks (reverting, committing etc), inline git blame
  • octo.nvim - for reviewing PRs. Leaving comments straight in Neovim is magical|700
  • vim-fugitive - mainly for git blame. I wish something like this existed but for GitHub blame. I often find PRs to be a lot richer with information about the change.

Raycast

I use Raycast to search code on GitHub (a shortcut to open https://github.com/search?type=code&q=""$1")

Racast is pretty awesome.

What I'm Still Missing

  • Moaarrrr tools that replace the use of Github.com. I truly dislike their slow page loads.
    • GitHub blame in neovim pls
    • Github code search in nvim pretty pls
    • In general, I wonder what will happen if sites were ported natively to the terminal
  • lazygit in rust (I'm missing like 200ms off the startup time)
  • A way to search git commit diffs for a string in neovim

Recap

These are a lot, yet I remember to use each one when I need it.

  • Did I forget something you're using?
  • Are there simpler/more powerful ways to do the same stuff?
  • Am I mad for using all of these tools? 🫠