Patchwork [02,of,10] largefiles: fix cat of non-largefiles from subdirectory

login
register
mail settings
Submitter Mads Kiilerich
Date April 15, 2013, 7:23 p.m.
Message ID <a02222599619df2bb004.1366053835@mk-desktop>
Download mbox | patch
Permalink /patch/1319/
State Accepted
Commit d78a136a803633cef03232108612c43a8f520099
Headers show

Comments

Mads Kiilerich - April 15, 2013, 7:23 p.m.
# HG changeset patch
# User Mads Kiilerich <madski@unity3d.com>
# Date 1365983011 -7200
#      Mon Apr 15 01:43:31 2013 +0200
# Node ID a02222599619df2bb004de1862a0dc9981c1d98d
# Parent  eac1beec2678ed2f4f9a4c4c5890353a1522f48d
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.

Patch

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 @@ 
         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 @@ 
 
 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):
diff --git a/tests/test-largefiles.t b/tests/test-largefiles.t
--- a/tests/test-largefiles.t
+++ b/tests/test-largefiles.t
@@ -1458,7 +1458,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