diff options
author | Sebastian Thiel <byronimo@gmail.com> | 2011-07-04 22:52:36 +0200 |
---|---|---|
committer | Sebastian Thiel <byronimo@gmail.com> | 2011-07-04 22:52:36 +0200 |
commit | c5558400e86a96936795e68bb6aa95c4c0bb0719 (patch) | |
tree | 4a5ef66bd2b09d6cd66a7d659d5cbbb2218ef513 | |
parent | 916c45de7c9663806dc2cd3769a173682e5e8670 (diff) | |
download | gitpython-c5558400e86a96936795e68bb6aa95c4c0bb0719.tar.gz |
Fetch info can now deal much better with non-default ref specs, fixes #24, #25
-rw-r--r-- | .gitmodules | 6 | ||||
m--------- | git/ext/gitdb | 0 | ||||
-rw-r--r-- | git/remote.py | 26 | ||||
-rw-r--r-- | git/test/test_remote.py | 52 |
4 files changed, 76 insertions, 8 deletions
diff --git a/.gitmodules b/.gitmodules index c1e1e76d..5741d992 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "gitdb"]
- path = git/ext/gitdb
- url = git://github.com/gitpython-developers/gitdb.git
+[submodule "gitdb"] + path = git/ext/gitdb + url = git://github.com/gitpython-developers/gitdb.git diff --git a/git/ext/gitdb b/git/ext/gitdb -Subproject 4524faf0d0c5383268b134084954b34faeaa766 +Subproject a5ed410aa0d3bed587214c3c017af2916b740da diff --git a/git/remote.py b/git/remote.py index 07019038..5e4439fb 100644 --- a/git/remote.py +++ b/git/remote.py @@ -279,12 +279,36 @@ class FetchInfo(object): ref_type = TagReference else: raise TypeError("Cannot handle reference type: %r" % ref_type_name) + #END handle ref type # create ref instance if ref_type is SymbolicReference: remote_local_ref = ref_type(repo, "FETCH_HEAD") else: - remote_local_ref = Reference.from_path(repo, join_path(ref_type._common_path_default, remote_local_ref.strip())) + # determine prefix. Tags are usually pulled into refs/tags, they may have subdirectories. + # It is not clear sometimes where exactly the item is, unless we have an absolute path as indicated + # by the 'ref/' prefix. Otherwise even a tag could be in refs/remotes, which is when it will have the + # 'tags/' subdirectory in its path. + # We don't want to test for actual existence, but try to figure everything out analytically. + ref_path = None + remote_local_ref = remote_local_ref.strip() + if remote_local_ref.startswith(Reference._common_path_default + "/"): + # always use actual type if we get absolute paths + # Will always be the case if something is fetched outside of refs/remotes (if its not a tag) + ref_path = remote_local_ref + if ref_type is not TagReference and not remote_local_ref.startswith(RemoteReference._common_path_default + "/"): + ref_type = Reference + #END downgrade remote reference + elif ref_type is TagReference and 'tags/' in remote_local_ref: + # even though its a tag, it is located in refs/remotes + ref_path = join_path(RemoteReference._common_path_default, remote_local_ref) + else: + ref_path = join_path(ref_type._common_path_default, remote_local_ref) + #END obtain refpath + + # even though the path could be within the git conventions, we make + # sure we respect whatever the user wanted, and disabled path checking + remote_local_ref = ref_type(repo, ref_path, check_path=False) # END create ref instance note = ( note and note.strip() ) or '' diff --git a/git/test/test_remote.py b/git/test/test_remote.py index ad1ba616..3e9ba8b8 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -443,11 +443,55 @@ class TestRemote(TestBase): def test_fetch_info(self): # assure we can handle remote-tracking branches - fi = FetchInfo._from_line(self.rorepo, - "* [new branch] master -> local/master", - "c437ee5deb8d00cf02f03720693e4c802e99f390 not-for-merge remote-tracking branch '0.3' of git://github.com/gitpython-developers/GitPython") + fetch_info_line_fmt = "c437ee5deb8d00cf02f03720693e4c802e99f390 not-for-merge %s '0.3' of git://github.com/gitpython-developers/GitPython" + remote_info_line_fmt = "* [new branch] nomatter -> %s" + fi = FetchInfo._from_line(self.rorepo, + remote_info_line_fmt % "local/master", + fetch_info_line_fmt % 'remote-tracking branch') assert fi.ref.is_valid() assert fi.ref.commit + # handles non-default refspecs: One can specify a different path in refs/remotes + # or a special path just in refs/something for instance - + fi = FetchInfo._from_line(self.rorepo, + remote_info_line_fmt % "subdir/tagname", + fetch_info_line_fmt % 'tag') + + assert isinstance(fi.ref, TagReference) + assert fi.ref.path.startswith('refs/tags') + + # it could be in a remote direcftory though + fi = FetchInfo._from_line(self.rorepo, + remote_info_line_fmt % "remotename/tags/tagname", + fetch_info_line_fmt % 'tag') + + assert isinstance(fi.ref, TagReference) + assert fi.ref.path.startswith('refs/remotes/') + + # it can also be anywhere ! + tag_path = "refs/something/remotename/tags/tagname" + fi = FetchInfo._from_line(self.rorepo, + remote_info_line_fmt % tag_path, + fetch_info_line_fmt % 'tag') + + assert isinstance(fi.ref, TagReference) + assert fi.ref.path == tag_path + + # branches default to refs/remotes + fi = FetchInfo._from_line(self.rorepo, + remote_info_line_fmt % "remotename/branch", + fetch_info_line_fmt % 'branch') + + assert isinstance(fi.ref, RemoteReference) + assert fi.ref.remote_name == 'remotename' + + # but you can force it anywhere, in which case we only have a references + fi = FetchInfo._from_line(self.rorepo, + remote_info_line_fmt % "refs/something/branch", + fetch_info_line_fmt % 'branch') + + assert type(fi.ref) is Reference + assert fi.ref.path == "refs/something/branch" + + |