commit:     9a1470f569e9f14f3941cb70feefbbd647c3b104
Author:     Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Wed Nov 11 22:27:15 2015 +0000
Commit:     Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Thu Nov 12 21:17:27 2015 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=9a1470f5

egencache: fix results when GIT_DIR is used in the environment.

If GIT_DIR is used, and .git is outside the root of the checkout, then
--work-tree=... needs to be specified, otherwise any Git command that
relies on relative directories to the root will be wrong.

Also ensure that diff-tree's --relative argument is explicitly told
what path to make the relative output for, rather rely on it being
relative to work-tree.

Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>

 bin/egencache | 30 ++++++++++++++++++++++--------
 1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/bin/egencache b/bin/egencache
index a9d4657..b44ad11 100755
--- a/bin/egencache
+++ b/bin/egencache
@@ -763,6 +763,16 @@ class GenChangeLogs(object):
                self._changelog_reversed = changelog_reversed
                self._max_jobs = max_jobs
                self._max_load = max_load
+               self._repo_path = self._portdb.porttrees[0]
+               # --work-tree=... must be passed to Git if GIT_DIR is used
+               # and GIT_DIR is not a child of the root of the checkout
+               # eg:
+               # GIT_DIR=$parent/work/.git/
+               # work-tree=$parent/staging/
+               # If work-tree is not passed, Git tries to use the shared
+               # parent of the current directory and the $GIT_DIR, which can
+               # be outside the root of the checkout.
+               self._work_tree = '--work-tree=%s' % self._repo_path
 
        @staticmethod
        def grab(cmd):
@@ -790,7 +800,7 @@ class GenChangeLogs(object):
                        ''' % (cp, time.strftime('%Y'))))
 
                # now grab all the commits
-               revlist_cmd = ['git', 'rev-list']
+               revlist_cmd = ['git', self._work_tree, 'rev-list']
                if self._changelog_reversed:
                        revlist_cmd.append('--reverse')
                revlist_cmd.extend(['HEAD', '--', '.'])
@@ -802,12 +812,17 @@ class GenChangeLogs(object):
                        # --no-renames to avoid getting more complex records on 
the list
                        # --format to get the timestamp, author and commit 
description
                        # --root to make it work fine even with the initial 
commit
-                       # --relative to get paths relative to ebuilddir
+                       # --relative=$cp to get paths relative to ebuilddir
                        # -r (recursive) to get per-file changes
                        # then the commit-id and path.
 
-                       cinfo = self.grab(['git', 'diff-tree', '--name-status', 
'--no-renames',
-                                       '--format=%ct %cN <%cE>%n%B', '--root', 
'--relative', '-r',
+                       cinfo = self.grab(['git', self._work_tree, 'diff-tree',
+                                       '--name-status',
+                                       '--no-renames',
+                                       '--format=%ct %cN <%cE>%n%B',
+                                       '--root',
+                                       '--relative=%s' % (cp, ),
+                                       '-r',
                                        c, '--', '.']).rstrip('\n').split('\n')
 
                        # Expected output:
@@ -888,8 +903,7 @@ class GenChangeLogs(object):
                output.close()
 
        def _task_iter(self):
-               repo_path = self._portdb.porttrees[0]
-               os.chdir(repo_path)
+               os.chdir(self._repo_path)
 
                if 'git' not in FindVCS():
                        writemsg_level(
@@ -899,10 +913,10 @@ class GenChangeLogs(object):
                        return
 
                for cp in self._portdb.cp_all():
-                       os.chdir(os.path.join(repo_path, cp))
+                       os.chdir(os.path.join(self._repo_path, cp))
                        # Determine whether ChangeLog is up-to-date by comparing
                        # the newest commit timestamp with the ChangeLog 
timestamp.
-                       lmod = self.grab(['git', 'log', '--format=%ct', '-1', 
'.'])
+                       lmod = self.grab(['git', self._work_tree, 'log', 
'--format=%ct', '-1', '.'])
                        if not lmod:
                                # This cp has not been added to the repo.
                                continue

Reply via email to