diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-07-02 07:34:06 -0400 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2018-07-02 07:34:06 -0400 |
commit | 2e0c9077c0569365ef30703df6ea0f8d8da679dc (patch) | |
tree | 47f18dbebf9ddcd2f7aec625afe410c907524e9c | |
parent | 837df1f199791dba6c93b65699d19ac8953ae432 (diff) |
Add email-driven git article
-rw-r--r-- | _layouts/page.html | 2 | ||||
-rw-r--r-- | _posts/2018-7-02-Email-driven-git.md | 217 | ||||
-rw-r--r-- | css/base.scss | 5 |
3 files changed, 223 insertions, 1 deletions
diff --git a/_layouts/page.html b/_layouts/page.html index 3abca1c..ce5da90 100644 --- a/_layouts/page.html +++ b/_layouts/page.html @@ -44,7 +44,7 @@ layout: base </p> <p> <i class="fa fa-lock"></i> - <a href="/publickey.txt">Public key: 7BC79407090047CA</a> + <a href="/publickey.txt">7BC79407090047CA</a> </p> {% if page.url != '/' %} <h3>Recent Posts</h3> diff --git a/_posts/2018-7-02-Email-driven-git.md b/_posts/2018-7-02-Email-driven-git.md new file mode 100644 index 0000000..157b64d --- /dev/null +++ b/_posts/2018-7-02-Email-driven-git.md @@ -0,0 +1,217 @@ +--- +title: The advantages of an email-driven git workflow +layout: post +--- + +[git 2.18.0][git 2.18.0] has been released, and with it my first contribution to +git has shipped! My patch was for a git feature which remains disappointingly +obscure: [git send-email](https://git-scm.com/docs/git-send-email). I want to +introduce my readers to this feature and speak to the benefits of using an +email-driven git workflow - the workflow git was originally designed for. + +[git 2.18.0]: https://raw.githubusercontent.com/git/git/master/Documentation/RelNotes/2.18.0.txt + +Email isn't as sexy as GitHub (and its imitators), but it has several +advantages over the latter. Email is standardized, federated, well-understood, +and venerable. A very large body of email-related software exists and is equally +reliable and well-understood. You can interact with email using only open source +software and customize your workflow at every level of the stack - filtering, +organizing, forwarding, replying, and so on; in any manner you choose. + +Git has several built-in tools for leveraging email. The first one of note is +[format-patch](https://git-scm.com/docs/git-format-patch). This can take a git +commit (or series of commits) and format them as plaintext emails with embedded +diffs. Here's a small example of its output: + +```mail +From 8f5045c871c3060ff5f5f99ce1ada09f4b4cd105 Mon Sep 17 00:00:00 2001 +From: Drew DeVault <sir@cmpwn.com> +Date: Wed, 2 May 2018 08:59:27 -0400 +Subject: [PATCH] Silently ignore touch_{motion,up} for unknown ids + +--- + types/wlr_seat.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/types/wlr_seat.c b/types/wlr_seat.c +index f77a492d..975746db 100644 +--- a/types/wlr_seat.c ++++ b/types/wlr_seat.c +@@ -1113,7 +1113,6 @@ void wlr_seat_touch_notify_up(struct wlr_seat *seat, uint32_t time, + struct wlr_seat_touch_grab *grab = seat->touch_state.grab; + struct wlr_touch_point *point = wlr_seat_touch_get_point(seat, touch_id); + if (!point) { +- wlr_log(L_ERROR, "got touch up for unknown touch point"); + return; + } + +@@ -1128,7 +1127,6 @@ void wlr_seat_touch_notify_motion(struct wlr_seat *seat, uint32_t time, + struct wlr_seat_touch_grab *grab = seat->touch_state.grab; + struct wlr_touch_point *point = wlr_seat_touch_get_point(seat, touch_id); + if (!point) { +- wlr_log(L_ERROR, "got touch motion for unknown touch point"); + return; + } + +-- +2.18.0 + +``` + +git format-patch is at the bottom of git's stack of outgoing email features. You +can send the emails it generates manually, but usually you'll use git send-email +instead. It logs into the SMTP server of your choice and sends the email for +you, after running git format-patch for you and giving you an opportunity to +make any edits you like. Given that most popular email clients these days are +awful and can't handle basic tasks like "sending email" properly, I strongly +recommend this tool over attempting to send format-patch's output yourself. + +<img style="max-width: 75%" src="https://sr.ht/wmKv.jpg" /> + +<p style="text-align: center; max-width: 80%; margin: 1rem auto"> + <em> + I put a notch in my keyboard for each person who ignores my advice, + struggles through sending emails manually, and eventually comes around + to letting git send-email do it for them. + </em> +</p> + +I recommend a few settings to apply to git send-email to make your workflow a +bit easier. One is `git config --global sendemail.verify off`, which turns off +a sometimes-annoying and always-confusing validation step which checks for +features only supported by newer SMTP servers - newer, in this case, meaning +more recent than November of 1995. I started a thread on the git mailing list +this week to discuss changing this option to off by default. + +You can also set the default recipient for a given repository by using a local +git config: `git config sendemail.to admin@example.org`. This lets you skip a +step if you send your patches to a consistent destination for that project, like +a mailing list. I also recommend `git config --global sendemail.annotate yes`, +which will always open the emails in your editor to allow you to make changes +(you can get this with `--annotate` if you don't want it every time). + +The main edit you'll want to make when annotating is to provide what some call +"timely commentary" on your patch. Immediately following the `---` after your +commit message, you can add a summary of your changes which can be seen by the +recipient, but doesn't appear in the final commit log. This is a useful place to +talk about anything useful regarding the testing, review, or integration of your +changes. You may also want to edit the `[PATCH]` text in the subject line to +something like `[PATCH v2]` - this can also be done with the `-v` flag as well. +I also like to add additional To's, Cc's, etc at this time. + +Git also provides tools for the recipient of your messages. One such tool is +[git am](https://git-scm.com/docs/git-am), which accepts an email prepared with +format-patch and integrates it into their repository. Several flags are provided +to assist with common integration activities, like signing off on the commit or +attempting a 3-way merge. The difficult part can be getting the email to git am +in the first place. If you simply use the GMail web UI, this can be difficult. I +use [mutt](http://www.mutt.org/), a TUI email client, to manage incoming +patches. This is useful for being able to compose replies with vim rather than +fighting some other mail client to write emails the way I want, but more +importantly it has the `|` key, which prompts you for a command to pipe the +email into. Other tools like [OfflineIMAP](http://www.offlineimap.org/) are also +useful here. + +On the subject of composing replies, reviewing patches is quite easy with the +email approach as well. Many bad, yet sadly popular email clients have +popularized the idea that the sender's message is immutable, encouraging you to +[top post][top posting] and leave an endlessly growing chain of replies +underneath your message. A secret these email clients have kept from you is that +you are, in fact, permitted by the mail RFCs to edit the sender's message as you +please when replying - a style called [bottom posting][bottom posting]. I +strongly encourage you to get comfortable doing this in general, but it's +essential when reviewing patches received over email. + +[top posting]: https://en.wikipedia.org/wiki/Posting_style#Top-posting +[bottom posting]: https://en.wikipedia.org/wiki/Posting_style#Bottom-posting + +In this manner, you can dissect the patch and respond to specific parts of it +requesting changes or clarifications. It's just email - you can reply, forward +the message, Cc interested parties, start several chains of discussion, and so +on. I recently sent the following feedback on a patch I received: + +```mail +Date: Mon, 11 Jun 2018 14:19:22 -0400 +From: Drew DeVault <sir@cmpwn.com> +To: Gregory Mullen <omitted> +Subject: Re: [PATCH 2/3 todo] Filter private events from events feed + +On 2018-06-11 9:14 AM, Gregory Mullen wrote: +> diff --git a/todosrht/alembic/versions/cb9732f3364c_clear_defaults_from_tickets_to_support_.py b/todosrht/alembic/versions/cb9732f3364c_clear_defaults_from_tickets_to_support_.py +> -%<- +> +class FlagType(types.TypeDecorator): + +I think you can safely import the srht FlagType here without implicating +the entire sr.ht database support code + +> diff --git a/todosrht/blueprints/html.py b/todosrht/blueprints/html.py +> -%<- +> +def collect_events(target, count): +> + events = [] +> + for e in EventNotification.query.filter(EventNotification.user_id == target.id).order_by(EventNotification.created.desc()): + +80 cols + +I suspect this 'collect_events' function can be done entirely in SQL +without having to process permissions in Python and do several SQL +round-trips + +> @html.route("/~<username>") +> def user_GET(username): +> - print(username) + +Whoops! Nice catch. + +> user = User.query.filter(User.username == username.lower()).first() +> if not user: +> abort(404) +> trackers, _ = get_tracker(username, None) +> # TODO: only show public events (or events the current user can see) + +Can remove the comment +``` + +Obviously this isn't the whole patch we're seeing - I've edited it down to just +the parts I want to talk about. I also chose to leave the file names in to aid +in navigating my feedback, with casual `-%<-` symbols indicating where I had +trimmed out parts of the patch. This approach is common and effective. + +The main disadvantage of email driven development is that some people are more +comfortable working with email in clients which are not well-suited to this kind +of work. Popular email clients have caused terrible ideas like HTML email to +proliferate, not only enabling spam, privacy leaks, and security +vulnerabilities, but also making it more difficult for people to write emails +that can be understood by git or tolerated by advanced email users. + +I don't think that the solution to these problems is to leave these powerful +tools hanging in the wind and move to less powerful models like GitHub's pull +requests. This is why on my own platform, [sr.ht](https://sr.ht), I chose to +embrace git's email-driven approach, and extend it with new tools that make it +easier to participate without directly using email. For those like me, I still +want the email to be there so you can dig my heels in and do it old-school, but +I appreciate that it's not for everyone. + +I started working on the sr.ht mailing list service a couple of weeks ago, which +is where these goals will be realized with new email-driven code review tools. +My friend [Simon](https://emersion.fr) has been helping out with a Python module +named [emailthreads](https://git.sr.ht/~emersion/python-emailthreads/) which can +be used to parse email discussions - with a surprising degree of accuracy, +considering the flexibility of email. Once I get these tools into a usable +state, we'll likely see sr.ht registrations finally opened to the general public +(interested in trying it earlier? [Email me](mailto:sir@cmpwn.com)). Of course, +it's all [open source](https://git.sr.ht/~sircmpwn/?search=sr.ht), so you can +follow along and try it on your own infrastructure if you like. + +Using email for git scales extremely well. The canonical project, of course, is +the Linux kernel. A change is made to the Linux kernel an average of 7 times per +hour, constantly. It is maintained by dozens of veritable clans of software +engineers hacking on dozens of modules, and email allows these changes to +efficiently flow code throughout the system. Without email, Linux's maintenance +model would be impossible. It's worth noting that git was designed for +maintaining Linux, of course. + +With the right setup, it's well suited to small projects as well. Sending a +patch along for review is a single git command. It lands directly in the +maintainer's inbox and can be integrated with a handful of keystrokes. All of +this works without any centralization or proprietary software involved. We +should embrace this! diff --git a/css/base.scss b/css/base.scss index d3078d1..f92db01 100644 --- a/css/base.scss +++ b/css/base.scss @@ -109,6 +109,11 @@ blockquote { padding-top: 20px; } +.sidebar .fa { + width: 18px; + text-align: center; +} + .sidebar, .sidebar a { color: #444; } |