[diffoscope] 01/01: Add git index file comparator.

Chris Lamb chris at chris-lamb.co.uk
Wed Jul 20 10:19:56 CEST 2016


This is an automated email from the git hooks/post-receive script.

lamby pushed a commit to branch master
in repository diffoscope.

commit cd4928cc8cb121b86693f4558f2cd5191f3d3395
Author: Chris Lamb <lamby at debian.org>
Date:   Wed Jul 20 09:19:39 2016 +0100

    Add git index file comparator.
    
    Signed-off-by: Chris Lamb <lamby at debian.org>
---
 diffoscope/comparators/__init__.py |   2 +
 diffoscope/comparators/git.py      | 103 +++++++++++++++++++++++++++++++++++++
 2 files changed, 105 insertions(+)

diff --git a/diffoscope/comparators/__init__.py b/diffoscope/comparators/__init__.py
index b94e84d..f02da1a 100644
--- a/diffoscope/comparators/__init__.py
+++ b/diffoscope/comparators/__init__.py
@@ -51,6 +51,7 @@ from diffoscope.comparators.elf import ElfFile, ElfSection, StaticLibFile
 from diffoscope.comparators.fsimage import FsImageFile
 from diffoscope.comparators.fonts import TtfFile
 from diffoscope.comparators.gettext import MoFile
+from diffoscope.comparators.git import GitIndexFile
 from diffoscope.comparators.gzip import GzipFile
 from diffoscope.comparators.haskell import HiFile
 from diffoscope.comparators.icc import IccFile
@@ -166,6 +167,7 @@ FILE_CLASSES = (
     MozillaZipFile,
     ImageFile,
     CbfsFile,
+    GitIndexFile,
     )
 
 
diff --git a/diffoscope/comparators/git.py b/diffoscope/comparators/git.py
new file mode 100644
index 0000000..d78282e
--- /dev/null
+++ b/diffoscope/comparators/git.py
@@ -0,0 +1,103 @@
+# -*- coding: utf-8 -*-
+#
+# diffoscope: in-depth comparison of files, archives, and directories
+#
+# Copyright © 2016 Chris Lamb <lamby at debian.org>
+#
+# diffoscope is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# diffoscope is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with diffoscope.  If not, see <http://www.gnu.org/licenses/>.
+
+import re
+import os
+import struct
+import binascii
+
+from diffoscope.difference import Difference
+from diffoscope.comparators.binary import File
+
+
+class GitIndexFile(File):
+    RE_FILE_TYPE = re.compile(r'^Git index')
+
+    @staticmethod
+    def recognizes(file):
+        return GitIndexFile.RE_FILE_TYPE.match(file.magic_file_type)
+
+    def compare_details(self, other, source=None):
+        return [Difference.from_text(
+            describe_index(self.path),
+            describe_index(other.path),
+            self,
+            other,
+        )]
+
+def parse_index(f):
+    _, version = struct.unpack('>LL', f.read(4 * 2))
+
+    return {
+        'version': version,
+        'entries': list(parse_entries(f)),
+    }
+
+def parse_entries(f):
+    num_entries = struct.unpack('>L', f.read(4))[0]
+
+    for _ in range(num_entries):
+        x = {}
+
+        pos = f.tell()
+
+        x['ctime'], x['ctime_nano'], x['mtime'], x['mtime_nano'], \
+                x['dev'], x['inode'], x['mode'], x['uid'], x['gid'], \
+                x['size'], x['sha'], x['flags'] = \
+            struct.unpack('>LLLLLLLLLL20sH', f.read((4 * 10) + 20 + 2))
+
+        x['path'] = f.read(x['flags'] & 0x0fff)
+
+        f.read((pos + ((f.tell() - pos + 8) & ~7)) - f.tell())
+
+        yield x
+
+def describe_index(filename):
+    with open(filename, 'rb') as f:
+        index = parse_index(f)
+
+    return """
+Version: {version}
+
+Entries:
+{entries_fmt}
+""".format(
+    entries_fmt=''.join(describe_entry(x) for x in index['entries']),
+    **index
+)
+
+def describe_entry(x):
+    return """
+Path:      {x[path]}
+SHA:       {hexsha}
+Size:      {x[size]}
+Flags:     {x[flags]:#b}
+User ID:   {x[uid]}
+Group ID:  {x[gid]}
+Created:   {x[ctime]}.{x[ctime_nano]}
+Modified:  {x[mtime]}.{x[mtime_nano]}
+Inode:     {x[inode]}
+Device ID: ({major}, {minor})
+""".format(
+    x=x,
+    major=os.major(x['dev']),
+    minor=os.minor(x['dev']),
+    hexsha=binascii.b2a_hex(x['sha']).decode('utf-8'),
+)
+

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/diffoscope.git


More information about the diffoscope mailing list