# HG changeset patch # User Thomas Arendsen Hein # Date 1123652866 -3600 # Node ID d70c1c31fd458a6bcff03175b03b2a553930ce20 # Parent cbe5c4d016b712283add05545165551f47166c92 Fix 3-way-merge of original parent, workdir and new parent. The dirstate has to match what is in the repository (what would be checked out with 'hg update -C'), because the resulting file may be identical to the new parent, or it may be completely different. Previously the dirstate wasn't updated, so if you changed the file to look like the original parent, it might be considered unmodified relative to the new parent. diff --git a/mercurial/hg.py b/mercurial/hg.py --- a/mercurial/hg.py +++ b/mercurial/hg.py @@ -392,7 +392,7 @@ class dirstate: def copied(self, file): return self.copies.get(file, None) - def update(self, files, state): + def update(self, files, state, **kw): ''' current states: n normal m needs merging @@ -407,7 +407,10 @@ class dirstate: self.map[f] = ('r', 0, 0, 0) else: s = os.stat(os.path.join(self.root, f)) - self.map[f] = (state, s.st_mode, s.st_size, s.st_mtime) + st_mode = kw.get('st_mode', s.st_mode) + st_size = kw.get('st_size', s.st_size) + st_mtime = kw.get('st_mtime', s.st_mtime) + self.map[f] = (state, st_mode, st_size, st_mtime) def forget(self, files): if not files: return @@ -1571,10 +1574,21 @@ class localrepository: m, o, flag = merge[f] self.merge3(f, m, o) util.set_exec(self.wjoin(f), flag) - if moddirstate and mode == 'm': - # only update dirstate on branch merge, otherwise we - # could mark files with changes as unchanged - self.dirstate.update([f], mode) + if moddirstate: + if mode == 'm': + # only update dirstate on branch merge, otherwise we + # could mark files with changes as unchanged + self.dirstate.update([f], mode) + elif p2 == nullid: + # update dirstate from parent1's manifest + m1n = self.changelog.read(p1)[0] + m1 = self.manifest.read(m1n) + file_ = self.file(f) + f_len = file_.length(file_.rev(m1[f])) + self.dirstate.update([f], mode, st_size=f_len, st_mtime=0) + else: + self.ui.warn("Second parent without branch merge!?\n" + "Dirstate for file %s may be wrong.\n" % f) remove.sort() for f in remove: diff --git a/tests/test-merge-revert.out b/tests/test-merge-revert.out --- a/tests/test-merge-revert.out +++ b/tests/test-merge-revert.out @@ -26,7 +26,6 @@ 3aa14bbc23d9 tip + hg update merging file1 + hg diff -FIXME: This is a known bug: + hg status + hg id 3aa14bbc23d9 tip diff --git a/tests/test-merge-revert2.out b/tests/test-merge-revert2.out --- a/tests/test-merge-revert2.out +++ b/tests/test-merge-revert2.out @@ -44,7 +44,6 @@ M file1 3aa14bbc23d9+ tip + hg revert + hg diff -FIXME: This is a known bug: + hg status + hg id 3aa14bbc23d9 tip