git: handle worktrees
A worktree checkout has a text file at .git instead of a dir.
BUG=chromium:1104812
TEST=CQ passes
Change-Id: If28efe8943fe8e34d4cd6feb54738ac17926fd3d
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/chromite/+/2551821
Reviewed-by: Stephane Belmon <sbelmon@google.com>
Tested-by: Mike Frysinger <vapier@chromium.org>
Commit-Queue: Mike Frysinger <vapier@chromium.org>
diff --git a/lib/git.py b/lib/git.py
index a6d139e..0f8f939 100644
--- a/lib/git.py
+++ b/lib/git.py
@@ -91,8 +91,18 @@
Returns:
Path of the gitdir directory. None if the directory is not a git repo.
"""
- if os.path.isdir(os.path.join(pwd, '.git')):
- return os.path.join(pwd, '.git')
+ dotgit = os.path.join(pwd, '.git')
+
+ # A "normal" git checkout.
+ if os.path.isdir(dotgit):
+ return dotgit
+
+ # A git worktree checkout.
+ if os.path.isfile(dotgit):
+ with open(dotgit, 'r') as fp:
+ if fp.read(7) == 'gitdir:':
+ return dotgit
+
# Is this directory a bare repo with no checkout?
if os.path.isdir(os.path.join(
pwd, 'objects')) and os.path.isdir(os.path.join(pwd, 'refs')):
diff --git a/lib/git_unittest.py b/lib/git_unittest.py
index 1666237..a96bb8f 100644
--- a/lib/git_unittest.py
+++ b/lib/git_unittest.py
@@ -190,6 +190,12 @@
ret = git.GetGitGitdir(self.fake_git_dir)
self.assertEqual(ret, self.fake_git_dir)
+ def testGetGitGitdir_worktree(self):
+ dotgit = os.path.join(self.tempdir, '.git')
+ osutils.WriteFile(dotgit, 'gitdir: /foo')
+ ret = git.GetGitGitdir(self.tempdir)
+ self.assertEqual(ret, dotgit)
+
def testGetGitGitdir_negative(self):
ret = git.GetGitGitdir(self.tempdir)
self.assertFalse(ret)