diff --git a/CHANGES.txt b/CHANGES.txt index b604a8ccb..5630d027b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -75,6 +75,9 @@ and when ``package_dir`` is used, so ``pip freeze`` works in more cases (:pull:`3258`) +* Correctly freeze Git develop packages in presence of the &subdirectory + option (:pull:`3258`) + **7.1.2 (2015-08-22)** diff --git a/pip/vcs/git.py b/pip/vcs/git.py index ae63b4356..ce92b5090 100644 --- a/pip/vcs/git.py +++ b/pip/vcs/git.py @@ -188,6 +188,33 @@ class Git(VersionControl): rv[ref_name] = commit return rv + def _get_subdirectory(self, location): + """Return the relative path of setup.py to the git repo root.""" + # find the repo root + git_dir = self.run_command(['rev-parse', '--git-dir'], + show_stdout=False, cwd=location).strip() + if not os.path.isabs(git_dir): + git_dir = os.path.join(location, git_dir) + root_dir = os.path.join(git_dir, '..') + # find setup.py + orig_location = location + while not os.path.exists(os.path.join(location, 'setup.py')): + last_location = location + location = os.path.dirname(location) + if location == last_location: + # We've traversed up to the root of the filesystem without + # finding setup.py + logger.warning( + "Could not find setup.py for directory %s (tried all " + "parent directories)", + orig_location, + ) + return None + # relative path of setup.py to repo root + if os.path.samefile(root_dir, location): + return None + return os.path.relpath(location, root_dir) + def get_src_requirement(self, dist, location, find_tags): repo = self.get_url(location) if not repo.lower().startswith('git:'): @@ -214,7 +241,11 @@ class Git(VersionControl): else: full_egg_name = '%s-dev' % egg_project_name - return '%s@%s#egg=%s' % (repo, current_rev, full_egg_name) + req = '%s@%s#egg=%s' % (repo, current_rev, full_egg_name) + subdirectory = self._get_subdirectory(location) + if subdirectory: + req += '&subdirectory=' + subdirectory + return req def get_url_rev(self): """