Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/logcmdutil.py @ 43445:d1b9d2c6ec96 stable
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()'.
author | Denis Laxalde <denis@laxalde.org> |
---|---|
date | Fri, 29 Nov 2019 21:43:13 +0100 |
parents | 8ff1ecfadcd1 |
children | 29adf0a087a1 |
comparison
equal
deleted
inserted
replaced
43444:66d5c8c3afed | 43445:d1b9d2c6ec96 |
---|---|
928 _(b'cannot follow file not in parent revision: "%s"') % fname | 928 _(b'cannot follow file not in parent revision: "%s"') % fname |
929 ) | 929 ) |
930 fctx = wctx.filectx(fname) | 930 fctx = wctx.filectx(fname) |
931 for fctx, linerange in dagop.blockancestors(fctx, fromline, toline): | 931 for fctx, linerange in dagop.blockancestors(fctx, fromline, toline): |
932 rev = fctx.introrev() | 932 rev = fctx.introrev() |
933 if rev is None: | |
934 rev = wdirrev | |
933 if rev not in userrevs: | 935 if rev not in userrevs: |
934 continue | 936 continue |
935 linerangesbyrev.setdefault(rev, {}).setdefault( | 937 linerangesbyrev.setdefault(rev, {}).setdefault( |
936 fctx.path(), [] | 938 fctx.path(), [] |
937 ).append(linerange) | 939 ).append(linerange) |
938 | 940 |
939 def nofilterhunksfn(fctx, hunks): | 941 def nofilterhunksfn(fctx, hunks): |
940 return hunks | 942 return hunks |
941 | 943 |
942 def hunksfilter(ctx): | 944 def hunksfilter(ctx): |
943 fctxlineranges = linerangesbyrev.get(ctx.rev()) | 945 fctxlineranges = linerangesbyrev.get(scmutil.intrev(ctx)) |
944 if fctxlineranges is None: | 946 if fctxlineranges is None: |
945 return nofilterhunksfn | 947 return nofilterhunksfn |
946 | 948 |
947 def filterfn(fctx, hunks): | 949 def filterfn(fctx, hunks): |
948 lineranges = fctxlineranges.get(fctx.path()) | 950 lineranges = fctxlineranges.get(fctx.path()) |
958 yield hunk | 960 yield hunk |
959 | 961 |
960 return filterfn | 962 return filterfn |
961 | 963 |
962 def filematcher(ctx): | 964 def filematcher(ctx): |
963 files = list(linerangesbyrev.get(ctx.rev(), [])) | 965 files = list(linerangesbyrev.get(scmutil.intrev(ctx), [])) |
964 return scmutil.matchfiles(repo, files) | 966 return scmutil.matchfiles(repo, files) |
965 | 967 |
966 revs = sorted(linerangesbyrev, reverse=True) | 968 revs = sorted(linerangesbyrev, reverse=True) |
967 | 969 |
968 differ = changesetdiffer() | 970 differ = changesetdiffer() |