Created
March 7, 2014 02:11
-
-
Save justinvh/9403749 to your computer and use it in GitHub Desktop.
A questionable revtree for dulwich
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| def revtree(self, sha=None): | |
| # We need to first traverse the tree and construct a state that | |
| # we can render to the end-user. This tree will be stored as a | |
| # JSON object on the commit message | |
| tree = {} | |
| seen = set() | |
| sha = sha or self.repo.head() | |
| for walker in self.repo.get_walker(include=[sha]): | |
| # Walk the commit and convert it into something usable | |
| commit = commit_as_dict(walker.commit) | |
| for change in walker.changes(): | |
| if not hasattr(change, 'new'): | |
| continue | |
| path = change.new.path | |
| if not path or path in seen: | |
| continue | |
| seen.add(path) | |
| dirs, filename = os.path.split(path) | |
| dirs = dirs.split('/') if len(dirs) else [] | |
| blob = change.new.sha | |
| entry = {'commit': commit, | |
| 'blob': blob, | |
| 'type': 'file', | |
| 'path': path, | |
| 'tree': {}} | |
| # Construct a top-level descriptor | |
| if not dirs: | |
| tree[filename] = entry | |
| continue | |
| # Construct a tree with all the parts | |
| rel_tree = tree | |
| for part in dirs: | |
| if not rel_tree.get(part): | |
| rel_tree[part] = {'commit': commit, | |
| 'type': 'folder', | |
| 'tree': {}} | |
| rel_tree = rel_tree[part]['tree'] | |
| rel_tree[filename] = entry | |
| # Now reorganize the tree so when we display it then the tree | |
| # will display folder ABC -> files ABC | |
| ordered_tree = OrderedDict() | |
| modified_tree = ordered_tree | |
| def process_tree(tr, ot): | |
| stack, files, folders = [], [], [] | |
| # Iterate through the current tree object | |
| for name, obj in tr.iteritems(): | |
| if obj['type'] == 'folder': | |
| folders.append((name, obj)) | |
| stack.append(name) | |
| else: | |
| files.append((name, obj)) | |
| # Construct the ordered parameters of the tree | |
| for name, obj in sorted(folders): | |
| ot[name] = obj | |
| # Construct the ordered parameters of the tree | |
| for name, obj in sorted(files): | |
| ot[name] = obj | |
| # Repeat the process for the new node | |
| for item in stack: | |
| process_tree(tr[item]['tree'], ot[item]['tree']) | |
| process_tree(tree, modified_tree) | |
| return ordered_tree |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment