aboutsummaryrefslogtreecommitdiffstats
path: root/git.sr.ht/send-email.md
blob: 68097118a1f8a2fc59ee8100d88bf453c9eb7d1d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
sr.ht leverages git's built-in collaboration tools for contributing to projects
hosted here. This guide will help you get started. If you run into any trouble,
please send an email to the [sr.ht-discuss][sr.ht-discuss] mailing list for
help.

[sr.ht-discuss]: https://lists.sr.ht/~sircmpwn/sr.ht-discuss

**Golden rule**: Do not copy-paste the output of git format-patch into your
typical mail client.

# For everyone

Before you dig too far into this guide, you should make sure that your email
client is configured to use plain text emails. By default, many email clients
compose emails with HTML, so you can use rich text formatting. Rich text is not
desirable for development-oriented email conversations, so you should disable
this feature and send your email as "plain text". Every email client is
different, you should research the options for your specific client. HTML emails
are rejected by all sr.ht services.

For real-world examples of how the discussions described in this document play
out, check out the [sr.ht-dev][sr.ht-dev] mailing list.

[sr.ht-dev]: https://lists.sr.ht/~sircmpwn/sr.ht-dev

Unsure if your setup is correct? Try sending the patch to sir@cmpwn.com for
feedback first - make sure you mention in the email that you want feedback.

# For contributors

## Preparing your changes

There's no need to "fork" the repository you want to contribute to - simply use
[`git clone`][git-clone] to obtain a local copy of the git repository and [work
normally][work-normally]. Be deliberate about your commits - use meaningful
commit messages and take special care to commit your work in the form of
logically separate changes. When it comes time to review your work, your commit
history is an important tool for the reviewer and will be closely examined.

[git-clone]: https://www.git-scm.com/docs/git-clone
[work-normally]: https://www.git-scm.com/book/en/v2

## Find out where to send your changes

This workflow is optional for projects hosted on sr.ht and each project will
have different requirements - review them carefully. To use this guide, you need
to find an email address to send your work to - this will often be a mailing
list on [lists.sr.ht](/lists.sr.ht). You will also want to find people who can
help review your changes - look for dedicated maintainers for the modules you're
working on, or use [`git blame`][git-blame] to find people who have recently
worked on similar code.

[git-blame]: https://www.git-scm.com/docs/git-blame

## Configure git send-email

When you've collected a list of email addresses to send your work to, we can use
[`git send-email`][git-send-email] to do the job. Its purpose is to convert your
git commits into emails with [`git format-patch`][git-format-patch] and connect
to your mail server to deliver them with SMTP.

[git-send-email]: https://www.git-scm.com/docs/git-send-email
[git-format-patch]: https://www.git-scm.com/docs/git-send-email

If you've never used git send-email before, you will need to do some one-time
setup to introduce it to your SMTP server. The connection details vary between
mail providers, but you're looking for information which is suitable for filling
out these config fields in `~/.config/git/config`:

    [sendemail]
        smtpencryption = tls
        smtpserver = mail.example.org
        smtpuser = you@example.org
        smtpserverport = 587

**Note**: G-Mail users have to take some extra steps, which are documented
[here][gmail].

[gmail]: https://www.git-scm.com/docs/git-send-email#_use_gmail_as_the_smtp_server

**Note**: Protonmail users are advised to use
[Hydroxide](https://github.com/emersion/hydroxide) to extend Protonmail with
SMTP support, and to choose mail services which support standard, open protocols
in the future.

You can also set your SMTP password as `sendemail.smtppass`. If you don't, you
will be prompted for it when it's needed. You can also configure git to use your
local keyring; consult [`git credential`][git-credential] for details.

[git-credential]: https://www.git-scm.com/docs/git-credential

## Send the patches along

When you've configured `git send-email`, completed your work, and you're ready
to send your patches in, you can run `git send-email --annotate [rev-spec...]`.
The `rev-spec` is the same as any other [revision specification][rev-spec], and
send-email will prepare patches from that commit to the tip (unless you specify
`-1`, `-2`, etc, in which case it will prepare up to that many patches). If
you're in a hurry, here are a few quick examples:

- `HEAD^` just includes the last commit
- `HEAD~3` includes the last three commits
- `origin/master` includes all commits since diverging from `origin/master`
- `0fdbc0da` only includes commit `0fdbc0da` when specified with `-1`
- `0fdbc0da` includes commit `0fdbc0da` and the 2 commits prior when specified
  with `-3`

[rev-spec]: https://www.git-scm.com/docs/gitrevisions

The `--annotate` flag will open the emails in your text editor before sending
them out. You should take a moment to review these. The subject line and
everything above the `---` are your commit message, and everything below the
`---` is the patch itself. Immediately following the `---`, you can add what
we call "timely commentary" - any information which is useful to the people
reviewing your patch, but doesn't necessarily belong in the final git history;
plus a blank line between this and the start of the patch. If you're sending a
few patches at once, you might also want to specify `--cover-letter`, which will
prepare an additional email summary to be sent first.

**Note**: When you're prompted for an "In-Reply-To" header, you can ignore it
for now.

## Using request-pull

For integrating large changesets, merging unrelated branches, or for maintainers
who prefer this workflow, you may want to use a "pull request". To use this
workflow you will need to have somewhere public to host your modified copy of
the git repository, like git.sr.ht. If you already have the upstream repository
cloned locally, take these steps to push your changes to your own git.sr.ht
repository:

    git remote rename origin upstream
    git remote add origin git@git.sr.ht:~yourname/some-project
    git push -u origin master

Click the link to confirm the creation of your repository. Take care to update
the URL provided to `git remote`. Then generate the pull request:

    git request-pull -p [rev-spec...] origin

You can copy-paste the output into your email client (remember to ensure you are
not sending HTML email) and add any timely commentary in front.

## Handling feedback

You will likely receive replies to your email with feedback on your changes.
This is normal! Use tools like [`git commit --amend`][amend] and [`git
rebase`][git-rebase] to continue improving your patch set and iterating on
feedback (tip: check out our [rebase guide](rebase.md)). When you're ready to
submit the next version of your patches, use `git send-email` normally, except:

- Add `-v2` to indicate that this is version 2 of your patch (or whatever number
  is appropriate).
- When prompted to fill out `In-Reply-To`, paste in the message ID of the last
  email in the thread. On lists.sr.ht you can get this by clicking "details" on
  the email in question. If you can't find this, don't sweat it, it's no big
  deal.

[amend]: https://www.git-scm.com/docs/git-commit#git-commit---amend
[git-rebase]: https://www.git-scm.com/docs/git-rebase

## Pulling from upstream

As you continue to work, you may want to pull from the upstream, and you
almost certainly don't want to create a merge commit when you have WIP or
unmerged patches in your history. To this end, you should generally use `git
pull --rebase` to fetch the latest changes from upstream.

If you get a conflict, read the information git prints. You have two choices -
skip the patch or fix it. If your patch has already been merged, the maintainer
likely made some minor changes that prevents git from detecting it's the same
commit you have locally - in this case, just `git rebase --skip` the patch. If
your patch still hasn't been merged upstream, you should resolve the conflicts
in your editor, using `git add some/file.c` to mark the conflicts as resolved,
and then using `git rebase --continue` to move on. You will probably want to
send a `-v2` patch upstream when you're done - any conflicts you resolved, your
maintainer will have to address, too. Save them the time!

## Extra tips

Here are a few extra tricks you might find useful with `git send-email`.

### Sending emails to the same address every time

If you send emails for a project to the same mailing list every time, you might
find it useful to set the default To address. Run this command from that
repository:

    git config sendemail.to patches@example.org

### Specifying a subproject for shared lists

Some projects have several repositories being discussed on a single mailing
list, and it's often helpful to specify the particular repository your patch
pertains to.

If you're just doing this once, add `--subject-prefix` to `git send-email`, like
so:

    git send-email --subject-prefix='PATCH example' HEAD^

You can also specify this as the default for that git repository:

    git config format.subjectPrefix 'PATCH example'

### Signing off on your commits

If you're asked by a project to "sign off" on your commits, add `--signoff` (or
`-s`) to `git send-email`. To set it as the default for that git repository:

    git config format.signOff yes

### Using --annotate every time

    git config --global sendemail.annotate yes

# For maintainers

## Tell people how to contribute

The first thing you need to do is help potential contributors figure out how to
contact you. The easiest way is to do nothing - git records your email with
every commit, so someone with a copy of your git repository can figure out how
to contact you. You'll probably want to make it a bit easier on them, though.

We recommend setting up a mailing list on [lists.sr.ht](/lists.sr.ht) for this
purpose. Once you do, you will get an email address for contributors to submit
patches to. Write this into your docs! You will probably also want to link to
the archives so that potential contributors can read other people's work to get
a feel for your submission process.

## Reviewing patches

When a patch comes in, you should review it carefully. Read the code, apply the
patch locally and make sure it compiles, test the changes, and so on. During
this process you'll probably come up with feedback on the patch. Pull open that
email client and compose a reply to the patch author. When your client composes
the reply, don't be afraid to slice and dice the email you're replying to - trim
out the fat and only include specific lines that you want to comment on.

If you only have small comments here and there, feel free to make the changes
yourself, again utilizing [`git commit --amend`][amend] and [`git
rebase`][git-rebase] to your heart's content. You may be wise to point out these
small errors when you thank the submitter for their patch, however, if you don't
want to see the same errors in future patches.

## Applying patches

In order to integrate the changes, you need to *apply* the patch. The tool for
this is [`git am`][git-am]. The difficult part here is going to be obtaining a
copy of the email to provide to `git am`. Some clients like [mutt][mutt] make
this easy (in mutt, you can use the `|` key to pipe an email directly to `git
am`), or tools like [offlineimap][offlineimap] can help (or a combination of the
two!). Most popular end-user clients do not provide this option. If you're in
this boat, the easiest way to get a raw email is to use the "raw" link on
lists.sr.ht, which is hidden away under the "details" button.

[git-am]: https://www.git-scm.com/docs/git-am
[mutt]: http://www.mutt.org
[offlineimap]: http://www.offlineimap.org/

If you copy the link to the raw email from lists.sr.ht, the command might look
like this:

    curl -s https://lists.sr.ht/... | git am

You can also just run `git am` alone and paste the patch into it, followed by
Ctrl+D. You can then make these commits available upstream by using [`git
push`][git-push] normally. Don't forget to send the contributor a thank you
email!

[git-push]: https://www.git-scm.com/docs/git-push