format-patch + sendmail in one. Still the kernel's workflow.
Mails patches generated by format-patch through SMTP, threaded as a reply chain. Still the canonical workflow for the Linux kernel and many other mailing-list projects.
Think of it as 'format-patch | sendmail' with proper threading and per-patch In-Reply-To headers wired up automatically. You point it at .patch files (or a revision range) and it sends them as a series.
git send-email [<options>] <file|directory|rev-list-options>
Common flow:
git format-patch -M origin/main -o outgoing/ --cover-letter
$EDITOR outgoing/0000-cover-letter.patch
git send-email --to=list@example.org outgoing/*.patch| Flag | What it does |
|---|---|
--to=<addr> | Primary recipient. Repeatable. |
--cc=<addr> | Cc recipient. Repeatable. Often auto-filled from Cc: trailers in patches. |
--bcc=<addr> | Bcc recipient. Repeatable. |
--in-reply-to=<msgid> | Make the series a reply to an existing message-id (e.g. v1 thread). |
--smtp-server=<host> | SMTP host (or sendmail binary path). Override sendemail.smtpServer. |
--smtp-user=<user>, --smtp-encryption=ssl|tls | Auth user and encryption. Pair with --smtp-pass or use a credential helper. |
--annotate | Open each patch in $EDITOR before sending (last-chance review). |
--cover-letter | When given a rev-range, generate and send a cover letter. |
--subject-prefix=<str> | Override [PATCH] with [PATCH v2], [RFC], etc. |
--no-thread | Send each patch as a standalone email, not threaded. |
--dry-run | ⚠️ Don't actually send; print what would happen. Use this first, every time. |
git send-email --dry-run --to=list@example.org outgoing/*.patchgit send-email --to=maintainer@kernel.org --cc=list@vger.kernel.org outgoing/*.patchgit send-email --in-reply-to='<20240101.123@example.org>' --subject-prefix='PATCH v2' outgoing/*.patchgit send-email --smtp-server=smtp.gmail.com --smtp-encryption=tls --smtp-user=me@gmail.com --to=list@example.org 0001-fix.patchHit each option, then Check answers. Score is recorded; Next is always open.