log: map None rev to wdirrev when filtering revisions with --line-range stable
authorDenis Laxalde <denis@laxalde.org>
Fri, 29 Nov 2019 21:43:13 +0100
branchstable
changeset 43740 d1b9d2c6ec96
parent 43739 66d5c8c3afed
child 43741 8accf5fa9930
log: map None rev to wdirrev when filtering revisions with --line-range When 'hg log -f --line-range <file>,<range>' is invoked with <range> containing uncommitted changes, the command crashes on Python 3 as follows: [...] File "/usr/lib/python3/dist-packages/mercurial/commands.py", line 4725, in log revs, differ = logcmdutil.getlinerangerevs(repo, revs, opts) File "/usr/lib/python3/dist-packages/mercurial/logcmdutil.py", line 933, in getlinerangerevs if rev not in userrevs: File "/usr/lib/python3/dist-packages/mercurial/smartset.py", line 969, in __contains__ if l < x: TypeError: '<' not supported between instances of 'int' and 'NoneType' The None value is because requested line range has uncommitted changes, so 'rev' is the working directory revision. This only occurs in Python 3 as Python 2 allows comparing None with int. As suggested by Yuya Nishihara, mapping None to node.wdirrev resolves the issue and also make the '--line-range' option properly work with -r 'wdir()'. We add extra tests for non-regression and to illustrate handling of 'wdir()'.
mercurial/logcmdutil.py
tests/test-log-linerange.t
--- a/mercurial/logcmdutil.py	Fri Nov 29 21:34:54 2019 +0100
+++ b/mercurial/logcmdutil.py	Fri Nov 29 21:43:13 2019 +0100
@@ -930,6 +930,8 @@
         fctx = wctx.filectx(fname)
         for fctx, linerange in dagop.blockancestors(fctx, fromline, toline):
             rev = fctx.introrev()
+            if rev is None:
+                rev = wdirrev
             if rev not in userrevs:
                 continue
             linerangesbyrev.setdefault(rev, {}).setdefault(
@@ -940,7 +942,7 @@
         return hunks
 
     def hunksfilter(ctx):
-        fctxlineranges = linerangesbyrev.get(ctx.rev())
+        fctxlineranges = linerangesbyrev.get(scmutil.intrev(ctx))
         if fctxlineranges is None:
             return nofilterhunksfn
 
@@ -960,7 +962,7 @@
         return filterfn
 
     def filematcher(ctx):
-        files = list(linerangesbyrev.get(ctx.rev(), []))
+        files = list(linerangesbyrev.get(scmutil.intrev(ctx), []))
         return scmutil.matchfiles(repo, files)
 
     revs = sorted(linerangesbyrev, reverse=True)
--- a/tests/test-log-linerange.t	Fri Nov 29 21:34:54 2019 +0100
+++ b/tests/test-log-linerange.t	Fri Nov 29 21:43:13 2019 +0100
@@ -898,6 +898,99 @@
   date:        Thu Jan 01 00:00:00 1970 +0000
   summary:     init
   
+
+Uncommitted changes in requested line range
+
+  $ sed 's/2/  /' bazn > bazn.new
+  $ mv bazn.new bazn
+  $ hg diff
+  diff --git a/dir/baz b/dir/bazn
+  rename from dir/baz
+  rename to dir/bazn
+  --- a/dir/baz
+  +++ b/dir/bazn
+  @@ -3,7 +3,7 @@
+   0
+   0
+    1+
+  -2+
+  +  +
+   3+
+   4
+   5
+  $ hg log -f -L bazn,5:7
+  changeset:   9:6af29c3a778f
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     foo -> dir/baz; 1-1+
+  
+  changeset:   5:cfdf972b3971
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     foo: 3 -> 3+ and 11+ -> 11-; bar: a -> a+
+  
+  changeset:   4:eaec41c1a0c9
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     11 -> 11+; leading space before "1"
+  
+  changeset:   2:63a884426fd0
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     2 -> 2+; added bar
+  
+  changeset:   0:5ae1f82b9a00
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     init
+  
+
+Uncommitted changes in line-range + wdir()
+
+  $ hg log -r 'wdir()' -f -L bazn,5:7 --limit 2 -p
+  changeset:   2147483647:ffffffffffff
+  parent:      9:6af29c3a778f
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  
+  diff --git a/dir/baz b/dir/bazn
+  copy from dir/baz
+  copy to dir/bazn
+  --- a/dir/baz
+  +++ b/dir/bazn
+  @@ -3,7 +3,7 @@
+   0
+   0
+    1+
+  -2+
+  +  +
+   3+
+   4
+   5
+  
+  changeset:   9:6af29c3a778f
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     foo -> dir/baz; 1-1+
+  
+  diff --git a/foo b/dir/baz
+  copy from foo
+  copy to dir/baz
+  --- a/foo
+  +++ b/dir/baz
+  @@ -2,7 +2,7 @@
+   0
+   0
+   0
+  - 1
+  + 1+
+   2+
+   3+
+   4
+  
+
   $ hg revert -a -C -q
 
 Binary files work but without diff hunks filtering.