Browse Source

Add a simple GIT index file parser, and a dump-index command.

Jelmer Vernooij 16 years ago
parent
commit
bc2075de96
2 changed files with 82 additions and 0 deletions
  1. 18 0
      bin/dulwich
  2. 64 0
      dulwich/index.py

+ 18 - 0
bin/dulwich

@@ -98,6 +98,23 @@ def cmd_dump_pack(args):
 		except ApplyDeltaError, e:
 			print "\t%s: Unable to apply delta: %r" % (name, e)
 
+
+def cmd_dump_index(args):
+	from dulwich.index import Index
+
+	opts, args = getopt(args, "", [])
+
+	if args == []:
+		print "Usage: dulwich dump-pack FILENAME"
+		sys.exit(1)
+
+	filename = args[0]
+	idx = Index(filename)
+
+	for o in idx:
+		print o[0]
+
+
 def cmd_init(args):
 	from dulwich.repo import Repo
 	import os
@@ -162,6 +179,7 @@ def cmd_clone(args):
 commands = {
 	"fetch-pack": cmd_fetch_pack,
 	"dump-pack": cmd_dump_pack,
+	"dump-index": cmd_dump_index,
 	"init": cmd_init,
 	"log": cmd_log,
 	"clone": cmd_clone,

+ 64 - 0
dulwich/index.py

@@ -0,0 +1,64 @@
+# index.py -- File parser/write for the git index file
+# Copryight (C) 2008 Jelmer Vernooij <jelmer@samba.org>
+ 
+# This program 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; version 2
+# of the License or (at your opinion) any later version of the license.
+# 
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA  02110-1301, USA.
+
+"""Parser for the git index file format."""
+
+import struct
+
+def read_cache_time(f):
+    return struct.unpack(">LL", f.read(8))
+
+
+def read_cache_entry(f):
+    beginoffset = f.tell()
+    ctime = read_cache_time(f)
+    mtime = read_cache_time(f)
+    (ino, dev, mode, uid, gid, size, sha, flags, ) = \
+        struct.unpack(">LLLLLL20sH", f.read(20 + 4 * 6 + 2))
+    name = ""
+    char = ord(f.read(1))
+    while char != 0:
+        name += chr(char)
+        char = ord(f.read(1))
+    # Padding:
+    real_size = ((f.tell() - beginoffset + 8) & ~7)
+    f.seek(beginoffset + real_size)
+    return (name, ctime, mtime, ino, dev, mode, uid, gid, size, sha, flags)
+
+class Index(object):
+
+    def __init__(self, filename):
+        f = open(filename, 'r')
+        try:
+            assert f.read(4) == "DIRC"
+            (version, self._num_entries) = struct.unpack(">LL", f.read(4 * 2))
+            assert version in (1, 2)
+            self._entries = []
+            for i in range(len(self)):
+                self._entries.append(read_cache_entry(f))
+        finally:
+            f.close()
+
+    def __len__(self):
+        return self._num_entries
+
+    def items(self):
+        return list(self._entries)
+
+    def __iter__(self):
+        return iter(self._entries)