Patchwork [STABLE] log: fix handling of root (or empty) path provided by matcher (issue6478)

login
register
mail settings
Submitter Yuya Nishihara
Date Feb. 2, 2021, 12:21 p.m.
Message ID <14feaa5792ed116ec8cc.1612268516@lemosa>
Download mbox | patch
Permalink /patch/48258/
State New
Headers show

Comments

Yuya Nishihara - Feb. 2, 2021, 12:21 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1612264817 -32400
#      Tue Feb 02 20:20:17 2021 +0900
# Branch stable
# Node ID 14feaa5792ed116ec8cc8469fc3de976fb4dd8f5
# Parent  0e2e7300f4302b02412b0b734717697049494c4c
log: fix handling of root (or empty) path provided by matcher (issue6478)

Since 27d6956d386b "match: use '' instead of '.' for root directory",
'.' should be translated to ''. We can't blame repo.file() about this because
an empty string is invalid as a file path, but I found at least two callers
(_makematcher() and revset.filelog()) would crash because of this path[0].

So let's make repo.file() accept an empty string. path[0] == b'/' wouldn't
work on Python 3 anyways.

Patch

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1135,7 +1135,7 @@  class revlogfilestorage(object):
     """File storage when using revlogs."""
 
     def file(self, path):
-        if path[0] == b'/':
+        if path.startswith(b'/'):
             path = path[1:]
 
         return filelog.filelog(self.svfs, path)
@@ -1146,7 +1146,7 @@  class revlognarrowfilestorage(object):
     """File storage when using revlogs and narrow files."""
 
     def file(self, path):
-        if path[0] == b'/':
+        if path.startswith(b'/'):
             path = path[1:]
 
         return filelog.narrowfilelog(self.svfs, path, self._storenarrowmatch)
diff --git a/mercurial/logcmdutil.py b/mercurial/logcmdutil.py
--- a/mercurial/logcmdutil.py
+++ b/mercurial/logcmdutil.py
@@ -845,7 +845,7 @@  def _makematcher(repo, revs, wopts):
         # slowpath; otherwise, we can turn off the slowpath
         if slowpath:
             for path in match.files():
-                if path == b'.' or path in repo.store:
+                if not path or path in repo.store:
                     break
             else:
                 slowpath = False
diff --git a/tests/test-log.t b/tests/test-log.t
--- a/tests/test-log.t
+++ b/tests/test-log.t
@@ -102,6 +102,41 @@  log on directory
   summary:     c
   
 
+log empty path (or repo root) of slow path shouldn't crash (issue6478)
+
+  $ hg log -ql1 '' inexistent
+  4:7e4639b4691b
+  $ hg log -ql1 . inexistent
+  4:7e4639b4691b
+  $ hg log -ql1 "`pwd`" inexistent
+  4:7e4639b4691b
+
+  $ hg log -ql1 '' e
+  4:7e4639b4691b
+  $ hg log -ql1 . e
+  4:7e4639b4691b
+  $ hg log -ql1 "`pwd`" e
+  4:7e4639b4691b
+
+log -f empty path (or repo root) shouldn't crash
+
+  $ hg log -qfl1 '' inexistent
+  abort: cannot follow file not in parent revision: "inexistent"
+  [255]
+  $ hg log -qfl1 . inexistent
+  abort: cannot follow file not in parent revision: "inexistent"
+  [255]
+  $ hg log -qfl1 "`pwd`" inexistent
+  abort: cannot follow file not in parent revision: "inexistent"
+  [255]
+
+  $ hg log -qfl1 '' e
+  4:7e4639b4691b
+  $ hg log -qfl1 . e
+  4:7e4639b4691b
+  $ hg log -qfl1 "`pwd`" e
+  4:7e4639b4691b
+
 -X, with explicit path
 
   $ hg log a -X a