# HG changeset patch # User Denis Laxalde # Date 2019-11-29 20:43:13 # Node ID d1b9d2c6ec96656ba66e0bf42018b0cb45071412 # Parent 66d5c8c3afedd0e74791f02a4cf88e4fbe55e7a8 log: map None rev to wdirrev when filtering revisions with --line-range When 'hg log -f --line-range ,' is invoked with 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()'. diff --git a/mercurial/logcmdutil.py b/mercurial/logcmdutil.py --- a/mercurial/logcmdutil.py +++ b/mercurial/logcmdutil.py @@ -930,6 +930,8 @@ def getlinerangerevs(repo, userrevs, opt 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 @@ def getlinerangerevs(repo, userrevs, opt 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 @@ def getlinerangerevs(repo, userrevs, opt 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) diff --git a/tests/test-log-linerange.t b/tests/test-log-linerange.t --- a/tests/test-log-linerange.t +++ b/tests/test-log-linerange.t @@ -898,6 +898,99 @@ Uncommitted changes with a rename 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.