diff options
-rw-r--r-- | lib/git/refs.py | 4 | ||||
-rw-r--r-- | lib/git/remote.py | 45 | ||||
-rw-r--r-- | test/git/test_index.py | 16 | ||||
-rw-r--r-- | test/git/test_remote.py | 11 | ||||
-rw-r--r-- | test/testlib/helper.py | 13 |
5 files changed, 66 insertions, 23 deletions
diff --git a/lib/git/refs.py b/lib/git/refs.py index 26e7c09e..52e128b5 100644 --- a/lib/git/refs.py +++ b/lib/git/refs.py @@ -263,11 +263,13 @@ class SymbolicReference(object): tokens = value.split(" ") # it is a detached reference - if len(tokens) == 1 and len(tokens[0]) == 40: + if self.repo.re_hexsha_only.match(tokens[0]): return Commit(self.repo, tokens[0]) # must be a head ! Git does not allow symbol refs to other things than heads # Otherwise it would have detached it + if tokens[0] != "ref:": + raise ValueError("Failed to parse symbolic refernce: wanted 'ref: <hexsha>', got %r" % value) return Head(self.repo, tokens[1]).commit def _set_commit(self, commit): diff --git a/lib/git/remote.py b/lib/git/remote.py index 7febf2ee..12394c6f 100644 --- a/lib/git/remote.py +++ b/lib/git/remote.py @@ -49,6 +49,38 @@ class Remote(LazyMixin, Iterable): __slots__ = ( "repo", "name", "_config_reader" ) _id_attribute_ = "name" + class FetchInfo(object): + """ + Carries information about the results of a fetch operation:: + + info = remote.fetch()[0] + info.local_ref # None, or Reference object to the local head or tag which was moved + info.remote_ref # Symbolic Reference or RemoteReference to the changed remote head or FETCH_HEAD + info.flags # additional flags to be & with enumeration members, i.e. info.flags & info.REJECTED + """ + __slots__ = tuple() + BRANCH_UPTODATE, REJECTED, FORCED_UPDATED, FAST_FORWARD, NEW_TAG, \ + TAG_UPDATE, NEW_BRANCH = [ 1 << x for x in range(1,8) ] + + def __init__(self, local_ref, remote_ref, flags): + """ + Initialize a new instance + """ + self.local_ref = local_ref + self.remote_ref = remote_ref + self.flags = flags + + @classmethod + def _from_line(cls, line): + """ + Parse information from the given line as returned by git-fetch -v + and return a new FetchInfo object representing this information. + """ + raise NotImplementedError("todo") + + # END FetchInfo definition + + def __init__(self, repo, name): """ Initialize a remote instance @@ -218,10 +250,11 @@ class Remote(LazyMixin, Iterable): Additional arguments to be passed to git-fetch Returns - self + list(FetchInfo, ...) list of FetchInfo instances providing detailed + information about the fetch results """ - self.repo.git.fetch(self, refspec, **kwargs) - return self + lines = self.repo.git.fetch(self, refspec, v=True, **kwargs).splitlines() + return [ self.FetchInfo._from_line(line) for line in lines ] def pull(self, refspec=None, **kwargs): """ @@ -235,10 +268,10 @@ class Remote(LazyMixin, Iterable): Additional arguments to be passed to git-pull Returns - self + list(Fetch """ - self.repo.git.pull(self, refspec, **kwargs) - return self + lines = self.repo.git.pull(self, refspec, v=True, **kwargs).splitlines() + return [ self.FetchInfo._from_line(line) for line in lines ] def push(self, refspec=None, **kwargs): """ diff --git a/test/git/test_index.py b/test/git/test_index.py index 3312abe1..3345949b 100644 --- a/test/git/test_index.py +++ b/test/git/test_index.py @@ -199,6 +199,9 @@ class TestTree(TestBase): def _count_existing(self, repo, files): + """ + Returns count of files that actually exist in the repository directory. + """ existing = 0 basedir = repo.git.git_dir for f in files: @@ -207,19 +210,6 @@ class TestTree(TestBase): return existing # END num existing helper - - def _make_file(self, rela_path, data, repo=None): - """ - Create a file at the given path relative to our repository, filled - with the given data. Returns absolute path to created file. - """ - repo = repo or self.rorepo - abs_path = os.path.join(repo.git.git_dir, rela_path) - fp = open(abs_path, "w") - fp.write(data) - fp.close() - return abs_path - @with_rw_repo('0.1.6') def test_index_mutation(self, rw_repo): index = rw_repo.index diff --git a/test/git/test_remote.py b/test/git/test_remote.py index ef00056d..f1e25ebf 100644 --- a/test/git/test_remote.py +++ b/test/git/test_remote.py @@ -59,11 +59,18 @@ class TestRemote(TestBase): assert remote.rename(prev_name).name == prev_name # END for each rename ( back to prev_name ) - remote.fetch() + # FETCH TESTING + assert len(remote.fetch()) == 1 + + + self.fail("rejected parsing") + self.fail("test parsing of each individual flag") + # PULL TESTING + # fails as we did not specify a branch and there is no configuration for it self.failUnlessRaises(GitCommandError, remote.pull) remote.pull('master') remote.update() - self.fail("test push once there is a test-repo") + # END for each remote assert num_remotes assert num_remotes == len(remote_set) diff --git a/test/testlib/helper.py b/test/testlib/helper.py index ab4b9f4e..d541a111 100644 --- a/test/testlib/helper.py +++ b/test/testlib/helper.py @@ -175,4 +175,15 @@ class TestBase(TestCase): each test type has its own repository """ cls.rorepo = Repo(GIT_REPO) - + + def _make_file(self, rela_path, data, repo=None): + """ + Create a file at the given path relative to our repository, filled + with the given data. Returns absolute path to created file. + """ + repo = repo or self.rorepo + abs_path = os.path.join(repo.git.git_dir, rela_path) + fp = open(abs_path, "w") + fp.write(data) + fp.close() + return abs_path |