diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -1570,8 +1570,14 @@ def _makelogrevset(repo, pats, opts, rev if not slowpath: for f in match.files(): if follow and f not in pctx: - raise util.Abort(_('cannot follow file not in parent ' - 'revision: "%s"') % f) + # If the file exists, it may be a directory, so let it + # take the slow path. + if os.path.exists(repo.wjoin(f)): + slowpath = True + continue + else: + raise util.Abort(_('cannot follow file not in parent ' + 'revision: "%s"') % f) filelog = repo.file(f) if not filelog: # A zero count may be a directory or deleted file, so @@ -1595,9 +1601,6 @@ def _makelogrevset(repo, pats, opts, rev if slowpath: # See walkchangerevs() slow path. # - if follow: - raise util.Abort(_('can only follow copies/renames for explicit ' - 'filenames')) # pats/include/exclude cannot be represented as separate # revset expressions as their filtering logic applies at file # level. For instance "-I a -X a" matches a revision touching @@ -1629,7 +1632,10 @@ def _makelogrevset(repo, pats, opts, rev filematcher = None if opts.get('patch') or opts.get('stat'): - if follow and not match.always(): + # When following files, track renames via a special matcher. + # If we're forced to take the slowpath it means we're following + # at least one pattern/directory, so don't bother with rename tracking. + if follow and not match.always() and not slowpath: # _makelogfilematcher expects its files argument to be relative to # the repo root, so use match.files(), not pats. filematcher = _makelogfilematcher(repo, match.files(), followfirst) diff --git a/tests/test-glog.t b/tests/test-glog.t --- a/tests/test-glog.t +++ b/tests/test-glog.t @@ -1645,13 +1645,28 @@ Test glob expansion of pats ('symbol', 'filelog') ('string', 'aa')))) -Test --follow on a directory +Test --follow on a non-existent directory $ testlog -f dir abort: cannot follow file not in parent revision: "dir" abort: cannot follow file not in parent revision: "dir" abort: cannot follow file not in parent revision: "dir" +Test --follow on a directory + + $ hg up -q '.^' + $ testlog -f dir + [] + (group + (func + ('symbol', '_matchfiles') + (list + (list + ('string', 'r:') + ('string', 'd:relpath')) + ('string', 'p:dir')))) + $ hg up -q tip + Test --follow on file not in parent revision $ testlog -f a @@ -1662,9 +1677,15 @@ Test --follow on file not in parent revi Test --follow and patterns $ testlog -f 'glob:*' - abort: can only follow copies/renames for explicit filenames - abort: can only follow copies/renames for explicit filenames - abort: can only follow copies/renames for explicit filenames + [] + (group + (func + ('symbol', '_matchfiles') + (list + (list + ('string', 'r:') + ('string', 'd:relpath')) + ('string', 'p:glob:*')))) Test --follow on a single rename @@ -1829,9 +1850,15 @@ Test --removed ('string', 'd:relpath')) ('string', 'p:a')))) $ testlog --removed --follow a - abort: can only follow copies/renames for explicit filenames - abort: can only follow copies/renames for explicit filenames - abort: can only follow copies/renames for explicit filenames + [] + (group + (func + ('symbol', '_matchfiles') + (list + (list + ('string', 'r:') + ('string', 'd:relpath')) + ('string', 'p:a')))) 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 @@ -78,12 +78,52 @@ log on directory summary: c --f, directory +-f, non-existent directory $ hg log -f dir abort: cannot follow file not in parent revision: "dir" [255] +-f, directory + + $ hg up -q 3 + $ hg log -f dir + changeset: 2:f8954cd4dc1f + user: test + date: Thu Jan 01 00:00:03 1970 +0000 + summary: c + +-f, directory with --patch + + $ hg log -f dir -p + changeset: 2:f8954cd4dc1f + user: test + date: Thu Jan 01 00:00:03 1970 +0000 + summary: c + + diff -r d89b0a12d229 -r f8954cd4dc1f dir/b + --- /dev/null* (glob) + +++ b/dir/b* (glob) + @@ -0,0 +1,1 @@ + +a + + +-f, pattern + + $ hg log -f -I 'dir**' -p + changeset: 2:f8954cd4dc1f + user: test + date: Thu Jan 01 00:00:03 1970 +0000 + summary: c + + diff -r d89b0a12d229 -r f8954cd4dc1f dir/b + --- /dev/null* (glob) + +++ b/dir/b* (glob) + @@ -0,0 +1,1 @@ + +a + + $ hg up -q 4 + -f, a wrong style $ hg log -f -l1 --style something