Patchwork [3,of,3,V2] lfs: add the '{raw}' template keyword to '{lfs_files}'

login
register
mail settings
Submitter Matt Harbison
Date Jan. 16, 2018, 2:42 a.m.
Message ID <8458bc4aa3f3f392df8b.1516070540@Envy>
Download mbox | patch
Permalink /patch/26780/
State Accepted
Headers show

Comments

Matt Harbison - Jan. 16, 2018, 2:42 a.m.
# HG changeset patch
# User Matt Harbison <matt_harbison@yahoo.com>
# Date 1515967224 18000
#      Sun Jan 14 17:00:24 2018 -0500
# Node ID 8458bc4aa3f3f392df8bc4e2a7bd15354942e927
# Parent  4f66e5c58c21d6a743d1ea69398b7fa2b9ff6419
lfs: add the '{raw}' template keyword to '{lfs_files}'

Even though it is (probably) weird to have multiline output from a keyword,
something similar to this is useful as the public interface to dump the raw
pointer content.  I still haven't figured out how to use `hg debugdata` in a non
trivial repo, and that will just be another point of aggravation when debugging
a problem.  The raw text is stored here, so that we don't mask any problems in
the data while deserializing and processing it.

Ultimately, this functionality should probably be provided by something like
`hg cat file -T '{raw}'`, and this keyword translate to a dict of the metadata.
For non-LFS files, this would do the same thing as normal `hg cat`.  This would
be similar (I think) to `git show HEAD:{filename}`.  But with the freeze
looming, I won't have time to figure that out, and it could be a valuable
debugging tool as this gets a wider audience.

Patch

diff --git a/hgext/lfs/__init__.py b/hgext/lfs/__init__.py
--- a/hgext/lfs/__init__.py
+++ b/hgext/lfs/__init__.py
@@ -231,6 +231,7 @@ 
     makemap = lambda v: {
         'file': v,
         'oid': pointers[v].oid(),
+        'raw': pointers[v].rawtext(),
     }
 
     # TODO: make the separator ', '?
diff --git a/hgext/lfs/pointer.py b/hgext/lfs/pointer.py
--- a/hgext/lfs/pointer.py
+++ b/hgext/lfs/pointer.py
@@ -24,11 +24,14 @@ 
     def __init__(self, *args, **kwargs):
         self['version'] = self.VERSION
         super(gitlfspointer, self).__init__(*args, **kwargs)
+        self._rawtext = ''
 
     @classmethod
     def deserialize(cls, text):
         try:
-            return cls(l.split(' ', 1) for l in text.splitlines()).validate()
+            p = cls(l.split(' ', 1) for l in text.splitlines()).validate()
+            p._rawtext = text  # Exclude from dict so it doesn't serialize
+            return p
         except ValueError: # l.split returns 1 item instead of 2
             raise InvalidPointer(_('cannot parse git-lfs text: %r') % text)
 
@@ -43,6 +46,11 @@ 
     def size(self):
         return int(self['size'])
 
+    def rawtext(self):
+        """The raw text read from the pointer file to create object.  This will
+        be empty for objects instantiated from key/values for serialization."""
+        return self._rawtext
+
     # regular expressions used by _validate
     # see https://github.com/git-lfs/git-lfs/blob/master/docs/spec.md
     _keyre = re.compile(r'\A[a-z0-9.-]+\Z')
diff --git a/tests/test-lfs.t b/tests/test-lfs.t
--- a/tests/test-lfs.t
+++ b/tests/test-lfs.t
@@ -859,6 +859,12 @@ 
   oid sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
   size 29
   x-is-binary 0
+  $ hg --cwd convert_lfs log -r 0 -T '{lfs_files % "{raw}\n"}'
+  version https://git-lfs.github.com/spec/v1
+  oid sha256:5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024
+  size 29
+  x-is-binary 0
+  
   $ hg --cwd convert_lfs \
   >     log -r 'all()' -T '{rev}: {lfs_files % "{file}: {oid}\n"}'
   0: a1: 5bb8341bee63b3649f222b2215bde37322bea075a30575aa685d8f8d21c77024