From f963881e53a9f0a2746a11cb9cdfa82eb1f90d8c Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jul 2010 00:35:30 +0200 Subject: Initial version of the rev-parse routine, which doesn't work too bad, but its still rather slow and many tests are not yet implemented --- lib/git/refs.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'lib/git/refs.py') diff --git a/lib/git/refs.py b/lib/git/refs.py index 343a0afb..a466e419 100644 --- a/lib/git/refs.py +++ b/lib/git/refs.py @@ -68,7 +68,7 @@ class SymbolicReference(object): :return: In case of symbolic references, the shortest assumable name is the path itself.""" - return self.path + return self.path def _abs_path(self): return join_path_native(self.repo.git_dir, self.path) @@ -109,6 +109,19 @@ class SymbolicReference(object): # I believe files are closing themselves on destruction, so it is # alright. + @classmethod + def dereference_recursive(cls, repo, ref_path): + """ + :return: hexsha stored in the reference at the given ref_path, recursively dereferencing all + intermediate references as required + :param repo: the repository containing the reference at ref_path""" + while True: + ref = cls(repo, ref_path) + hexsha, ref_path = ref._get_ref_info() + if hexsha is not None: + return hexsha + # END recursive dereferencing + def _get_ref_info(self): """Return: (sha, target_ref_path) if available, the sha the file at rela_path points to, or None. target_ref_path is the reference we @@ -794,6 +807,10 @@ class TagReference(Reference): else: raise ValueError( "Tag %s points to a Blob or Tree - have never seen that before" % self ) + @property + def tree(self): + return self.commit.tree + @property def tag(self): """ -- cgit v1.2.1 From 1c6d7830d9b87f47a0bfe82b3b5424a32e3164ad Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jul 2010 10:46:02 +0200 Subject: RevParse now generally works, but there are still some more specialized tests missing --- lib/git/refs.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'lib/git/refs.py') diff --git a/lib/git/refs.py b/lib/git/refs.py index a466e419..23d45ed0 100644 --- a/lib/git/refs.py +++ b/lib/git/refs.py @@ -807,10 +807,6 @@ class TagReference(Reference): else: raise ValueError( "Tag %s points to a Blob or Tree - have never seen that before" % self ) - @property - def tree(self): - return self.commit.tree - @property def tag(self): """ -- cgit v1.2.1 From a32a6bcd784fca9cb2b17365591c29d15c2f638e Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jul 2010 11:16:49 +0200 Subject: Refs now use object.new_from_sha where possible, preventing git-batch-check to be started up for sha resolution --- lib/git/refs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/git/refs.py') diff --git a/lib/git/refs.py b/lib/git/refs.py index 23d45ed0..8b773ae7 100644 --- a/lib/git/refs.py +++ b/lib/git/refs.py @@ -210,7 +210,7 @@ class SymbolicReference(object): except AttributeError: sha = str(ref) try: - obj = Object.new(self.repo, sha) + obj = Object.new_from_sha(self.repo, hex_to_bin(sha)) if obj.type != "commit": raise TypeError("Invalid object type behind sha: %s" % sha) write_value = obj.hexsha @@ -536,7 +536,7 @@ class Reference(SymbolicReference, LazyMixin, Iterable): always point to the actual object as it gets re-created on each query""" # have to be dynamic here as we may be a tag which can point to anything # Our path will be resolved to the hexsha which will be used accordingly - return Object.new(self.repo, self.path) + return Object.new_from_sha(self.repo, hex_to_bin(self.dereference_recursive(self.repo, self.path))) def _set_object(self, ref): """ -- cgit v1.2.1 From 9059525a75b91e6eb6a425f1edcc608739727168 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 6 Jul 2010 20:21:52 +0200 Subject: Made repo.py a package to allow better localization of functions and utilities - the repo module got rather large --- lib/git/refs.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib/git/refs.py') diff --git a/lib/git/refs.py b/lib/git/refs.py index 8b773ae7..be094d01 100644 --- a/lib/git/refs.py +++ b/lib/git/refs.py @@ -208,9 +208,8 @@ class SymbolicReference(object): try: write_value = ref.commit.hexsha except AttributeError: - sha = str(ref) try: - obj = Object.new_from_sha(self.repo, hex_to_bin(sha)) + obj = self.repo.rev_parse(ref+"^{}") # optionally deref tags if obj.type != "commit": raise TypeError("Invalid object type behind sha: %s" % sha) write_value = obj.hexsha -- cgit v1.2.1 From bc31651674648f026464fd4110858c4ffeac3c18 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 7 Jul 2010 17:30:47 +0200 Subject: Adjusted previous object creators to use the rev_parse method directly. rev_parse could be adjusted not to return Objects anymore, providing better performance for those who just want a sha only. On the other hand, the method is high-level and should be convenient to use as well, its a starting point for more usually, hence its unlikely to call it in tight loops --- lib/git/refs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/git/refs.py') diff --git a/lib/git/refs.py b/lib/git/refs.py index be094d01..03b80690 100644 --- a/lib/git/refs.py +++ b/lib/git/refs.py @@ -345,7 +345,7 @@ class SymbolicReference(object): # figure out target data target = reference if resolve: - target = Object.new(repo, reference) + target = repo.rev_parse(str(reference)) if not force and isfile(abs_ref_path): target_data = str(target) -- cgit v1.2.1