123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 |
- <!doctype html><!-- This is a valid HTML5 document. -->
- <!-- Screen readers, SEO, extensions and so on. -->
- <html lang="fr">
- <!-- Has to be within the first 1024 bytes, hence before the `title` element
- See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
- <meta charset="utf-8">
- <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
- <!-- The viewport meta is quite crowded and we are responsible for that.
- See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
- <meta name="viewport" content="width=device-width,initial-scale=1">
- <!-- Required to make a valid HTML5 document. -->
- <title>The advantages of an email-driven git workflow (archive) — David Larlet</title>
- <meta name="description" content="Publication mise en cache pour en conserver une trace.">
- <!-- That good ol' feed, subscribe :). -->
- <link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
- <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
- <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
- <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
- <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
- <link rel="manifest" href="/static/david/icons2/site.webmanifest">
- <link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
- <link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
- <meta name="msapplication-TileColor" content="#f7f7f7">
- <meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
- <meta name="theme-color" content="#f7f7f7" media="(prefers-color-scheme: light)">
- <meta name="theme-color" content="#272727" media="(prefers-color-scheme: dark)">
- <!-- Documented, feel free to shoot an email. -->
- <link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
- <!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
- <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
- <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
- <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
- <link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
- <link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
- <link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
- <script>
- function toggleTheme(themeName) {
- document.documentElement.classList.toggle(
- 'forced-dark',
- themeName === 'dark'
- )
- document.documentElement.classList.toggle(
- 'forced-light',
- themeName === 'light'
- )
- }
- const selectedTheme = localStorage.getItem('theme')
- if (selectedTheme !== 'undefined') {
- toggleTheme(selectedTheme)
- }
- </script>
-
- <meta name="robots" content="noindex, nofollow">
- <meta content="origin-when-cross-origin" name="referrer">
- <!-- Canonical URL for SEO purposes -->
- <link rel="canonical" href="https://drewdevault.com/2018/07/02/Email-driven-git.html">
-
- <body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all">
-
-
- <article>
- <header>
- <h1>The advantages of an email-driven git workflow</h1>
- </header>
- <nav>
- <p class="center">
- <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
- <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
- </svg> Accueil</a> •
- <a href="https://drewdevault.com/2018/07/02/Email-driven-git.html" title="Lien vers le contenu original">Source originale</a>
- </p>
- </nav>
- <hr>
- <p><a href="https://raw.githubusercontent.com/git/git/master/Documentation/RelNotes/2.18.0.txt">git 2.18.0</a> has been released, and with it my first contribution to
- git has shipped! My patch was for a git feature which remains disappointingly
- obscure: <a href="https://git-scm.com/docs/git-send-email">git send-email</a>. 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.</p>
- <p>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.</p>
- <p>Git has several built-in tools for leveraging email. The first one of note is
- <a href="https://git-scm.com/docs/git-format-patch">format-patch</a>. 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:</p>
- <pre><code class="language-mail" data-lang="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
-
- </code></pre>
- <p>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.</p>
- <p><img src="https://sr.ht/wmKv.jpg"></p>
- <p>
- <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>
- <p>I recommend a few settings to apply to git send-email to make your workflow a
- bit easier. One is <code>git config --global sendemail.verify off</code>, 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.</p>
- <p>You can also set the default recipient for a given repository by using a local
- git config: <code>git config sendemail.to admin@example.org</code>. 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 <code>git config --global sendemail.annotate yes</code>,
- which will always open the emails in your editor to allow you to make changes
- (you can get this with <code>--annotate</code> if you don’t want it every time).</p>
- <p>The main edit you’ll want to make when annotating is to provide what some call
- “timely commentary” on your patch. Immediately following the <code>---</code> 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 <code>[PATCH]</code> text in the subject line to
- something like <code>[PATCH v2]</code> - this can also be done with the <code>-v</code> flag as well.
- I also like to add additional To’s, Cc’s, etc at this time.</p>
- <p>Git also provides tools for the recipient of your messages. One such tool is
- <a href="https://git-scm.com/docs/git-am">git am</a>, 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 <a href="http://www.mutt.org/">mutt</a>, 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 <code>|</code> key, which prompts you for a command to pipe the
- email into. Other tools like <a href="http://www.offlineimap.org/">OfflineIMAP</a> are also
- useful here.</p>
- <p>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
- <a href="https://en.wikipedia.org/wiki/Posting_style#Top-posting">top post</a> 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 <a href="https://en.wikipedia.org/wiki/Posting_style#Bottom-posting">bottom posting</a>. I
- strongly encourage you to get comfortable doing this in general, but it’s
- essential when reviewing patches received over email.</p>
- <p>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:</p>
- <pre><code class="language-mail" data-lang="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
- </code></pre>
- <p>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 <code>-%<-</code> symbols indicating where I had
- trimmed out parts of the patch. This approach is common and effective.</p>
- <p>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.</p>
- <p>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, <a href="https://sr.ht">sr.ht</a>, 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.</p>
- <p>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 <a href="https://emersion.fr">Simon</a> has been helping out with a Python module
- named <a href="https://git.sr.ht/~emersion/python-emailthreads/">emailthreads</a> 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? <a href="mailto:sir@cmpwn.com">Email me</a>). Of course,
- it’s all <a href="https://git.sr.ht/~sircmpwn/?search=sr.ht">open source</a>, so you can
- follow along and try it on your own infrastructure if you like.</p>
- <p>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.</p>
- <p>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!</p>
- <hr>
- <p>Related articles sent in by readers:</p>
- <p><a href="https://begriffs.com/posts/2018-06-05-mailing-list-vs-github.html">Mailing lists vs Github</a>
- by Joe Nelson</p>
- <p><a href="https://web.archive.org/web/20180522180815/https://dpc.pw/blog/2017/08/youre-using-git-wrong/">You’re using git wrong</a> by
- Dawid Ciężarkiewicz</p>
- </article>
-
-
- <hr>
-
- <footer>
- <p>
- <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
- <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
- </svg> Accueil</a> •
- <a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2">
- <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-rss2"></use>
- </svg> Suivre</a> •
- <a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie">
- <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-user-tie"></use>
- </svg> Pro</a> •
- <a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail">
- <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-mail"></use>
- </svg> Email</a> •
- <abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2">
- <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-hammer2"></use>
- </svg> Légal</abbr>
- </p>
- <template id="theme-selector">
- <form>
- <fieldset>
- <legend><svg class="icon icon-brightness-contrast">
- <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-brightness-contrast"></use>
- </svg> Thème</legend>
- <label>
- <input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
- </label>
- <label>
- <input type="radio" value="dark" name="chosen-color-scheme"> Foncé
- </label>
- <label>
- <input type="radio" value="light" name="chosen-color-scheme"> Clair
- </label>
- </fieldset>
- </form>
- </template>
- </footer>
- <script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
- <script>
- function loadThemeForm(templateName) {
- const themeSelectorTemplate = document.querySelector(templateName)
- const form = themeSelectorTemplate.content.firstElementChild
- themeSelectorTemplate.replaceWith(form)
-
- form.addEventListener('change', (e) => {
- const chosenColorScheme = e.target.value
- localStorage.setItem('theme', chosenColorScheme)
- toggleTheme(chosenColorScheme)
- })
-
- const selectedTheme = localStorage.getItem('theme')
- if (selectedTheme && selectedTheme !== 'undefined') {
- form.querySelector(`[value="${selectedTheme}"]`).checked = true
- }
- }
-
- const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
- window.addEventListener('load', () => {
- let hasDarkRules = false
- for (const styleSheet of Array.from(document.styleSheets)) {
- let mediaRules = []
- for (const cssRule of styleSheet.cssRules) {
- if (cssRule.type !== CSSRule.MEDIA_RULE) {
- continue
- }
- // WARNING: Safari does not have/supports `conditionText`.
- if (cssRule.conditionText) {
- if (cssRule.conditionText !== prefersColorSchemeDark) {
- continue
- }
- } else {
- if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
- continue
- }
- }
- mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
- }
-
- // WARNING: do not try to insert a Rule to a styleSheet you are
- // currently iterating on, otherwise the browser will be stuck
- // in a infinite loop…
- for (const mediaRule of mediaRules) {
- styleSheet.insertRule(mediaRule.cssText)
- hasDarkRules = true
- }
- }
- if (hasDarkRules) {
- loadThemeForm('#theme-selector')
- }
- })
- </script>
- </body>
- </html>
|