[PATCH STABLE RFC] transplant: avoid a dirstate race when transplanting multiple changesets
Greg Ward
greg-hg at gerg.ca
Tue Jan 25 22:12:14 UTC 2011
On Tue, Jan 25, 2011 at 10:29 AM, Mads Kiilerich <mads at kiilerich.com> wrote:
>> --- a/hgext/transplant.py
>> +++ b/hgext/transplant.py
>> @@ -177,6 +177,16 @@
>> lock.release()
>> wlock.release()
>>
>> + # Extra after-the-fact check for one of the symptoms of
>> + # issue2264: if this is raised, it's too late and we've already
>> + # committed bad changesets. Not sure if it's worth the overhead
>> + # of a status() call.
>> + (modified, added, removed) = repo.status()[0:3]
>> + if modified or added or removed:
>> + raise RuntimeError('uncommitted changes left in working dir '
>> + 'after transplanting %d changesets\n'
>> + % len(revs))
>> +
>
> Wouldn't util.Abort be better? (I guess the existing use of RuntimeError
> should be changed too.)
It's indicating an internal error, not a user error. util.Abort()
hides the stack trace and gives a single-line error message, so it's
appropriate for user errors. But if this happens, I *want* a great
big scary stack trace. (Same reason for the other RuntimeError I
added to transplant.py a few months back, also related to this bug.)
However, I'm not convinced that this check adds enough value to be
worth the overhead of a repo.status() call. It would take almost
nothing to convince me to drop it.
>> @@ -252,6 +262,12 @@
>> m = match.exact(repo.root, '', files)
>>
>> n = repo.commit(message, user, date, extra=extra, match=m)
>> +
>> + # force repo.status() to look harder at each file in this patch
>> + # when committing the next patch (avoids a dirstate race)
>> + for fn in files:
>> + repo.dirstate.normallookup(fn)
>> +
>
> Shouldn't this be done before commit so commit is guaranteed to pick up all
> these patched files and we get a 100% reliable fix?
In a sense, it is. It's done after commit i in order for commit i+1
to see all the patched files. See, there's only a problem when we are
transplanting multiple changesets (..., i, i+1, ...), and the i+1
makes a change to F that does not change F's size relative to i. In
that case, the transplant of i is fine, but i+1 is transplanted wrong.
Fixing the dirstate after transplanting i makes things fine for the
coming i+1.
Greg
More information about the Mercurial-devel
mailing list