Backport of https://github.com/pypa/pip/pull/9827 with parts of https://github.com/pypa/pip/pull/4690 to make it work with pip v9.0.1 diff --git a/pip/vcs/git.py b/pip/vcs/git.py index 2187dd8..d1502f8 100644 --- a/pip/vcs/git.py +++ b/pip/vcs/git.py @@ -81,7 +81,7 @@ class Git(VersionControl): and branches may need origin/ as a prefix. Returns the SHA1 of the branch or tag if found. """ - revisions = self.get_short_refs(dest) + revisions = self.get_short_refs(dest, rev) origin_rev = 'origin/%s' % rev if origin_rev in revisions: @@ -171,12 +171,20 @@ class Git(VersionControl): ['rev-parse', 'HEAD'], show_stdout=False, cwd=location) return current_rev.strip() - def get_full_refs(self, location): + def get_full_refs(self, location, pattern=''): """Yields tuples of (commit, ref) for branches and tags""" - output = self.run_command(['show-ref'], + output = self.run_command(['show-ref', pattern], show_stdout=False, cwd=location) - for line in output.strip().splitlines(): - commit, ref = line.split(' ', 1) + for line in output.split("\n"): + line = line.rstrip("\r") + if not line: + continue + try: + commit, ref = line.split(' ', 1) + except ValueError: + # Include the offending line to simplify troubleshooting if + # this error ever occurs. + raise ValueError(f'unexpected show-ref line: {line!r}') yield commit.strip(), ref.strip() def is_ref_remote(self, ref): @@ -200,10 +208,10 @@ class Git(VersionControl): def get_refs(self, location): return self.get_short_refs(location) - def get_short_refs(self, location): + def get_short_refs(self, location, pattern=''): """Return map of named refs (branches or tags) to commit hashes.""" rv = {} - for commit, ref in self.get_full_refs(location): + for commit, ref in self.get_full_refs(location, pattern): ref_name = None if self.is_ref_remote(ref): ref_name = ref[len('refs/remotes/'):]