0
@@ -773,6 +773,186 @@ def git(cmd, *args, **kwargs):
0
if not kwargs.has_key('ignore_output'):
0
return proc.stdout.read()[:-1]
0
+ """Abstracts a reference to a data file within a Git repository. It also
0
+ maintains knowledge of whether the object has been modified or not."""
0
+ def __init__(self, shelf, path, hash = None):
0
+ assert self.hash is not None
0
+ self.data = git('cat-file', 'blob', self.hash)
0
+ def set_data(self, data):
0
+ def __getstate__(self):
0
+ odict = self.__dict__.copy() # copy the dict since we change it
0
+ del odict['dirty'] # remove dirty flag
0
+ def __setstate__(self,dict):
0
+ self.__dict__.update(dict) # update attributes
0
+ """This class implements a Python "shelf" using a branch within a Git
0
+ repository. There is no "writeback" argument, meaning changes are only
0
+ written upon calling close or sync.
0
+ This implementation uses a dictionary of gitbook objects, since we don't
0
+ really want to use Pickling within a Git repository (it's not friendly to
0
+ other Git users, nor does it support merging)."""
0
+ ls_tree_pat = re.compile('(040000 tree|100644 blob) ([0-9a-f]{40})\t(start|(.+))$')
0
+ def __init__(self, branch):
0
+ def create_branch(self, cmd, args, kwargs):
0
+ """If an issues branch already exists at the remote, we simply refer
0
+ to it from now on. Otherwise, we create a dummy commit in order get
0
+ hash = git('rev-parse', 'origin/%s' % self.branch,
0
+ msg = "Created %s branch\n" % self.branch
0
+ hash = git('hash-object', '-w', '--stdin', input = msg)
0
+ hash = git('mktree', input = "100644 blob %s\tstart\n" % hash)
0
+ hash = git('commit-tree', hash, input = msg)
0
+ git('branch', self.branch, hash)
0
+ def current_head(self):
0
+ return git('rev-parse', self.branch, restart = self.create_branch)
0
+ def open(cls, branch):
0
+ shelf = gitshelve(branch)
0
+ ls_tree = string.split(git('ls-tree', '-r', '-t', '-z',
0
+ self.current_head()), '\0')
0
+ match = cls.ls_tree_pat.match(line)
0
+ if match.group(1) == "040000 tree":
0
+ parts = os.path.split(path)
0
+ if not dict.has_key(part):
0
+ dict['__root__'] = hash
0
+ assert not shelf.paths.has_key(path)
0
+ shelf.paths[path] = gitbook(shelf, path, hash)
0
+ open = classmethod(open)
0
+ for book in self.paths:
0
+ def sync_book(self, book):
0
+ # Create a unique blob to represent the new issue. This is the
0
+ # issue's official object name from now on, and will never change.
0
+ blob = git('hash-object', '-w', '--stdin', input = repr(book))
0
+ tree = git('mktree', input = "100644 blob %s\tinfo\n" % blob)
0
+ # Merge this blob with existing issue blobs that share the same
0
+ # first two hash digits
0
+ if self.trees.has_key(blob[:2]):
0
+ parent = self.trees[blob[:2]]
0
+ self.trees[blob[:2]] = parent
0
+ parent.append((tree, blob[2:]))
0
+ for child in parent[1:]:
0
+ buffer.write("040000 tree %s\t%s\n" % (child[0], child[1]))
0
+ tree = git('mktree', input = buffer.getvalue())
0
+ self.trees[blob[:2]][0] = tree
0
+ # Merge it into the tree of issues overall
0
+ keys = self.trees.keys()
0
+ buffer.write("040000 tree %s\t%s\n" % (self.trees[key][0], key))
0
+ tree = git('mktree', input = buffer.getvalue())
0
+ # Commit the merged tree (though at this moment it's a dangling commit)
0
+ commit = git('commit-tree', tree, '-p', self.current_head(),
0
+ # Update the head of the issues branch to point to the new commit
0
+ self.update_head(commit)
0
+ del self.objects # free it up right away
0
+ def __getitem__(self, path):
0
+ return self.paths[path].data()
0
+ def __setitem__(self, path, data):
0
+ if not self.paths.has_key(path):
0
+ self.paths[path] = gitbook(self, path)
0
+ self.paths[path].set_data(data)
0
+ def __detitem__(self, path):
0
+ def __contains__(self, path):
0
+ return self.paths.has_key()
0
class GitIssueSet(IssueSet):
0
"""This object implements all the command necessary to interact with Git
0
for the purpose of storing and distributing issues."""
0
@@ -941,129 +1121,131 @@ def get_issue(issueSet, id):
0
######################################################################
0
- print "Show help here."
0
+if __name__ == '__main__':
0
+ print "Show help here."
0
######################################################################
0
-# jww (2008-05-12): Pick the appropriate IssueSet to used based on what we
0
-# find in our environment.
0
+ # jww (2008-05-12): Pick the appropriate IssueSet to used based on what we
0
+ # find in our environment.
0
-
issueSet = IssueSet.load_state(GitIssueSet())
0
+
issueSet = IssueSet.load_state(GitIssueSet())
0
######################################################################
0
- print " # Id Title State Date Assign Tags"
0
- print "-------------------------------------------------------------------------------"
0
+ print " # Id Title State Date Assign Tags"
0
+ print "-------------------------------------------------------------------------------"
0
- for name in issueSet.issues.keys():
0
- issue = issueSet.issues[name]
0
+ for name in issueSet.issues.keys():
0
+ issue = issueSet.issues[name]
0
- print "%4d %s %-23s %-6s %5s %6s %s" % \
0
- (index, issue.name[:7], issue.title, issue.status,
0
- issue.created and issue.created.strftime('%m/%d'),
0
- str(issue.author)[:6], '')
0
+ print "%4d %s %-23s %-6s %5s %6s %s" % \
0
+ (index, issue.name[:7], issue.title, issue.status,
0
+ issue.created and issue.created.strftime('%m/%d'),
0
+ str(issue.author)[:6], '')
0
######################################################################
0
-elif command == "show" or command == "dump":
0
- print "Shows needs an index or Id."
0
- issue = get_issue(issueSet, args[0])
0
- issue.format_long_text(issue.summary),
0
- issue.format_long_text(issue.description),
0
- issue.format_people_list(issue.reporters),
0
- issue.format_people_list(issue.owners),
0
- issue.format_people_list(issue.assigned),
0
- issue.format_people_list(issue.carbons),
0
- issue.resolution or "",
0
- issue.components or "",
0
- issue.milestone or "",
0
+ elif command == "show" or command == "dump":
0
+ print "Shows needs an index or Id."
0
+ issue = get_issue(issueSet, args[0])
0
+ issue.format_long_text(issue.summary),
0
+ issue.format_long_text(issue.description),
0
+ issue.format_people_list(issue.reporters),
0
+ issue.format_people_list(issue.owners),
0
+ issue.format_people_list(issue.assigned),
0
+ issue.format_people_list(issue.carbons),
0
+ issue.resolution or "",
0
+ issue.components or "",
0
+ issue.milestone or "",
0
######################################################################
0
-elif command == "change":
0
- print "Change needs an issue."
0
+ elif command == "change":
0
+ print "Change needs an issue."
0
-
issue = get_issue(issueSet, args[0])
0
+
issue = get_issue(issueSet, args[0])
0
- # jww (2008-05-13): Need to parse datetime, lists, and people
0
- eval ("issue.set_%s(\"%s\")" % (args[1], args[2]))
0
+ # jww (2008-05-13): Need to parse datetime, lists, and people
0
+ eval ("issue.set_%s(\"%s\")" % (args[1], args[2]))
0
######################################################################
0
- print "New needs a title."
0
+ elif command == "new":
0
+ print "New needs a title."
0
- issue = Issue(issueSet, issueSet.current_author(), args[0])
0
- issueSet.add_issue(issue)
0
- issue.mark_dirty(True)
0
+ issue = Issue(issueSet, issueSet.current_author(), args[0])
0
+ issueSet.add_issue(issue)
0
+ issue.mark_dirty(True)
0
######################################################################
0
-# If any of the commands made the issueSet dirty, (possibly) update the
0
-# repository and write out a new cache
0
+ # If any of the commands made the issueSet dirty, (possibly) update the
0
+ # repository and write out a new cache
0
######################################################################
Comments
No one has commented yet.