diff options
author | Sebastian Thiel <byronimo@gmail.com> | 2015-01-22 15:22:39 +0100 |
---|---|---|
committer | Sebastian Thiel <byronimo@gmail.com> | 2015-01-22 15:22:39 +0100 |
commit | 06bec1bcd1795192f4a4a274096f053afc8f80ec (patch) | |
tree | fda896da0f7406ff257b8f9d1d3805965bc94311 | |
parent | b54b9399920375f0bab14ff8495c0ea3f5fa1c33 (diff) | |
download | gitpython-06bec1bcd1795192f4a4a274096f053afc8f80ec.tar.gz |
Fetch now deals with custom refspecs much better.
Even though the test-csae only verifies this spec:
+refs/pull/*:refs/heads/pull/*
I could locally verify that it indeed handles other ones just as well:
+refs/pull/*:refs/pull/*
Fixes #243
-rw-r--r-- | git/remote.py | 16 | ||||
-rw-r--r-- | git/test/fixtures/uncommon_branch_prefix_FETCH_HEAD | 6 | ||||
-rw-r--r-- | git/test/fixtures/uncommon_branch_prefix_stderr | 6 | ||||
-rw-r--r-- | git/test/test_docs.py | 2 | ||||
-rw-r--r-- | git/test/test_remote.py | 16 |
5 files changed, 40 insertions, 6 deletions
diff --git a/git/remote.py b/git/remote.py index c37d6c49..39d9dc4d 100644 --- a/git/remote.py +++ b/git/remote.py @@ -14,6 +14,7 @@ from .config import ( cp, ) from .refs import ( + Head, Reference, RemoteReference, SymbolicReference, @@ -177,8 +178,9 @@ class FetchInfo(object): info.note # additional notes given by git-fetch intended for the user info.old_commit # if info.flags & info.FORCED_UPDATE|info.FAST_FORWARD, # field is set to the previous location of ref, otherwise None + info.remote_ref_path # The path from which we fetched on the remote. It's the remote's version of our info.ref """ - __slots__ = ('ref', 'old_commit', 'flags', 'note') + __slots__ = ('ref', 'old_commit', 'flags', 'note', 'remote_ref_path') NEW_TAG, NEW_HEAD, HEAD_UPTODATE, TAG_UPDATE, REJECTED, FORCED_UPDATE, \ FAST_FORWARD, ERROR = [1 << x for x in range(8)] @@ -193,7 +195,7 @@ class FetchInfo(object): '=': HEAD_UPTODATE, ' ': FAST_FORWARD} - def __init__(self, ref, flags, note='', old_commit=None): + def __init__(self, ref, flags, note='', old_commit=None, remote_ref_path=None): """ Initialize a new instance """ @@ -201,6 +203,7 @@ class FetchInfo(object): self.flags = flags self.note = note self.old_commit = old_commit + self.remote_ref_path = remote_ref_path def __str__(self): return self.name @@ -243,7 +246,7 @@ class FetchInfo(object): new_hex_sha, fetch_operation, fetch_note = fetch_line.split("\t") ref_type_name, fetch_note = fetch_note.split(' ', 1) except ValueError: # unpack error - raise ValueError("Failed to parse FETCH__HEAD line: %r" % fetch_line) + raise ValueError("Failed to parse FETCH_HEAD line: %r" % fetch_line) # parse flags from control_character flags = 0 @@ -288,6 +291,11 @@ class FetchInfo(object): # note: remote-tracking is just the first part of the 'remote-tracking branch' token. # We don't parse it correctly, but its enough to know what to do, and its new in git 1.7something ref_type = RemoteReference + elif '/' in ref_type_name: + # If the fetch spec look something like this '+refs/pull/*:refs/heads/pull/*', and is thus pretty + # much anything the user wants, we will have trouble to determine what's going on + # For now, we assume the local ref is a Head + ref_type = Head else: raise TypeError("Cannot handle reference type: %r" % ref_type_name) # END handle ref type @@ -325,7 +333,7 @@ class FetchInfo(object): note = (note and note.strip()) or '' - return cls(remote_local_ref, flags, note, old_commit) + return cls(remote_local_ref, flags, note, old_commit, local_remote_ref) class Remote(LazyMixin, Iterable): diff --git a/git/test/fixtures/uncommon_branch_prefix_FETCH_HEAD b/git/test/fixtures/uncommon_branch_prefix_FETCH_HEAD new file mode 100644 index 00000000..7df36f24 --- /dev/null +++ b/git/test/fixtures/uncommon_branch_prefix_FETCH_HEAD @@ -0,0 +1,6 @@ +c2e3c20affa3e2b61a05fdc9ee3061dd416d915e 'refs/pull/1/head' of http://github.com/loic-bot/testrepo +fd8695d980e2c6df62b7785f93fd6292d1e283fb 'refs/pull/1/merge' of http://github.com/loic-bot/testrepo +bb46faf089720d1a3f9e4dc3b11ed5ff77d7e764 'refs/pull/2/head' of http://github.com/loic-bot/testrepo +5faa366d58454eceea811e0e34c502bdd7b37e4b 'refs/pull/2/merge' of http://github.com/loic-bot/testrepo +b3ad3c4f1864b50d4d3e09320947a1a3c34c9ea2 'refs/pull/3/head' of http://github.com/loic-bot/testrepo +71fe57e511776042b009ed4bb281b62b0522b434 'refs/pull/3/merge' of http://github.com/loic-bot/testrepo diff --git a/git/test/fixtures/uncommon_branch_prefix_stderr b/git/test/fixtures/uncommon_branch_prefix_stderr new file mode 100644 index 00000000..5a6aca65 --- /dev/null +++ b/git/test/fixtures/uncommon_branch_prefix_stderr @@ -0,0 +1,6 @@ + = [up to date] refs/pull/1/head -> pull/1/head + = [up to date] refs/pull/1/merge -> pull/1/merge + = [up to date] refs/pull/2/head -> pull/2/head + = [up to date] refs/pull/2/merge -> pull/2/merge + = [up to date] refs/pull/3/head -> pull/3/head + = [up to date] refs/pull/3/merge -> pull/3/merge diff --git a/git/test/test_docs.py b/git/test/test_docs.py index 25566243..397641e0 100644 --- a/git/test/test_docs.py +++ b/git/test/test_docs.py @@ -181,7 +181,7 @@ class Tutorials(TestBase): def test_references_and_objects(self, rw_dir): # [1-test_references_and_objects] import git - repo = git.Repo.clone_from(self._small_repo_url(), os.path.join(rw_dir, 'repo')) + repo = git.Repo.clone_from(self._small_repo_url(), os.path.join(rw_dir, 'repo'), branch='master') heads = repo.heads master = heads.master # lists can be accessed by name for convenience diff --git a/git/test/test_remote.py b/git/test/test_remote.py index d4a92ed4..4fd78230 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -7,7 +7,8 @@ from git.test.lib import ( TestBase, with_rw_repo, - with_rw_and_rw_remote_repo + with_rw_and_rw_remote_repo, + fixture ) from git import ( RemoteProgress, @@ -520,3 +521,16 @@ class TestRemote(TestBase): assert type(fi.ref) is Reference assert fi.ref.path == "refs/something/branch" + + def test_uncommon_branch_names(self): + stderr_lines = fixture('uncommon_branch_prefix_stderr').decode('ascii').splitlines() + fetch_lines = fixture('uncommon_branch_prefix_FETCH_HEAD').decode('ascii').splitlines() + + # The contents of the files above must be fetched with a custom refspec: + # +refs/pull/*:refs/heads/pull/* + res = [FetchInfo._from_line('ShouldntMatterRepo', stderr, fetch_line) + for stderr, fetch_line in zip(stderr_lines, fetch_lines)] + assert len(res) + assert res[0].remote_ref_path == 'refs/pull/1/head' + assert res[0].ref.path == 'refs/heads/pull/1/head' + assert isinstance(res[0].ref, Head) |