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()