# HG changeset patch # User mpm@selenic.com # Date 1123919649 28800 # Node ID 6d6095823b82f32c7d20230c4b7fc18fe6343dae # Parent 6390c377a9e617e01061d33f3729948d72b6f54f# Parent 2d2fee33ec680a2c04383dc7f1ed1477335bca51 Merge with TAH diff --git a/doc/hg.1.txt b/doc/hg.1.txt --- a/doc/hg.1.txt +++ b/doc/hg.1.txt @@ -509,7 +509,7 @@ SPECIFYING MULTIPLE REVISIONS If BEGIN is greater than END, revisions are treated in reverse order. - A range acts as an open interval. This means that a range of 3:5 + A range acts as a closed interval. This means that a range of 3:5 gives 3, 4 and 5. Similarly, a range of 4:2 gives 4, 3, and 2. ENVIRONMENT VARIABLES diff --git a/mercurial/hg.py b/mercurial/hg.py --- a/mercurial/hg.py +++ b/mercurial/hg.py @@ -10,7 +10,7 @@ import util from revlog import * from demandload import * demandload(globals(), "re lock urllib urllib2 transaction time socket") -demandload(globals(), "tempfile httprangereader bdiff urlparse") +demandload(globals(), "tempfile httprangereader bdiff urlparse stat") demandload(globals(), "bisect select") class filelog(revlog): @@ -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,9 @@ 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_size = kw.get('st_size', s.st_size) + st_mtime = kw.get('st_mtime', s.st_mtime) + self.map[f] = (state, s.st_mode, st_size, st_mtime) def forget(self, files): if not files: return @@ -484,33 +486,41 @@ class dirstate: if match(fn): yield src, fn - def changes(self, files = None, match = util.always): + def changes(self, files=None, match=util.always): self.read() dc = self.map.copy() - lookup, changed, added, unknown = [], [], [], [] + lookup, modified, added, unknown = [], [], [], [] + removed, deleted = [], [] for src, fn in self.walk(files, match): - try: s = os.stat(os.path.join(self.root, fn)) - except: continue - - if fn in dc: - c = dc[fn] + try: + s = os.stat(os.path.join(self.root, fn)) + except OSError: + continue + if not stat.S_ISREG(s.st_mode): + continue + c = dc.get(fn) + if c: del dc[fn] - if c[0] == 'm': - changed.append(fn) + modified.append(fn) elif c[0] == 'a': added.append(fn) elif c[0] == 'r': unknown.append(fn) elif c[2] != s.st_size or (c[1] ^ s.st_mode) & 0100: - changed.append(fn) - elif c[1] != s.st_mode or c[3] != s.st_mtime: + modified.append(fn) + elif c[3] != s.st_mtime: lookup.append(fn) else: - if match(fn): unknown.append(fn) + unknown.append(fn) - return (lookup, changed, added, filter(match, dc.keys()), unknown) + for fn, c in [(fn, c) for fn, c in dc.items() if match(fn)]: + if c[0] == 'r': + removed.append(fn) + else: + deleted.append(fn) + return (lookup, modified, added, removed + deleted, unknown) # used to avoid circular references so destructors work def opener(base): @@ -1563,10 +1573,20 @@ 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) + f_len = len(self.file(f).read(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 b/tests/test-merge-revert2 --- a/tests/test-merge-revert2 +++ b/tests/test-merge-revert2 @@ -4,6 +4,7 @@ mkdir t cd t hg init echo "added file1" > file1 +echo "another line of text" >> file1 echo "added file2" > file2 hg add file1 file2 hg commit -m "added file1 and file2" -d "0 0" -u user 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 @@ -3,36 +3,37 @@ + hg commit -m added file1 and file2 -d 0 0 -u user + hg commit -m changed file1 -d 0 0 -u user + hg -q log -1:3aa14bbc23d90e3f8b5b639b4a43d76509bae76c -0:8633637036c18f021d771208e16ae3508ab81d28 +1:f4d7a8c73d231bc078e2a5e791325e55e8a4c252 +0:232e179b3f294d467cfa66e1439bc5b0d44e4a93 + hg id -3aa14bbc23d9 tip +f4d7a8c73d23 tip + hg update -C 0 + hg id -8633637036c1 +232e179b3f29 + hg id -8633637036c1+ +232e179b3f29+ + hg revert + hg diff + hg status + hg id -8633637036c1 +232e179b3f29 + hg update + hg diff + hg status + hg id -3aa14bbc23d9 tip +f4d7a8c73d23 tip + hg update -C 0 + hg update merge: warning: conflicts during merge merging file1 merging file1 failed! + hg diff -diff -r 3aa14bbc23d9 file1 +diff -r f4d7a8c73d23 file1 --- a/file1 +++ b/file1 -@@ -1,2 +1,6 @@ +@@ -1,3 +1,7 @@ added file1 + another line of text +<<<<<<< +changed file1 different +======= @@ -41,20 +42,19 @@ diff -r 3aa14bbc23d9 file1 + hg status M file1 + hg id -3aa14bbc23d9+ tip +f4d7a8c73d23+ tip + hg revert + hg diff -FIXME: This is a known bug: + hg status + hg id -3aa14bbc23d9 tip +f4d7a8c73d23 tip + hg revert -r tip + hg diff + hg status + hg id -3aa14bbc23d9 tip +f4d7a8c73d23 tip + hg update -C + hg diff + hg status + hg id -3aa14bbc23d9 tip +f4d7a8c73d23 tip