remove .fns file for removed host burns
[build-farm.git] / buildfarm / history.py
index ffe392f4e2b345f592a1e44d72c6e1cfb66e89a3..1d00b758df107654034b7f3247f0e233d60bcf03 100644 (file)
 from cStringIO import StringIO
 
 from dulwich.objects import Tree
-from dulwich.patch import write_blob_diff
+from dulwich.patch import write_tree_diff
 from dulwich.repo import Repo
 
 
 class Branch(object):
     """A version control branch."""
 
-    def authors(self):
-        """Determine all authors that have contributed to this project.
-        """
-        ret = set()
-        for rev in self.log():
-            ret.add(rev.author)
-        return ret
-
-    def log(self):
+    def log(self, limit=None):
         raise NotImplementedError(self.log)
 
     def diff(self, revision):
         raise NotImplementedError(self.diff)
 
+    def changes_summary(self, revision):
+        raise NotImplementedError(self.changes_summary)
+
 
 class Revision(object):
 
-    def __init__(self, revision, date, author, message, modified=[], added=[],
-            removed=[]):
+    def __init__(self, revision, date, committer, author, message):
         self.revision = revision
         self.date = date
         self.author = author
+        self.committer = committer
         self.message = message
-        self.modified = modified
-        self.added = added
-        self.removed = removed
 
 
-class GitBranch(object):
+class GitBranch(Branch):
 
     def __init__(self, path, branch="master"):
         self.repo = Repo(path)
@@ -72,29 +64,19 @@ class GitBranch(object):
         return self.store.tree_changes(parent_tree, commit.tree)
 
     def _revision_from_commit(self, commit):
-        added = set()
-        modified = set()
-        removed = set()
-        for ((oldpath, newpath), (oldmode, newmode), (oldsha, newsha)) in self._changes_for(commit):
-            if oldpath is None:
-                added.add(newpath)
-            elif newpath is None:
-                removed.add(oldpath)
-            else:
-                modified.add(newpath)
-        return Revision(commit.id, commit.commit_time, commit.author,
-            commit.message, modified=modified, removed=removed,
-            added=added)
+        return Revision(commit.id, commit.commit_time,
+            committer=commit.committer, author=commit.author,
+            message=commit.message)
 
-    def log(self, from_rev=None, exclude_revs=None):
+    def log(self, from_rev=None, exclude_revs=None, limit=None):
+        if exclude_revs is None:
+            exclude_revs = set()
         if from_rev is None:
             try:
                 commit = self.repo["refs/heads/%s" % self.branch]
             except KeyError:
                 return
             from_rev = commit.id
-        else:
-            from_rev = commit.id
         done = set()
         pending_commits = [from_rev]
         while pending_commits != []:
@@ -102,17 +84,36 @@ class GitBranch(object):
              commit = self.repo[commit_id]
              yield self._revision_from_commit(commit)
              done.add(commit.id)
+             if len(done) >= limit:
+                 return
+             exclude_revs.add(commit.id)
              # FIXME: Add sorted by commit_time
              for p in commit.parents:
-                 if exclude_revs is not None and p in exclude_revs:
+                 if p in exclude_revs:
                      continue
                  pending_commits.append(p)
+                 exclude_revs.add(p)
+
+    def changes_summary(self, revision):
+        commit = self.repo[revision]
+        added = set()
+        modified = set()
+        removed = set()
+        for ((oldpath, newpath), (oldmode, newmode), (oldsha, newsha)) in self._changes_for(commit):
+            if oldpath is None:
+                added.add(newpath)
+            elif newpath is None:
+                removed.add(oldpath)
+            else:
+                modified.add(newpath)
+        return (added, modified, removed)
 
     def diff(self, revision):
         commit = self.repo[revision]
         f = StringIO()
-        changes = self._changes_for(commit)
-        for (oldpath, newpath), (oldmode, newmode), (oldsha, newsha) in changes:
-            write_blob_diff(f, (oldpath, oldmode, self.store[oldsha]),
-                            (newpath, newmode, self.store[newsha]))
+        if len(commit.parents) == 0:
+            parent_tree = Tree().id
+        else:
+            parent_tree = self.store[commit.parents[0]].tree
+        write_tree_diff(f, self.store, parent_tree, commit.tree)
         return (self._revision_from_commit(commit), f.getvalue())