# HG changeset patch # User Durham Goode # Date 2014-12-05 22:27:32 # Node ID 9601229ed361d7844a9db6656eee0953c734c490 # Parent 30b602168c3bb62de5afea8b97de9234e7394c3e 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 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. 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 ..