Inotify causing silent merge corruptions ?!

Marc Bevand m.bevand at gmail.com
Wed Dec 31 07:46:44 CST 2008


Let's assume a simple repo with 2 heads B and C:

  A-B
   \
    C

A contains 2 empty files: f1 and f2.
B modifies file f1.
C modifies file f2.
The index files might look like:

  $ hg debugindex .hg/store/data/f1.i
     rev    offset  length   base linkrev nodeid       p1           p2
       0         0       0      0       0 b80de5d13875 000000000000 
000000000000
       1         0      41      0       1 76b4f1cd0f8e b80de5d13875 
000000000000
  $ hg debugindex .hg/store/data/f2.i
     rev    offset  length   base linkrev nodeid       p1           p2
       0         0       0      0       0 b80de5d13875 000000000000 
000000000000
       1         0      41      0       2 6aaa11283f90 b80de5d13875 
000000000000

(The connoisseurs will recognize the 2 nodeid b80de5d13875 as the SHA1
of 40 NUL bytes: p1 + p2 + empty string because f1 and f2 are empty).
Anyway, assuming we "hg update -C C" the manifest should be:

  $ hg --debug manifest
  b80de5d138758541c5f05265ad144ab9fa86d1db 644   f1
  6aaa11283f90e5f07e5eff4cc36ffaf81bd687d2 644   f2

IOW repository revision C is composed of rev 0 of f1 and rev 1 of f2. At
this point, do you guys agree that if a merge is performed without conflict
followed by a commit, the manifest *should* show that f1 is now at rev 1:

  $ hg --debug manifest
  76b4f1cd0f8e7f79060e717acaa5a9386b4f4cb1 644   f1
  6aaa11283f90e5f07e5eff4cc36ffaf81bd687d2 644   f2

Right ? Well I have a case here where this did not happen. The manifest
after merge+commit was still:

  $ hg --debug manifest
  b80de5d138758541c5f05265ad144ab9fa86d1db 644   f1
  6aaa11283f90e5f07e5eff4cc36ffaf81bd687d2 644   f2

Meaning that the merge operation *silently* failed to incorporate
changes from branch B into the merged cset. I tracked down the problem
to the culprit merge after noticing some files where clearly not
containing the data they were supposed to...

This occured with Mercurial at revision 11660d2918af (1.1.1 + some
trivial changes), running on Linux kernel 2.6.27, with the inotify
extension, on a large repo (700MB, 100k files) residing on a local XFS
filesystem. I suspect an inotify bug, maybe a race condition. I cloned
my repo to be in the state it was at right before the merge, to
reperform the merge, but this time it does merge as expected. Next thing
I am going to try is to write a script to repeatedly attempt the merge.
If it is a race condition in inotify, it should eventually reproduce the
bug.

-marc




More information about the Mercurial mailing list