diff options
author | Sebastian Thiel <byronimo@gmail.com> | 2009-11-26 11:49:58 +0100 |
---|---|---|
committer | Sebastian Thiel <byronimo@gmail.com> | 2009-11-26 12:09:23 +0100 |
commit | aaeb986f3a09c1353bdf50ab23cca8c53c397831 (patch) | |
tree | 6f0575dab0a2cd04558d854cc62d99e1fe93bd0f | |
parent | 9c92df685d6c600a0a3324dff08a4d00d829a4f5 (diff) | |
download | gitpython-aaeb986f3a09c1353bdf50ab23cca8c53c397831.tar.gz |
SymbolicReferences can now be at any path within the repository, there is no restriction anymore.
Added a test to assure the git commands can handle it
-rw-r--r-- | lib/git/cmd.py | 2 | ||||
-rw-r--r-- | lib/git/index.py | 6 | ||||
-rw-r--r-- | lib/git/refs.py | 37 | ||||
-rw-r--r-- | test/git/test_refs.py | 30 |
4 files changed, 48 insertions, 27 deletions
diff --git a/lib/git/cmd.py b/lib/git/cmd.py index bccfb611..6ee8f355 100644 --- a/lib/git/cmd.py +++ b/lib/git/cmd.py @@ -344,7 +344,7 @@ class Git(object): """ tokens = header_line.split() if len(tokens) != 3: - raise ValueError("SHA named %s could not be resolved" % tokens[0] ) + raise ValueError("SHA named %s could not be resolved, git returned: %r" % (tokens[0], header_line.strip()) ) if len(tokens[0]) != 40: raise ValueError("Failed to parse header: %r" % header_line) return (tokens[0], tokens[1], int(tokens[2])) diff --git a/lib/git/index.py b/lib/git/index.py index 61307bb8..f4aa26c7 100644 --- a/lib/git/index.py +++ b/lib/git/index.py @@ -1039,10 +1039,6 @@ class IndexFile(LazyMixin, diff.Diffable): If None, all paths in the index will be checked out. Otherwise an iterable of relative or absolute paths or a single path pointing to files or directories in the index is expected. - The command will raise of files or directories do not exist in the index - ( as opposed to the original git command who ignores them ). Additionally - this command allows to checkout directories which is an extension to git-update-index. - ``force`` If True, existing files will be overwritten even if they contain local modifications. @@ -1064,6 +1060,8 @@ class IndexFile(LazyMixin, diff.Diffable): Raise CheckoutError If at least one file failed to be checked out. This is a summary, hence it will checkout as many files as it can anyway. + If one of files or directories do not exist in the index + ( as opposed to the original git command who ignores them ). Raise GitCommandError if error lines could not be parsed - this truly is an exceptional state """ diff --git a/lib/git/refs.py b/lib/git/refs.py index b0996878..3d9fa226 100644 --- a/lib/git/refs.py +++ b/lib/git/refs.py @@ -43,7 +43,7 @@ class Reference(LazyMixin, Iterable): return '<git.%s "%s">' % (self.__class__.__name__, self.path) def __eq__(self, other): - return self.path == other.path and self.object == other.object + return self.path == other.path def __ne__(self, other): return not ( self == other ) @@ -203,34 +203,29 @@ class SymbolicReference(object): A typical example for a symbolic reference is HEAD. """ - __slots__ = ("repo", "name") + __slots__ = ("repo", "path") - def __init__(self, repo, name): - if '/' in name: - # NOTE: Actually they can be looking like ordinary refs. Theoretically we handle this - # case incorrectly - raise ValueError("SymbolicReferences are not located within a directory, got %s" % name) - # END error handling + def __init__(self, repo, path): self.repo = repo - self.name = name + self.path = path def __str__(self): - return self.name + return self.path def __repr__(self): - return '<git.%s "%s">' % (self.__class__.__name__, self.name) + return '<git.%s "%s">' % (self.__class__.__name__, self.path) def __eq__(self, other): - return self.name == other.name + return self.path == other.path def __ne__(self, other): return not ( self == other ) def __hash__(self): - return hash(self.name) + return hash(self.path) def _get_path(self): - return join_path_native(self.repo.path, self.name) + return join_path_native(self.repo.path, self.path) def _get_commit(self): """ @@ -311,7 +306,7 @@ class SymbolicReference(object): # checking # Otherwise we detach it and have to do it manually if write_value.startswith('ref:'): - self.repo.git.symbolic_ref(self.name, write_value[5:]) + self.repo.git.symbolic_ref(self.path, write_value[5:]) return # END non-detached handling @@ -346,6 +341,10 @@ class SymbolicReference(object): Return Instance of SymbolicReference or HEAD depending on the given path + + Note + It enforces that symbolic refs in git are only found in the + root of the .git repository, never within a folder. """ if not path: raise ValueError("Cannot create Symbolic Reference from %r" % path) @@ -366,10 +365,10 @@ class HEAD(SymbolicReference): _HEAD_NAME = 'HEAD' __slots__ = tuple() - def __init__(self, repo, name=_HEAD_NAME): - if name != self._HEAD_NAME: - raise ValueError("HEAD instance must point to %r, got %r" % (self._HEAD_NAME, name)) - super(HEAD, self).__init__(repo, name) + def __init__(self, repo, path=_HEAD_NAME): + if path != self._HEAD_NAME: + raise ValueError("HEAD instance must point to %r, got %r" % (self._HEAD_NAME, path)) + super(HEAD, self).__init__(repo, path) def reset(self, commit='HEAD', index=True, working_tree = False, diff --git a/test/git/test_refs.py b/test/git/test_refs.py index 8fa30aa1..1eceb162 100644 --- a/test/git/test_refs.py +++ b/test/git/test_refs.py @@ -10,6 +10,7 @@ from git import * import git.refs as refs from git.objects.tag import TagObject from itertools import chain +import os class TestRefs(TestBase): @@ -63,7 +64,7 @@ class TestRefs(TestBase): types_found = set() for ref in self.rorepo.refs: types_found.add(type(ref)) - assert len(types_found) == 3 + assert len(types_found) == 4 @with_rw_repo('0.1.6') def test_head_reset(self, rw_repo): @@ -233,7 +234,30 @@ class TestRefs(TestBase): self.failUnlessRaises(GitCommandError, far_away_head.checkout) assert active_branch == active_branch.checkout(force=True) + # test symbolic references which are not at default locations like HEAD + # or FETCH_HEAD - they may also be at spots in refs of course + symbol_ref_path = "refs/symbol_ref" + symref = SymbolicReference(rw_repo, symbol_ref_path) + assert symref.path == symbol_ref_path + symbol_ref_abspath = os.path.join(rw_repo.path, symref.path) + + # set it + symref.reference = new_head + assert symref.reference == new_head + assert os.path.isfile(symbol_ref_abspath) + assert symref.commit == new_head.commit + # test ref listing - assure we have packed refs - rw_repo.git.pack_refs(all=True) - assert rw_repo.heads + rw_repo.git.pack_refs(all=True, prune=True) + heads = rw_repo.heads + assert heads + assert new_head in heads + assert active_branch in heads assert rw_repo.tags + + # NOTE: It appears git-cat-file cannot resolve refs which are packed ! + # At least it fails here for some reason + # Couldn't reproduce the bug in a simple example though ... lets see. + self.failUnlessRaises(ValueError, getattr, new_head, 'commit') + self.failUnlessRaises(ValueError, getattr, symref, "commit") + |