logo

drewdevault.com

[mirror] blog and personal website of Drew DeVault git clone https://hacktivis.me/git/mirror/drewdevault.com.git

Code-review-with-aerc.md (7021B)


  1. ---
  2. title: Code review at the speed of email
  3. date: 2022-07-25
  4. ---
  5. I'm a big proponent of the email workflow for patch submission and code review.
  6. I have previously published some content ([How to use git.sr.ht's send-email
  7. feature][0], [Forks & pull requests vs email][1], [git-send-email.io][2]) which
  8. demonstrates the contributor side of this workflow, but it's nice to illustrate
  9. the advantages of the maintainer workflow as well. For this purpose, I've
  10. recorded a short video demonstrating how I manage code review as an
  11. email-oriented maintainer.
  12. *Disclaimer: I am the founder of [SourceHut][3], a platform built on this
  13. workflow which competes with platforms like GitHub and GitLab. This article's
  14. perspective is biased.*
  15. [0]: https://spacepub.space/w/no6jnhHeUrt2E5ST168tRL
  16. [1]: https://spacepub.space/w/3JhBcvEYbminv8ji4k84gx
  17. [2]: https://git-send-email.io
  18. [3]: https://sourcehut.org
  19. <iframe title="Code review at the speed of email" src="https://spacepub.space/videos/embed/385c414a-2bdc-4bf3-82a0-76fcb15093e9" allowfullscreen="" sandbox="allow-same-origin allow-scripts allow-popups" width="560" height="315" frameborder="0"></iframe>
  20. <p class="text-center">
  21. <em>
  22. This blog post provides additional material to supplement this video, and also
  23. includes all of the information from the video itself. For those who prefer
  24. reading over watching, you can just stick to reading this blog post. Or, you
  25. can watch the video and skim the post. Or you can just do something else! When
  26. was the last time you called your grandmother?
  27. </em>
  28. </p>
  29. With hundreds of hours of review experience on GitHub, GitLab, and SourceHut, I
  30. can say with confidence the email workflow allows me to work much faster than
  31. any of the others. I can review small patches in seconds, work quickly with
  32. multiple git repositories, easily test changes and make tweaks as necessary,
  33. rebase often, and quickly chop up and provide feedback for larger patches.
  34. Working my way through a 50-email patch queue usually takes me about 20 minutes,
  35. compared to an hour or more for the same number of merge requests.
  36. This workflow also works entirely offline. I can read and apply changes locally,
  37. and even reply with feedback or to thank contributors for their patch. My mail
  38. setup automatically downloads mail from IMAP using [isync][4] and outgoing mails
  39. are queued with [postfix][5] until the network is ready. I have often worked
  40. through my patch queue on an airplane or a train with spotty or non-functional
  41. internet access without skipping a beat. Working from low-end devices like a
  42. Pinebook or a phone are also no problem &mdash; aerc is very lightweight in the
  43. terminal and the SourceHut web interface is [much lighter & faster][6] than any
  44. other web forge.
  45. [4]: https://isync.sourceforge.io/
  46. [5]: http://www.postfix.org/
  47. [6]: https://forgeperf.org
  48. The centerpiece of my setup is an email client I wrote specifically for software
  49. development using this workflow: [aerc][7].[^1] The stock configuration of aerc
  50. is pretty good, but I make a couple of useful additions specifically for
  51. development on SourceHut. Specifically, I add a few keybindings to
  52. `~/.config/aerc/binds.conf`:
  53. [7]: https://aerc-mail.org/
  54. [^1]: Don't want to switch from your current mail client? Tip: You can use more than one 🙂 I usually fire up multiple aerc instances in any case, one "main" instance and more ephemeral processes for working in specific projects. The startup time is essentially negligible, so this solution is very cheap and versatile.
  55. ```
  56. [messages]
  57. ga = :flag<Enter>:pipe -mb git am -3<Enter>
  58. gp = :term git push<Enter>
  59. gl = :term git log<Enter>
  60. rt = :reply -a -Tthanks<Enter>
  61. Rt = :reply -qa -Tquoted_thanks<Enter>
  62. [compose::review]
  63. V = :header -f X-Sourcehut-Patchset-Update NEEDS_REVISION<Enter>
  64. A = :header -f X-Sourcehut-Patchset-Update APPLIED<Enter>
  65. R = :header -f X-Sourcehut-Patchset-Update REJECTED<Enter>
  66. ```
  67. The first three commands, ga, gp, and gl, are for invoking git commands. "ga"
  68. applies the current email as a patch, using [git am][8], and "gp" simply runs
  69. git push. "gl" is useful for quickly reviewing the git log. ga also flags the
  70. email so that it shows up in the UI as having been applied, which is useful as
  71. I'm jumping all over a patch queue. I also make liberal use of \\ (:filter) to
  72. filter my messages to patches applicable to specific projects or goals.
  73. [8]: https://git-scm.com/docs/git-am
  74. rt and Rt use aerc templates installed at `~/.config/aerc/templates/` to reply
  75. to emails after I've finished reviewing them. The "thanks" template is:
  76. ```
  77. X-Sourcehut-Patchset-Update: APPLIED
  78. Thanks!
  79. {{exec "{ git remote get-url --push origin; git reflog -2 origin/master --pretty=format:%h | xargs printf '%s\n' | tac; } | xargs printf 'To %s\n %s..%s master -> master'" ""}}
  80. ```
  81. And quoted\_thanks is:
  82. ```
  83. X-Sourcehut-Patchset-Update: APPLIED
  84. Thanks!
  85. {{exec "{ git remote get-url --push origin; git reflog -2 origin/master --pretty=format:%h | xargs printf '%s\n' | tac; } | xargs printf 'To %s\n %s..%s master -> master'" ""}}
  86. On {{dateFormat (.OriginalDate | toLocal) "Mon Jan 2, 2006 at 3:04 PM MST"}}, {{(index .OriginalFrom 0).Name}} wrote:
  87. {{wrapText .OriginalText 72 | quote}}
  88. ```
  89. Both of these add a magic "X-Sourcehut-Patchset-Update" header, which updates
  90. the status of the patch on the mailing list. They also include a shell pipeline
  91. which adds some information about the last push from this repository, to help
  92. the recipient understand what happened to their patch. I often make some small
  93. edits to request the user follow-up with a ticket for some future work, or add
  94. other timely comments. The second template, quoted\_reply, is also particularly
  95. useful for this: it quotes the original message so I can reply to specific parts
  96. of it, in the commit message, timely commentary, or the code itself, often
  97. pointing out parts of the code that I made some small tweaks to before applying.
  98. And that's basically it! You can browse all of my dotfiles [here][9] to see more
  99. details about my system configuration. With this setup I am able to work my way
  100. through a patch queue easier and faster than ever before. That's why I like the
  101. email workflow so much: for power users, no alternative is even close in terms
  102. of efficiency.
  103. [9]: https://git.sr.ht/~sircmpwn/dotfiles
  104. Of course, this is the power user workflow, and it can be intimidating to learn
  105. all of these things. This is why we offer more novice-friendly tools, which lose
  106. some of the advantages but are often more intuitive. For instance, we are
  107. working on user interface on the web for patch review, mirroring our existing
  108. [web interface for patch submission][10]. But, in my opinion, it doesn't get
  109. better than this for serious FOSS maintainers.
  110. [10]: https://spacepub.space/w/no6jnhHeUrt2E5ST168tRL
  111. Feel free to reach out on IRC in #sr.ht.watercooler on Libera Chat, or [via
  112. email](mailto:sir@cmpwn.com), if you have any questions about this workflow and
  113. how you can apply it to your own projects. Happy hacking!