I hacked a bit more on this today.
The Mercurial extension now stores the review IDs returned from the
server in the Mercurial repository. When you submit a review for a
changeset, the client will look in the local store to see if a review
has already been associated with the changeset. If it has, the client
sends it to the server so the server can reuse the review.
That's pretty basic stuff and there's little value add beside making the
server work less.
The real win comes from hooking up obsolescence markers (the feature
powering changeset evolution). If you rewrite history (amend, rebase,
etc) and the SHA-1 of a changeset changes, Mercurial records that Y is a
successor to X. At review time, the review extension will ask Mercurial,
"what are the previous versions of Y?" When Mercurial returns X, we see
we already have a review for that changeset and we recycle the review
ID. It's pretty magical.
A win here is that clients can start leveraging obsolescence and
changeset evolution before the server supports obsolescence marker
exchange - something that probably won't scale up to Mozilla's needs for
the review repo for a while.
Another win is that it makes the impact of history rewriting on ongoing
review requests pretty bullet proof. For example, say your history looks
like:
* A Parent of review base
* B Pre work foo
* C Pre work bar
* D Foo bar
You push these to the server and get review IDs:
* B -> 1
* C -> 2
* D -> 3
Say two different people are reviewing patches B and C and that you get
review on C first and want to check it in. Or, say that it makes sense
for C to come before B for whatever reason. You reorder patches and are
left with:
* A Parent of review base
* C' Pre work bar (2)
* B' Pre work foo (1)
* D' Foo bar (3)
If you push C', B', and D' for review, a naive implementation (let's
call it the "Git" implementation) may assume that the first pushed
commit (C') is a newer version of B because B was the first commit last
time. Sure, you can attempt some heuristic matching, but that's an
inexact science with lots of cracks. Things start to get *really*
difficult when you fold or drop commits. Anyway, with obsolescence
markers, Mercurial knows that C' is a successor of C and that C was
review 2. This gets passed to the server and the proper reviews are
updated accordingly.
The magic here is beautiful. I can't wait to see this running outside of
my test environment :D