mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-06 04:41:01 +01:00
169 lines
5.9 KiB
Text
169 lines
5.9 KiB
Text
|
@title Differential User Guide: Inline Comments
|
||
|
@group userguide
|
||
|
|
||
|
Guide to inline comments in Differential.
|
||
|
|
||
|
Overview
|
||
|
========
|
||
|
|
||
|
Differential allows reviewers to leave feedback about changes to code inline,
|
||
|
within the body of the diff itself. These comments are called "inline
|
||
|
comments", and can be used to discuss specific parts of a change.
|
||
|
|
||
|
(NOTE) Click the line number next to a line to leave an inline comment.
|
||
|
|
||
|
To leave an inline comment, click the line number next to a line when reviewing
|
||
|
a change in Differential. You can also leave a comment on a range of adjacent
|
||
|
lines by clicking one line number and dragging to a nearby line number.
|
||
|
|
||
|
(NOTE) Other users can't see your comments right away!
|
||
|
|
||
|
When you make a comment, it is initially an **unsubmitted draft**, indicated by
|
||
|
an "Unsubmitted" badge in the comment header. Other users can't see it yet.
|
||
|
This behavior is different from the behavior of other software you may be
|
||
|
familiar with.
|
||
|
|
||
|
To publish your inline comments, scroll to the bottom of the page and submit
|
||
|
the form there. All your unsubmitted inline comments will be published when you
|
||
|
do, alongside an optional normal comment and optional action (like accepting
|
||
|
the revision).
|
||
|
|
||
|
Differential doesn't publish inlines initially because having a draft phase
|
||
|
gives reviewers more time to revise and adjust the inlines, and make their
|
||
|
feedback more cohesive, and contextualize their inlines with discussion in a
|
||
|
normal comment. It also allows Differential to send fewer, more relevant emails
|
||
|
and notifications.
|
||
|
|
||
|
|
||
|
Porting / Ghost Comments
|
||
|
========================
|
||
|
|
||
|
When a revision is updated, we attempt to port inline comments forward and
|
||
|
display them on the new diff. Ported comments have a pale, ghostly appearance
|
||
|
and include a button which allows you to jump back to the original context
|
||
|
where the comment appeared.
|
||
|
|
||
|
Ported comments sometimes appear in unexpected locations. There are two major
|
||
|
reasons for this:
|
||
|
|
||
|
- In the general case, it is not possible to always port comments to the same
|
||
|
lines humans would automatically.
|
||
|
- We are very aggressive about porting comments forward, even in the presence
|
||
|
of heavy changes. This helps prevent mistakes and makes it easier to verify
|
||
|
feedback has been addressed.
|
||
|
|
||
|
You can disable this behavior in
|
||
|
{nav Settings > Diff Preferences > Show Older Inlines} if you prefer comments
|
||
|
stay anchored to their original diff.
|
||
|
|
||
|
To understand why porting comments forward is difficult and can produce
|
||
|
unexpected results, and why we choose to be aggressive about it, let's look at
|
||
|
a case where the right behavior is ambiguous. Imagine this code is added as
|
||
|
part of a change:
|
||
|
|
||
|
```name=important.c
|
||
|
111 ...
|
||
|
112
|
||
|
113 if (a() || b() || c()) {
|
||
|
114 return;
|
||
|
115 }
|
||
|
116
|
||
|
117 ...
|
||
|
```
|
||
|
|
||
|
Suppose a reviewer leaves this comment on line 113:
|
||
|
|
||
|
> important.c:113 This is a serious security vulnerability!
|
||
|
|
||
|
The author later updates the diff, and the code now looks like this, with some
|
||
|
other changes elsewhere so the line numbers have also shifted:
|
||
|
|
||
|
```name=important.c
|
||
|
140 ...
|
||
|
141
|
||
|
142 if (a()) {
|
||
|
143 return;
|
||
|
144 }
|
||
|
145
|
||
|
146 if (b()) {
|
||
|
147 return;
|
||
|
148 }
|
||
|
149
|
||
|
150 ...
|
||
|
```
|
||
|
|
||
|
If we port the inline forward from the first change to the second change, where
|
||
|
should it go? A human would probably do one of three things:
|
||
|
|
||
|
# Put it on line 142, with the call to `a()`.
|
||
|
# Put it on line 146, with the call to `b()`.
|
||
|
# Don't bring it forward at all.
|
||
|
|
||
|
A human would choose between (1) and (2) based on context about what `a()` and
|
||
|
`b()` are and what the reviewer meant. The algorithm can not possibly read the
|
||
|
comment and understand which part of the statement it talked about. Humans
|
||
|
might not even agree on which line is the better fit.
|
||
|
|
||
|
When we choose one of these behaviors, humans will sometimes think the other
|
||
|
behavior was the better one, because they have more information about what
|
||
|
`a()` and `b()` are and what the comment actually meant. The line we choose may
|
||
|
be unexpected, but it is the best the algorithm can do without being able to
|
||
|
actually read the code or understand what the comment means.
|
||
|
|
||
|
A human might also choose not to bring the comment forward if they knew that
|
||
|
removing `c()` addressed it, but the algorithm can not know that. The call to
|
||
|
`a()` or `b()` may be the dangerous thing the reviewer was talking about, and
|
||
|
we err on the side of caution by bringing comments forward aggressively.
|
||
|
|
||
|
When a line of code with an inline comment on it changes, we can not know if
|
||
|
the change addressed the inline or not. We take the cautious route and
|
||
|
//always// assume it did not, and that humans need to verify problems have
|
||
|
really been addressed.
|
||
|
|
||
|
This means that inlines are sometimes ported forward into places that don't
|
||
|
make sense (the code has changed completely), but we won't drop important
|
||
|
inlines just because the structure of the code has changed.
|
||
|
|
||
|
Here's another case where bringing inlines forward seems desirable. Imagine
|
||
|
this code is added as part of a change:
|
||
|
|
||
|
```name=warpgate.c
|
||
|
12 ...
|
||
|
13 function_x();
|
||
|
14 ...
|
||
|
```
|
||
|
|
||
|
Suppose a reviewer leaves this comment on line 13:
|
||
|
|
||
|
> warpgate.c:13 This should be function_y() instead.
|
||
|
|
||
|
The author later updates the diff, and the code now looks like this:
|
||
|
|
||
|
```name=warpgate.c
|
||
|
12 ...
|
||
|
13 function_y();
|
||
|
14 ...
|
||
|
```
|
||
|
|
||
|
For the reasons discussed above, we port the comment forward, so it will appear
|
||
|
under line 13.
|
||
|
|
||
|
We think this is desirable: it makes it trivial for an author or reviewer to
|
||
|
look through the changes and verify that the feedback has really been
|
||
|
addressed, because you can see that the code now uses the proper function.
|
||
|
|
||
|
This isn't to say that we always do the best we can. There may be cases where
|
||
|
the algorithm can be smarter than it currently is or otherwise produce a better
|
||
|
result. If you find such a case, file a bug report. But it's expected that the
|
||
|
algorithm will sometimes port comments into places that aren't optimal or no
|
||
|
longer make sense, because this is frequently the best behavior available among
|
||
|
the possible alternatives.
|
||
|
|
||
|
|
||
|
Next Steps
|
||
|
==========
|
||
|
|
||
|
Continue by:
|
||
|
|
||
|
- returning to the @{article:Differential User Guide}.
|