largefiles: fix cat of non-largefiles from subdirectory
We were calling back to the original commands.cat from inside the walk loop
that handled and filtered out largefiles. That did however happen with file
paths relative to repo root and the original cat would fail when it applied its
own walk and match on top of that.
Instead we now duplicate and modify the code from commands.cat and patch it to
handle both normal and largefiles.
A change in test output shows that this also makes the exit code with
largefiles consistent with the normal one in the case where one of several
specified files are missing.
This also fixes the combination of --output and largefiles.
--- a/hgext/largefiles/lfcommands.py Mon Apr 15 01:41:49 2013 +0200
+++ b/hgext/largefiles/lfcommands.py Mon Apr 15 01:43:31 2013 +0200
@@ -530,24 +530,6 @@
lfdirstate.drop(lfile)
return ret
-def catlfile(repo, lfile, rev, filename):
- hash = lfutil.readstandin(repo, lfile, rev)
- if not lfutil.inusercache(repo.ui, hash):
- store = basestore._openstore(repo)
- success, missing = store.get([(lfile, hash)])
- if len(success) != 1:
- raise util.Abort(
- _('largefile %s is not in cache and could not be downloaded')
- % lfile)
- path = lfutil.usercachepath(repo.ui, hash)
- fpout = cmdutil.makefileobj(repo, filename)
- fpin = open(path, "rb")
- for chunk in lfutil.blockstream(fpin):
- fpout.write(chunk)
- fpout.close()
- fpin.close()
- return 0
-
# -- hg commands declarations ------------------------------------------------
cmdtable = {
--- a/hgext/largefiles/overrides.py Mon Apr 15 01:41:49 2013 +0200
+++ b/hgext/largefiles/overrides.py Mon Apr 15 01:43:31 2013 +0200
@@ -19,6 +19,7 @@
import lfutil
import lfcommands
+import basestore
# -- Utility functions: commonly/repeatedly needed functionality ---------------
@@ -1155,13 +1156,37 @@
notbad.add(lf)
return origmatchfn(lf)
m.matchfn = lfmatchfn
- m.bad = lambda f, msg: f not in notbad
+ origbadfn = m.bad
+ def lfbadfn(f, msg):
+ if not f in notbad:
+ return origbadfn(f, msg)
+ m.bad = lfbadfn
for f in ctx.walk(m):
+ fp = cmdutil.makefileobj(repo, opts.get('output'), ctx.node(),
+ pathname=f)
lf = lfutil.splitstandin(f)
if lf is None:
- err = orig(ui, repo, f, **opts)
+ # duplicating unreachable code from commands.cat
+ data = ctx[f].data()
+ if opts.get('decode'):
+ data = repo.wwritedata(f, data)
+ fp.write(data)
else:
- err = lfcommands.catlfile(repo, lf, ctx.rev(), opts.get('output'))
+ hash = lfutil.readstandin(repo, lf, ctx.rev())
+ if not lfutil.inusercache(repo.ui, hash):
+ store = basestore._openstore(repo)
+ success, missing = store.get([(lf, hash)])
+ if len(success) != 1:
+ raise util.Abort(
+ _('largefile %s is not in cache and could not be '
+ 'downloaded') % lf)
+ path = lfutil.usercachepath(repo.ui, hash)
+ fpin = open(path, "rb")
+ for chunk in lfutil.blockstream(fpin):
+ fp.write(chunk)
+ fpin.close()
+ fp.close()
+ err = 0
return err
def mercurialsinkbefore(orig, sink):
--- a/tests/test-largefiles.t Mon Apr 15 01:41:49 2013 +0200
+++ b/tests/test-largefiles.t Mon Apr 15 01:43:31 2013 +0200
@@ -1486,7 +1486,10 @@
$ hg cat -r '.^' sub/large4 doesntexist
large4-modified
doesntexist: no such file in rev a381d2c8c80e
- [1]
+ $ hg --cwd sub cat -r '.^' large4
+ large4-modified
+ $ hg --cwd sub cat -r '.^' ../normal3
+ normal3-modified
Test that renaming a largefile results in correct output for status