diff mercurial/cmdutil.py @ 11899:99cafcae25d9

log: do not --follow file that is deleted and recreated later (issue732) == What == issue732 is only one example of a buggy behaviour, but there are in fact many intricated cases. For example: ( "o" contains an alive version of the tracked file, "x" does not) tip - o - o - x - o - o - x ... \ o - o - o - o - x ... \ / o - o This repository contains at least two instances of the tracked file, but when calling "hg log -f file" only the latest one (the one alive in tip) matters to us. == How == We must extract from the filelog the history of the file instance we're interested in and discard changes related to other instances of that file. We see that we're only interested in ancestors(node), and that all other nodes in the filelog should not be considered.
author Nicolas Dumazet <nicdumz.commits@gmail.com>
date Sun, 15 Aug 2010 23:17:53 +0900
parents 15aa42aaae4c
children a80577bfea29
line wrap: on
line diff
--- a/mercurial/cmdutil.py	Sun Aug 15 22:44:15 2010 +0900
+++ b/mercurial/cmdutil.py	Sun Aug 15 23:17:53 2010 +0900
@@ -1059,8 +1059,14 @@
         # We only have to read through the filelog to find wanted revisions
 
         minrev, maxrev = min(revs), max(revs)
-        # Only files, no patterns.  Check the history of each file.
         def filerevgen(filelog, last):
+            """
+            Only files, no patterns.  Check the history of each file.
+
+            Examines filelog entries within minrev, maxrev linkrev range
+            Returns an iterator yielding (linkrev, parentlinkrevs, copied)
+            tuples in backwards order
+            """
             cl_count = len(repo)
             revs = []
             for j in xrange(0, last + 1):
@@ -1071,8 +1077,13 @@
                 # happen while doing "hg log" during a pull or commit
                 if linkrev > maxrev or linkrev >= cl_count:
                     break
+
+                parentlinkrevs = []
+                for p in filelog.parentrevs(j):
+                    if p != nullrev:
+                        parentlinkrevs.append(filelog.linkrev(p))
                 n = filelog.node(j)
-                revs.append((filelog.linkrev(j),
+                revs.append((linkrev, parentlinkrevs,
                              follow and filelog.renamed(n)))
 
             for rev in reversed(revs):
@@ -1101,7 +1112,18 @@
             else:
                 last = filelog.rev(node)
 
-            for rev, copied in filerevgen(filelog, last):
+
+            # keep track of all ancestors of the file
+            ancestors = set([filelog.linkrev(last)])
+
+            # iterate from latest to oldest revision
+            for rev, flparentlinkrevs, copied in filerevgen(filelog, last):
+                if rev not in ancestors:
+                    continue
+                # XXX insert 1327 fix here
+                if flparentlinkrevs:
+                    ancestors.update(flparentlinkrevs)
+
                 fncache.setdefault(rev, [])
                 fncache[rev].append(file_)
                 wanted.add(rev)