From b377c07200392ac35a6ed668673451d3c9b1f5c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steve=20Fr=C3=A9cinaux?= Date: Fri, 5 Sep 2008 21:51:14 +0200 Subject: Use a dictionnary for tree contents It seems more natural to use a dictionnary for directories, since we usually want to access them by name, and entry order is not relevant. Also, finding a particular blob given its name is O(1) instead of O(N). --- lib/git/tree.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'lib/git/tree.py') diff --git a/lib/git/tree.py b/lib/git/tree.py index f1aa0b3b..86e893ef 100644 --- a/lib/git/tree.py +++ b/lib/git/tree.py @@ -32,13 +32,13 @@ class Tree(LazyMixin): def construct_initialize(self, repo, id, text): self.repo = repo self.id = id - self.contents = [] + self.contents = {} self.__baked__ = False for line in text.splitlines(): - self.contents.append(self.content_from_string(self.repo, line)) - - self.contents = [c for c in self.contents if c is not None] + obj = self.content_from_string(self.repo, line) + if obj: + self.contents[obj.name] = obj self.__bake_it__() return self @@ -84,8 +84,7 @@ class Tree(LazyMixin): Returns ``GitPython.Blob`` or ``GitPython.Tree`` or ``None`` if not found """ - contents = [c for c in self.contents if c.name == file] - return contents and contents[0] or None + return self.contents.get(file) @property def basename(self): -- cgit v1.2.1 From 43eb1edf93c381bf3f3809a809df33dae23b50d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steve=20Fr=C3=A9cinaux?= Date: Fri, 5 Sep 2008 23:04:58 +0200 Subject: Initialize trees completely in tree.__bake__(). This is a simplification of the tree baking code. As a matter of consequency, Tree.construct() and tree.construct_initialize() have been killed, and repo.tree() has lost the "paths" argument. This is not a problem since one can just have the same result with: dict(k, o for k, o in tree.items() if k in paths) --- lib/git/tree.py | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) (limited to 'lib/git/tree.py') diff --git a/lib/git/tree.py b/lib/git/tree.py index 86e893ef..1ed3396d 100644 --- a/lib/git/tree.py +++ b/lib/git/tree.py @@ -21,28 +21,18 @@ class Tree(LazyMixin): setattr(self, k, v) def __bake__(self): - temp = Tree.construct(self.repo, self.id) - self.contents = temp.contents + # Ensure the treeish references directly a tree + treeish = self.id + if not treeish.endswith(':'): + treeish = treeish + ':' - @classmethod - def construct(cls, repo, treeish, paths = []): - output = repo.git.ls_tree(treeish, *paths) - return Tree(repo, id=treeish).construct_initialize(repo, treeish, output) - - def construct_initialize(self, repo, id, text): - self.repo = repo - self.id = id + # Read the tree contents. self.contents = {} - self.__baked__ = False - - for line in text.splitlines(): + for line in self.repo.git.ls_tree(self.id).splitlines(): obj = self.content_from_string(self.repo, line) if obj: self.contents[obj.name] = obj - self.__bake_it__() - return self - def content_from_string(self, repo, text): """ Parse a content item and create the appropriate object -- cgit v1.2.1 From 0425bc64384fe9a6a22edb7831d6e8c1756e2c7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steve=20Fr=C3=A9cinaux?= Date: Sat, 6 Sep 2008 00:10:12 +0200 Subject: Implement dict protocol for trees. It is rather intuitive to consider trees as a dict of objects (like a directory could be seen as a dict of files). --- lib/git/tree.py | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) (limited to 'lib/git/tree.py') diff --git a/lib/git/tree.py b/lib/git/tree.py index 1ed3396d..630fa1fc 100644 --- a/lib/git/tree.py +++ b/lib/git/tree.py @@ -15,7 +15,7 @@ class Tree(LazyMixin): self.id = None self.mode = None self.name = None - self.contents = None + self._contents = None for k, v in kwargs.items(): setattr(self, k, v) @@ -27,11 +27,11 @@ class Tree(LazyMixin): treeish = treeish + ':' # Read the tree contents. - self.contents = {} + self._contents = {} for line in self.repo.git.ls_tree(self.id).splitlines(): obj = self.content_from_string(self.repo, line) - if obj: - self.contents[obj.name] = obj + if obj is not None: + self._contents[obj.name] = obj def content_from_string(self, repo, text): """ @@ -74,7 +74,7 @@ class Tree(LazyMixin): Returns ``GitPython.Blob`` or ``GitPython.Tree`` or ``None`` if not found """ - return self.contents.get(file) + return self.get(file) @property def basename(self): @@ -82,3 +82,29 @@ class Tree(LazyMixin): def __repr__(self): return '' % self.id + + # Implement the basics of the dict protocol: + # directories/trees can be seen as object dicts. + def __getitem__(self, key): + return self._contents[key] + + def __iter__(self): + return iter(self._contents) + + def __len__(self, keys): + return len(self._contents) + + def __contains__(self, key): + return key in self._contents + + def get(self, key): + return self._contents.get(key) + + def items(self): + return self._contents.items() + + def keys(self): + return self._contents.keys() + + def values(self): + return self._contents.values() -- cgit v1.2.1 From 2f6a6e35d003c243968cdb41b72fbbe609e56841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steve=20Fr=C3=A9cinaux?= Date: Sat, 6 Sep 2008 00:34:18 +0200 Subject: Make Tree.content_from_string a static method. It doesn't use an object's private contents, so let's go... --- lib/git/tree.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/git/tree.py') diff --git a/lib/git/tree.py b/lib/git/tree.py index 630fa1fc..59d3af1e 100644 --- a/lib/git/tree.py +++ b/lib/git/tree.py @@ -33,7 +33,8 @@ class Tree(LazyMixin): if obj is not None: self._contents[obj.name] = obj - def content_from_string(self, repo, text): + @staticmethod + def content_from_string(repo, text): """ Parse a content item and create the appropriate object -- cgit v1.2.1 From c8c50d8be2dc5ae74e53e44a87f580bf25956af9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steve=20Fr=C3=A9cinaux?= Date: Sat, 6 Sep 2008 00:35:04 +0200 Subject: Do not use **kwargs for constructors. It is better to have an explicit list of variables for the constructors, be it only to avoid mispelled arguments. --- lib/git/tree.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'lib/git/tree.py') diff --git a/lib/git/tree.py b/lib/git/tree.py index 59d3af1e..dbd78ac4 100644 --- a/lib/git/tree.py +++ b/lib/git/tree.py @@ -9,17 +9,14 @@ from lazy import LazyMixin import blob class Tree(LazyMixin): - def __init__(self, repo, **kwargs): + def __init__(self, repo, id, mode=None, name=None): LazyMixin.__init__(self) self.repo = repo - self.id = None - self.mode = None - self.name = None + self.id = id + self.mode = mode + self.name = name self._contents = None - for k, v in kwargs.items(): - setattr(self, k, v) - def __bake__(self): # Ensure the treeish references directly a tree treeish = self.id -- cgit v1.2.1