Skip to content

Installing a Git "ref" doesn't work for later installs #5624

@cjerdonek

Description

@cjerdonek
  • pip version: 10.0.1
  • Python version: all
  • OS: all

Support for installing Git "refs" was added in response to issue #3876.

However, I noticed by inspecting the code that it will only work for the first install. If you try to install a ref after a package has already been installed, it won't work.

For example--

$ pip install -e git+https://github.com/pypa/twine.git@refs/pull/363/head#egg=twine

Now 74172b75179fb6b92f8cb0940800fca3cd3b309d is installed (visible in this PR): https://github.com/pypa/twine/pull/363/commits

Now try installing a different ref:

$ pip install -e git+https://github.com/pypa/twine.git@refs/pull/361/head#egg=twine
Obtaining twine from git+https://github.com/pypa/twine.git@refs/pull/361/head#egg=twine
  Updating /.../envs/pip-testing/src/twine clone (to revision refs/pull/361/head)
  Did not find branch or tag 'refs/pull/361/head', assuming revision or ref.
fatal: ambiguous argument 'refs/pull/361/head': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
Command "git reset --hard -q refs/pull/361/head" failed with error code 128 in /.../envs/pip-testing/src/twine

This is failing because Git.update() doesn't do an extra fetch in the "ref" case:

def update(self, dest, rev_options):
# First fetch changes from the default remote
if self.get_git_version() >= parse_version('1.9.0'):
# fetch tags in addition to everything else
self.run_command(['fetch', '-q', '--tags'], cwd=dest)
else:
self.run_command(['fetch', '-q'], cwd=dest)
# Then reset to wanted revision (maybe even origin/master)
rev_options = self.check_rev_options(dest, rev_options)
cmd_args = ['reset', '--hard', '-q'] + rev_options.to_args()
self.run_command(cmd_args, cwd=dest)
#: update submodules
self.update_submodules(dest)

It only does the extra fetch in the Git.fetch_new() case (i.e. called in the first install):

if not self.is_commit_id_equal(dest, rev_options.rev):
rev = rev_options.rev
# Only fetch the revision if it's a ref
if rev.startswith('refs/'):
self.run_command(
['fetch', '-q', url] + rev_options.to_args(),
cwd=dest,
)
# Change the revision to the SHA of the ref we fetched
rev = 'FETCH_HEAD'
self.run_command(['checkout', '-q', rev], cwd=dest)

I proposed a fix with tests here: #5623

Metadata

Metadata

Assignees

No one assigned

    Labels

    C: vcspip's interaction with version control systems like git, svn and bzrauto-lockedOutdated issues that have been locked by automationtype: bugA confirmed bug or unintended behavior

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions