summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Thiel <byronimo@gmail.com>2011-07-04 22:52:36 +0200
committerSebastian Thiel <byronimo@gmail.com>2011-07-04 22:52:36 +0200
commitc5558400e86a96936795e68bb6aa95c4c0bb0719 (patch)
tree4a5ef66bd2b09d6cd66a7d659d5cbbb2218ef513
parent916c45de7c9663806dc2cd3769a173682e5e8670 (diff)
downloadgitpython-c5558400e86a96936795e68bb6aa95c4c0bb0719.tar.gz
Fetch info can now deal much better with non-default ref specs, fixes #24, #25
-rw-r--r--.gitmodules6
m---------git/ext/gitdb0
-rw-r--r--git/remote.py26
-rw-r--r--git/test/test_remote.py52
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"
+
+