From b372e26366348920eae32ee81a47b469b511a21f Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 16 Oct 2009 19:19:57 +0200 Subject: added Diffable interface to objects.base, its used by Commit and Tree objects. Diff class has been prepared to process raw input, but its not yet more than a frame --- lib/git/objects/commit.py | 56 +---------------------------------------------- 1 file changed, 1 insertion(+), 55 deletions(-) (limited to 'lib/git/objects/commit.py') diff --git a/lib/git/objects/commit.py b/lib/git/objects/commit.py index 847f4dec..7ed38703 100644 --- a/lib/git/objects/commit.py +++ b/lib/git/objects/commit.py @@ -11,7 +11,7 @@ from tree import Tree import base import utils -class Commit(base.Object, Iterable): +class Commit(base.Object, Iterable, base.Diffable): """ Wraps a git Commit object. @@ -176,60 +176,6 @@ class Commit(base.Object, Iterable): return self.iter_items( self.repo, self, paths, **kwargs ) - @classmethod - def diff(cls, repo, a, b=None, paths=None): - """ - Creates diffs between a tree and the index or between two trees: - - ``repo`` - is the Repo - - ``a`` - is a named commit - - ``b`` - is an optional named commit. Passing a list assumes you - wish to omit the second named commit and limit the diff to the - given paths. - - ``paths`` - is a list of paths to limit the diff to. - - Returns - git.Diff[]:: - - between tree and the index if only a is given - between two trees if a and b are given and are commits - """ - paths = paths or [] - - if isinstance(b, list): - paths = b - b = None - - if paths: - paths.insert(0, "--") - - if b: - paths.insert(0, b) - paths.insert(0, a) - text = repo.git.diff('-M', full_index=True, *paths) - return diff.Diff._list_from_string(repo, text) - - @property - def diffs(self): - """ - Returns - git.Diff[] - Diffs between this commit and its first parent or all changes if this - commit is the first commit and has no parent. - """ - if not self.parents: - d = self.repo.git.show(self.id, '-M', full_index=True, pretty='raw') - return diff.Diff._list_from_string(self.repo, d) - else: - return self.diff(self.repo, self.parents[0].id, self.id) - @property def stats(self): """ -- cgit v1.2.1 From a5cf1bc1d3e38ab32a20707d66b08f1bb0beae91 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 17 Oct 2009 20:13:02 +0200 Subject: Removed a few diff-related test cases that fail now as the respective method is missing - these tests have to be redone in test-diff module accordingly --- lib/git/objects/commit.py | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/git/objects/commit.py') diff --git a/lib/git/objects/commit.py b/lib/git/objects/commit.py index 7ed38703..521130c5 100644 --- a/lib/git/objects/commit.py +++ b/lib/git/objects/commit.py @@ -214,6 +214,7 @@ class Commit(base.Object, Iterable, base.Diffable): if not hasattr(stream,'next'): stream = proc_or_stream.stdout + for line in stream: id = line.split()[1] assert line.split()[0] == "commit" -- cgit v1.2.1 From aed099a73025422f0550f5dd5c3e4651049494b2 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sun, 18 Oct 2009 12:54:16 +0200 Subject: resolved cyclic inclusion issue by moving the Diffable interface into the diff module, which probably is the right thing to do anyway --- lib/git/objects/commit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/git/objects/commit.py') diff --git a/lib/git/objects/commit.py b/lib/git/objects/commit.py index 521130c5..181cbb52 100644 --- a/lib/git/objects/commit.py +++ b/lib/git/objects/commit.py @@ -11,7 +11,7 @@ from tree import Tree import base import utils -class Commit(base.Object, Iterable, base.Diffable): +class Commit(base.Object, Iterable, diff.Diffable): """ Wraps a git Commit object. -- cgit v1.2.1 From 0b3ecf2dcace76b65765ddf1901504b0b4861b08 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 19 Oct 2009 22:49:52 +0200 Subject: commit.count: is an instance method now repo: added head , tag and iter_trees methods for completeness changes: headlines now sorted chronologically --- lib/git/objects/commit.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'lib/git/objects/commit.py') diff --git a/lib/git/objects/commit.py b/lib/git/objects/commit.py index 181cbb52..a68a7bed 100644 --- a/lib/git/objects/commit.py +++ b/lib/git/objects/commit.py @@ -101,16 +101,9 @@ class Commit(base.Object, Iterable, diff.Diffable): """ return self.message.split('\n', 1)[0] - @classmethod - def count(cls, repo, rev, paths='', **kwargs): + def count(self, paths='', **kwargs): """ - Count the number of commits reachable from this revision - - ``repo`` - is the Repo - - ``rev`` - revision specifier, see git-rev-parse for viable options + Count the number of commits reachable from this commit ``paths`` is an optinal path or a list of paths restricting the return value @@ -121,7 +114,7 @@ class Commit(base.Object, Iterable, diff.Diffable): Returns int """ - return len(repo.git.rev_list(rev, '--', paths, **kwargs).strip().splitlines()) + return len(self.repo.git.rev_list(self.id, '--', paths, **kwargs).strip().splitlines()) @classmethod def iter_items(cls, repo, rev, paths='', **kwargs): -- cgit v1.2.1 From 989671780551b7587d57e1d7cb5eb1002ade75b4 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 19 Oct 2009 23:44:18 +0200 Subject: Implemneted IterableLists for refs, commits and remote objects including simple tests --- lib/git/objects/commit.py | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/git/objects/commit.py') diff --git a/lib/git/objects/commit.py b/lib/git/objects/commit.py index a68a7bed..4080305f 100644 --- a/lib/git/objects/commit.py +++ b/lib/git/objects/commit.py @@ -23,6 +23,7 @@ class Commit(base.Object, Iterable, diff.Diffable): type = "commit" __slots__ = ("tree", "author", "authored_date", "committer", "committed_date", "message", "parents") + _id_attribute_ = "id" def __init__(self, repo, id, tree=None, author=None, authored_date=None, committer=None, committed_date=None, message=None, parents=None): -- cgit v1.2.1 From 1b89f39432cdb395f5fbb9553b56595d29e2b773 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 23 Oct 2009 16:39:02 +0200 Subject: commit.name_rev property added for convenience --- lib/git/objects/commit.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'lib/git/objects/commit.py') diff --git a/lib/git/objects/commit.py b/lib/git/objects/commit.py index 4080305f..0f8ed7f8 100644 --- a/lib/git/objects/commit.py +++ b/lib/git/objects/commit.py @@ -117,6 +117,15 @@ class Commit(base.Object, Iterable, diff.Diffable): """ return len(self.repo.git.rev_list(self.id, '--', paths, **kwargs).strip().splitlines()) + @property + def name_rev(self): + """ + Returns + String describing the commits hex sha based on the closest Reference. + Mostly useful for UI purposes + """ + return self.repo.git.name_rev(self) + @classmethod def iter_items(cls, repo, rev, paths='', **kwargs): """ -- cgit v1.2.1 From b999cae064fb6ac11a61a39856e074341baeefde Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 23 Oct 2009 23:44:49 +0200 Subject: actor: added __eq__, __ne__ and __hash__ methods including simple test commit: Fixed long-standing issue during message parsing that would fail to parse properly in case we were created from data. Also it would strip white space from the messages although it shouldn't --- lib/git/objects/commit.py | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) (limited to 'lib/git/objects/commit.py') diff --git a/lib/git/objects/commit.py b/lib/git/objects/commit.py index 4080305f..00f3d0e4 100644 --- a/lib/git/objects/commit.py +++ b/lib/git/objects/commit.py @@ -83,7 +83,7 @@ class Commit(base.Object, Iterable, diff.Diffable): # prepare our data lines to match rev-list data_lines = self.data.splitlines() data_lines.insert(0, "commit %s" % self.id) - temp = self._iter_from_process_or_stream(self.repo, iter(data_lines)).next() + temp = self._iter_from_process_or_stream(self.repo, iter(data_lines), False).next() self.parents = temp.parents self.tree = temp.tree self.author = temp.author @@ -111,7 +111,8 @@ class Commit(base.Object, Iterable, diff.Diffable): to commits actually containing the paths ``kwargs`` - Additional options to be passed to git-rev-list + Additional options to be passed to git-rev-list. They must not alter + the ouput style of the command, or parsing will yield incorrect results Returns int """ @@ -144,9 +145,8 @@ class Commit(base.Object, Iterable, diff.Diffable): options = {'pretty': 'raw', 'as_process' : True } options.update(kwargs) - # the test system might confront us with string values - proc = repo.git.rev_list(rev, '--', paths, **options) - return cls._iter_from_process_or_stream(repo, proc) + return cls._iter_from_process_or_stream(repo, proc, True) def iter_parents(self, paths='', **kwargs): """ @@ -191,7 +191,7 @@ class Commit(base.Object, Iterable, diff.Diffable): return stats.Stats._list_from_string(self.repo, text) @classmethod - def _iter_from_process_or_stream(cls, repo, proc_or_stream): + def _iter_from_process_or_stream(cls, repo, proc_or_stream, from_rev_list): """ Parse out commit information into a list of Commit objects @@ -201,6 +201,9 @@ class Commit(base.Object, Iterable, diff.Diffable): ``proc`` git-rev-list process instance (raw format) + ``from_rev_list`` + If True, the stream was created by rev-list in which case we parse + the message differently Returns iterator returning Commit objects """ @@ -208,10 +211,10 @@ class Commit(base.Object, Iterable, diff.Diffable): if not hasattr(stream,'next'): stream = proc_or_stream.stdout - for line in stream: - id = line.split()[1] - assert line.split()[0] == "commit" + commit_tokens = line.split() + id = commit_tokens[1] + assert commit_tokens[0] == "commit" tree = stream.next().split()[1] parents = [] @@ -231,13 +234,20 @@ class Commit(base.Object, Iterable, diff.Diffable): stream.next() message_lines = [] - next_line = None - for msg_line in stream: - if not msg_line.startswith(' '): - break - # END abort message reading - message_lines.append(msg_line.strip()) - # END while there are message lines + if from_rev_list: + for msg_line in stream: + if not msg_line.startswith(' '): + # and forget about this empty marker + break + # END abort message reading + # strip leading 4 spaces + message_lines.append(msg_line[4:]) + # END while there are message lines + else: + # a stream from our data simply gives us the plain message + for msg_line in stream: + message_lines.append(msg_line) + # END message parsing message = '\n'.join(message_lines) yield Commit(repo, id=id, parents=tuple(parents), tree=tree, author=author, authored_date=authored_date, -- cgit v1.2.1 From 3cb5ba18ab1a875ef6b62c65342de476be47871b Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 3 Nov 2009 16:35:33 +0100 Subject: object: renamed id attribute to sha as it in fact is always being rewritten as sha, even if the passed in id was a ref. This is done to assure objects are uniquely identified and will compare correctly --- lib/git/objects/commit.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'lib/git/objects/commit.py') diff --git a/lib/git/objects/commit.py b/lib/git/objects/commit.py index d9f87116..80b3ad23 100644 --- a/lib/git/objects/commit.py +++ b/lib/git/objects/commit.py @@ -23,9 +23,9 @@ class Commit(base.Object, Iterable, diff.Diffable): type = "commit" __slots__ = ("tree", "author", "authored_date", "committer", "committed_date", "message", "parents") - _id_attribute_ = "id" + _id_attribute_ = "sha" - def __init__(self, repo, id, tree=None, author=None, authored_date=None, + def __init__(self, repo, sha, tree=None, author=None, authored_date=None, committer=None, committed_date=None, message=None, parents=None): """ Instantiate a new Commit. All keyword arguments taking None as default will @@ -33,7 +33,7 @@ class Commit(base.Object, Iterable, diff.Diffable): The parameter documentation indicates the type of the argument after a colon ':'. - ``id`` + ``sha`` is the sha id of the commit or a ref ``parents`` : tuple( Commit, ... ) @@ -62,15 +62,15 @@ class Commit(base.Object, Iterable, diff.Diffable): Returns git.Commit """ - super(Commit,self).__init__(repo, id) + super(Commit,self).__init__(repo, sha) self._set_self_from_args_(locals()) if parents is not None: self.parents = tuple( self.__class__(repo, p) for p in parents ) # END for each parent to convert - if self.id and tree is not None: - self.tree = Tree(repo, id=tree, path='') + if self.sha and tree is not None: + self.tree = Tree(repo, tree, path='') # END id to tree conversion def _set_cache_(self, attr): @@ -82,7 +82,7 @@ class Commit(base.Object, Iterable, diff.Diffable): if attr in Commit.__slots__: # prepare our data lines to match rev-list data_lines = self.data.splitlines() - data_lines.insert(0, "commit %s" % self.id) + data_lines.insert(0, "commit %s" % self.sha) temp = self._iter_from_process_or_stream(self.repo, iter(data_lines), False).next() self.parents = temp.parents self.tree = temp.tree @@ -116,7 +116,7 @@ class Commit(base.Object, Iterable, diff.Diffable): Returns int """ - return len(self.repo.git.rev_list(self.id, '--', paths, **kwargs).strip().splitlines()) + return len(self.repo.git.rev_list(self.sha, '--', paths, **kwargs).strip().splitlines()) @property def name_rev(self): @@ -189,14 +189,14 @@ class Commit(base.Object, Iterable, diff.Diffable): git.Stats """ if not self.parents: - text = self.repo.git.diff_tree(self.id, '--', numstat=True, root=True) + text = self.repo.git.diff_tree(self.sha, '--', numstat=True, root=True) text2 = "" for line in text.splitlines()[1:]: (insertions, deletions, filename) = line.split("\t") text2 += "%s\t%s\t%s\n" % (insertions, deletions, filename) text = text2 else: - text = self.repo.git.diff(self.parents[0].id, self.id, '--', numstat=True) + text = self.repo.git.diff(self.parents[0].sha, self.sha, '--', numstat=True) return stats.Stats._list_from_string(self.repo, text) @classmethod @@ -259,15 +259,15 @@ class Commit(base.Object, Iterable, diff.Diffable): # END message parsing message = '\n'.join(message_lines) - yield Commit(repo, id=id, parents=tuple(parents), tree=tree, author=author, authored_date=authored_date, + yield Commit(repo, id, parents=tuple(parents), tree=tree, author=author, authored_date=authored_date, committer=committer, committed_date=committed_date, message=message) # END for each line in stream def __str__(self): """ Convert commit to string which is SHA1 """ - return self.id + return self.sha def __repr__(self): - return '' % self.id + return '' % self.sha -- cgit v1.2.1