[PATCH STABLE RFC] transplant: avoid a dirstate race when transplanting multiple changesets

Greg Ward greg-hg at gerg.ca
Thu Jan 27 08:44:45 CST 2011


On Wed, Jan 26, 2011 at 6:56 PM, Matt Mackall <mpm at selenic.com> wrote:
> So usually after update or commit, we mark a file in state 'normal',
> which records the current time in the dirstate.
>
> If the file then gets modified in the same second without the size
> changing, then the next commit -in the same process- could miss the
> change.

That's my understanding.

> But if we actually write out the dirstate, we blank out the timestamp of
> any files where timestamp matches a window around the current second,
> which is like the normallookup state but only for files inside the risk
> window.

Ahhh, that explains why my first dimly-understood attempt at fixing
the bug (dirstate.write() after each commit() in transplant) worked.
That was just a bigger hammer than calling normallookup() on each file
known to be modified by the transplanted changeset.

Unfortunately, I'm having a hard time writing a little standalone
Python script to reproduce the (alleged) bug.  Here's what I have so
far:

"""
from mercurial import ui, hg, match, node

def replacebyte(fn, b):
    f = open("file1", "rb+")
    f.seek(0, 0)
    f.write(b)
    f.close()

repo = hg.repository(ui.ui(), '.')
print "before commit 1:", repo.dirstate._map['file1']
m = match.exact(repo.root, '', ['file1'])
replacebyte("file1", "x")
n = repo.commit(text="x", user="test", date=(0, 0), match=m)
print len(repo) - 1
print "after commit 1:", repo.dirstate._map['file1']
replacebyte("file1", "y")
n = repo.commit(text="y", user="test", date=(0, 0), match=m)
print len(repo) - 1
print "after commit 2:", repo.dirstate._map['file1']
"""

This is meant to be run at the end of the current
test-transplant-multiple.t: i.e. we are already in a repo that's
tracking 'file1'.

The above is *supposed* to be an abstraction of what transplant does
to expose the bug, but it doesn't work.  The two committed changesets
are fine.  Huh.  Any clue what I'm missing?

Greg


More information about the Mercurial-devel mailing list