changeset 8:2548735d24ef

will now more or less correctly determine a changelist from a git commit
author Scott Chacon <schacon@gmail.com>
date Sat, 25 Apr 2009 16:57:11 -0700
parents 89992b6d2eef
children 7e776864b301
files dulwich/objects.py dulwich/repo.py git_handler.py
diffstat 3 files changed, 60 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/dulwich/objects.py
+++ b/dulwich/objects.py
@@ -362,6 +362,9 @@
         """Return a list of tuples describing the tree entries"""
         return [(mode, name, hexsha) for (name, (mode, hexsha)) in self._entries.iteritems()]
 
+    def entry(self, name):
+        return self._entries[name]
+        
     def iteritems(self):
         for name in sorted(self._entries.keys()):
             yield name, self_entries[name][0], self._entries[name][1]
@@ -501,18 +504,6 @@
         self._text += "\n" # There must be a new line after the headers
         self._text += self._message
 
-    def getfile(self, f):
-        import random
-        dt = "file contents:" + str(random.randrange(1, 100))
-        print dt
-        return dt
-        
-    def getmode(self, f):
-        return ""
-
-    def getfiles(self):
-        return ['test']
-
     @property
     def tree(self):
         """Returns the tree that is the state of this commit"""
--- a/dulwich/repo.py
+++ b/dulwich/repo.py
@@ -305,6 +305,56 @@
     def get_blob(self, sha):
         return self._get_object(sha, Blob)
 
+
+    # takes a commit object and a file path
+    # returns the contents of that file at that commit
+    # TODO : make this recursive - any file in a subdir wont be found here
+    def get_file(self, commit, f):
+        otree = self.tree(commit.tree)
+        parts = f.split('/')
+        for part in parts:
+            (mode, sha) = otree.entry(part)
+            obj = self.get_object(sha)
+            if isinstance (obj, Blob):
+                return (mode, sha, obj._text)
+            elif isinstance(obj, Tree):
+                otree = obj
+
+    # takes a commit and returns an array of the files that were changed
+    # between that commit and it's parents
+    # TODO : optimize this, it's horrible
+    # TODO : if no parents, return all files
+    def get_files_changed(self, commit):        
+        
+        def filenames(basetree, comptree, prefix):
+            changes = list()
+            csha = None
+            ctree = None
+            for (bmode, bname, bsha) in basetree.entries():
+                bobj = self.get_object(bsha)
+                if comptree:
+                    (cmode, csha) = comptree.entry(bname)
+                if csha != bsha:
+                    if isinstance (bobj, Blob):
+                        changes.append (prefix + bname)
+                    elif isinstance(bobj, Tree):
+                        if csha:
+                            ctree = self.get_object(csha)
+                        changes.extend (filenames (bobj, ctree, prefix + bname + '/'))
+            # TODO: handle removals?
+            return changes
+        
+        all_changes = list()
+        otree = self.tree(commit.tree)
+        if len(commit.parents) == 0:
+            all_changes = filenames(otree, None, '')
+        for parent in commit.parents:
+            pcommit = self.commit(parent)
+            ptree = self.tree(pcommit.tree)
+            all_changes.extend(filenames(otree, ptree, ''))
+            
+        return all_changes
+
     def revision_history(self, head):
         """Returns a list of the commits reachable from head.
 
--- a/git_handler.py
+++ b/git_handler.py
@@ -81,19 +81,18 @@
         
         # import each of the commits, oldest first
         for commit in convert_list:
-            print "commit: %s" % sha
             self.import_git_commit(commit)
     
         # TODO : update Hg bookmarks (possibly named heads?)
         print bookmarks.parse(self.repo)
 
     def import_git_commit(self, commit):
-        print commit.parents
-
+        print "importing: " + commit.id
+        
         # TODO : have to handle merge contexts at some point (two parent files, etc)
         def getfilectx(repo, memctx, f):
-            data = commit.getfile(f)
-            e = commit.getmode(f)
+            (e, sha, data) = self.git.get_file(commit, f)
+            e = '' # TODO : make this a real mode
             return context.memfilectx(f, data, 'l' in e, 'x' in e, None)
         
         p1 = "0" * 40
@@ -109,7 +108,9 @@
             # TODO : map extra parents to the extras file
             pass
 
-        files = commit.getfiles()
+        files = self.git.get_files_changed(commit)
+
+        print files
 
         # get a list of the changed, added, removed files
         extra = {}