Patchwork [STABLE,V2] log: fix log -f slow path to actually follow history

login
register
mail settings
Submitter Durham Goode
Date Dec. 8, 2014, 7:24 p.m.
Message ID <ebef5f34480a211f701b.1418066658@dev2000.prn2.facebook.com>
Download mbox | patch
Permalink /patch/7020/
State Accepted
Commit 9601229ed361d7844a9db6656eee0953c734c490
Headers show

Comments

Durham Goode - Dec. 8, 2014, 7:24 p.m.
# HG changeset patch
# User Durham Goode <durham@fb.com>
# Date 1417818452 28800
#      Fri Dec 05 14:27:32 2014 -0800
# Node ID ebef5f34480a211f701bfd3da2911d08145f096e
# Parent  406dfc63a1ad71213dccc1a45de99a3c5d5ac460
log: fix log -f slow path to actually follow history

The revset created when -f was used with a slow path (for patterns and
directories) did not actually contain any logic to enforce follow. Instead it
was depending on the passed in subset to already be limited (which was limited
to :. but not ::.). This fixes it by adding a '& ::.' to any -f log revset.

hg log -f <file> is still broken, in that it can return results that aren't
actually ancestors of the current file, but fixing that has major perf
implications, so we'll deal with it later.
Matt Mackall - Dec. 8, 2014, 10:51 p.m.
On Mon, 2014-12-08 at 11:24 -0800, Durham Goode wrote:
> # HG changeset patch
> # User Durham Goode <durham@fb.com>
> # Date 1417818452 28800
> #      Fri Dec 05 14:27:32 2014 -0800
> # Node ID ebef5f34480a211f701bfd3da2911d08145f096e
> # Parent  406dfc63a1ad71213dccc1a45de99a3c5d5ac460
> log: fix log -f slow path to actually follow history

This is queued for stable, thanks.

Patch

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1745,6 +1745,9 @@  def _makelogrevset(repo, pats, opts, rev
             else:
                 slowpath = False
 
+    fpats = ('_patsfollow', '_patsfollowfirst')
+    fnopats = (('_ancestors', '_fancestors'),
+               ('_descendants', '_fdescendants'))
     if slowpath:
         # See walkchangerevs() slow path.
         #
@@ -1763,11 +1766,10 @@  def _makelogrevset(repo, pats, opts, rev
             matchargs.append('x:' + p)
         matchargs = ','.join(('%r' % p) for p in matchargs)
         opts['_matchfiles'] = matchargs
+        if follow:
+            opts[fnopats[0][followfirst]] = '.'
     else:
         if follow:
-            fpats = ('_patsfollow', '_patsfollowfirst')
-            fnopats = (('_ancestors', '_fancestors'),
-                       ('_descendants', '_fdescendants'))
             if pats:
                 # follow() revset interprets its file argument as a
                 # manifest entry, so use match.files(), not pats.
diff --git a/tests/test-glog.t b/tests/test-glog.t
--- a/tests/test-glog.t
+++ b/tests/test-glog.t
@@ -1658,13 +1658,17 @@  Test --follow on a directory
   $ testlog -f dir
   []
   (group
-    (func
-      ('symbol', '_matchfiles')
-      (list
+    (and
+      (func
+        ('symbol', '_matchfiles')
         (list
-          ('string', 'r:')
-          ('string', 'd:relpath'))
-        ('string', 'p:dir'))))
+          (list
+            ('string', 'r:')
+            ('string', 'd:relpath'))
+          ('string', 'p:dir')))
+      (func
+        ('symbol', 'ancestors')
+        ('symbol', '.'))))
   $ hg up -q tip
 
 Test --follow on file not in parent revision
@@ -1679,13 +1683,17 @@  Test --follow and patterns
   $ testlog -f 'glob:*'
   []
   (group
-    (func
-      ('symbol', '_matchfiles')
-      (list
+    (and
+      (func
+        ('symbol', '_matchfiles')
         (list
-          ('string', 'r:')
-          ('string', 'd:relpath'))
-        ('string', 'p:glob:*'))))
+          (list
+            ('string', 'r:')
+            ('string', 'd:relpath'))
+          ('string', 'p:glob:*')))
+      (func
+        ('symbol', 'ancestors')
+        ('symbol', '.'))))
 
 Test --follow on a single rename
 
@@ -1852,13 +1860,17 @@  Test --removed
   $ testlog --removed --follow a
   []
   (group
-    (func
-      ('symbol', '_matchfiles')
-      (list
+    (and
+      (func
+        ('symbol', '_matchfiles')
         (list
-          ('string', 'r:')
-          ('string', 'd:relpath'))
-        ('string', 'p:a'))))
+          (list
+            ('string', 'r:')
+            ('string', 'd:relpath'))
+          ('string', 'p:a')))
+      (func
+        ('symbol', 'ancestors')
+        ('symbol', '.'))))
 
 Test --patch and --stat with --follow and --follow-first
 
diff --git a/tests/test-log.t b/tests/test-log.t
--- a/tests/test-log.t
+++ b/tests/test-log.t
@@ -1543,3 +1543,24 @@  issue3772: hg log -r :null showing revis
   
 
   $ cd ..
+
+hg log -f dir across branches
+
+  $ hg init acrossbranches
+  $ cd acrossbranches
+  $ mkdir d
+  $ echo a > d/a && hg ci -Aqm a
+  $ echo b > d/a && hg ci -Aqm b
+  $ hg up -q 0
+  $ echo b > d/a && hg ci -Aqm c
+  $ hg log -f d -T '{desc}' -G
+  @  c
+  |
+  o  a
+  
+  $ hg log -f d/a -T '{desc}' -G
+  o  b
+  |
+  o  a
+  
+  $ cd ..