# HG changeset patch # User Mads Kiilerich # Date 2013-04-14 23:43:31 # Node ID d78a136a803633cef03232108612c43a8f520099 # Parent 5f9019e6d451aed829bbae55f56ed317aa5c9e17 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. diff --git a/hgext/largefiles/lfcommands.py b/hgext/largefiles/lfcommands.py --- a/hgext/largefiles/lfcommands.py +++ b/hgext/largefiles/lfcommands.py @@ -530,24 +530,6 @@ def _updatelfile(repo, lfdirstate, lfile 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 = { diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py --- a/hgext/largefiles/overrides.py +++ b/hgext/largefiles/overrides.py @@ -19,6 +19,7 @@ from hgext import rebase import lfutil import lfcommands +import basestore # -- Utility functions: commonly/repeatedly needed functionality --------------- @@ -1155,13 +1156,37 @@ def overridecat(orig, ui, repo, file1, * 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): diff --git a/tests/test-largefiles.t b/tests/test-largefiles.t --- a/tests/test-largefiles.t +++ b/tests/test-largefiles.t @@ -1486,7 +1486,10 @@ Cat a largefile $ 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