8000 Fetch info can now deal much better with non-default ref specs, fixes… · codepongo/GitPython@c555840 · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c555840

Browse files
committed
Fetch info can now deal much better with non-default ref specs, fixes gitpython-developers#24, gitpython-developers#25
1 parent 916c45d commit c555840

File tree

4 files changed

+77
-9
lines changed

4 files changed

+77
-9
lines changed

.gitmodules

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
[submodule "gitdb"]
2-
path = git/ext/gitdb
3-
url = git://github.com/gitpython-developers/gitdb.git
1+
[submodule "gitdb"]
2+
path = git/ext/gitdb
3+
url = git://github.com/gitpython-developers/gitdb.git

git/ext/gitdb

Submodule gitdb updated 1 file

git/remote.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,12 +279,36 @@ def _from_line(cls, repo, line, fetch_line):
279279
ref_type = TagReference
280280
else:
281281
raise TypeError("Cannot handle reference type: %r" % ref_type_name)
282+
#END handle ref type
282283

283284
# create ref instance
284285
if ref_type is SymbolicReference:
285286
remote_local_ref = ref_type(repo, "FETCH_HEAD")
286287
else:
287-
remote_local_ref = Reference.from_path(repo, join_path(ref_type._common_path_default, remote_local_ref.strip()))
288+
# determine prefix. Tags are usually pulled into refs/tags, they may have subdirectories.
289+
# It is not clear sometimes where exactly the item is, unless we have an absolute path as indicated
290+
# by the 'ref/' prefix. Otherwise even a tag could be in refs/remotes, which is when it will have the
291+
# 'tags/' subdirectory in its path.
292+
# We don't want to test for actual existence, but try to figure everything out analytically.
293+
ref_path = None
294+
remote_local_ref = remote_local_ref.strip()
295+
if remote_local_ref.startswith(Reference._common_path_default + "/"):
296+
# always use actual type if we get absolute paths
297+
# Will always be the case if something is fetched outside of refs/remotes (if its not a tag)
298+
ref_path = remote_local_ref
299+
if ref_type is not TagReference and not remote_local_ref.startswith(RemoteReference._common_path_default + "/"):
300+
ref_type = Reference
301+
#END downgrade remote reference
302+
elif ref_type is TagReference and 'tags/' in remote_local_ref:
303+
# even though its a tag, it is located in refs/remotes
304+
ref_path = join_path(RemoteReference._common_path_default, remote_local_ref)
305+
else:
306+
ref_path = join_path(ref_type._common_path_default, remote_local_ref)
307+
#END obtain refpath
308+
309+
# even though the path could be within the git conventions, we make
310+
# sure we respect whatever the user wanted, and disabled path checking
311+
remote_local_ref = ref_type(repo, ref_path, check_path=False)
288312
# END create ref instance
289313

290314
note = ( note and note.strip() ) or ''

git/test/test_remote.py

Lines changed: 48 additions & 4 deletions
< 1E79 /tr>
Original file line numberDiff line numberDiff line change
@@ -443,11 +443,55 @@ def test_creation_and_removal(self, bare_rw_repo):
443443

444444
def test_fetch_info(self):
445445
# assure we can handle remote-tracking branches
446-
fi = FetchInfo._from_line(self.rorepo,
447-
"* [new branch] master -> local/master",
448-
"c437ee5deb8d00cf02f03720693e4c802e99f390 not-for-merge remote-tracking branch '0.3' of git://github.com/gitpython-developers/GitPython")
446+
fetch_info_line_fmt = "c437ee5deb8d00cf02f03720693e4c802e99f390 not-for-merge %s '0.3' of git://github.com/gitpython-developers/GitPython"
447+
remote_info_line_fmt = "* [new branch] nomatter -> %s"
448+
fi = FetchInfo._from_line(self.rorepo,
449+
remote_info_line_fmt % "local/master",
450+
fetch_info_line_fmt % 'remote-tracking branch')
449451
assert fi.ref.is_valid()
450452
assert fi.ref.commit
451453

454+
# handles non-default refspecs: One can specify a different path in refs/remotes
455+
# or a special path just in refs/something for instance
452456

453-
457+
fi = FetchInfo._from_line(self.rorepo,
458+
remote_info_line_fmt % "subdir/tagname",
459+
fetch_info_line_fmt % 'tag')
460+
461+
assert isinstance(fi.ref, TagReference)
462+
assert fi.ref.path.startswith('refs/tags')
463+
464+
# it could be in a remote direcftory though
465+
fi = FetchInfo._from_line(self.rorepo,
466+
remote_info_line_fmt % "remotename/tags/tagname",
467+
fetch_info_line_fmt % 'tag')
468+
469+
assert isinstance(fi.ref, TagReference)
470+
assert fi.ref.path.startswith('refs/remotes/')
471+
472+
# it can also be anywhere !
473+
tag_path = "refs/something/remotename/tags/tagname"
474+
fi = FetchInfo._from_line(self.rorepo,
475+
remote_info_line_fmt % tag_path,
476+
fetch_info_line_fmt % 'tag')
477+
478+
assert isinstance(fi.ref, TagReference)
479+
assert fi.ref.path == tag_path
480+
481+
# branches default to refs/remotes
482+
fi = FetchInfo._from_line(self.rorepo,
483+
remote_info_line_fmt % "remotename/branch",
484+
fetch_info_line_fmt % 'branch')
485+
486+
assert isinstance(fi.ref, RemoteReference)
487+
assert fi.ref.remote_name == 'remotename'
488+
489+
# but you can force it anywhere, in which case we only have a references
490+
fi = FetchInfo._from_line(self.rorepo,
491+
remote_info_line_fmt % "refs/something/branch",
492+
fetch_info_line_fmt % 'branch')
493+
494+
assert type(fi.ref) is Reference
495+
assert fi.ref.path == "refs/something/branch"
496+
497+

0 commit comments

Comments
 (0)
0