project: unify HEAD path management

Add a helper function to unify the duplication of finding the full
path to the symbolic HEAD ref.  This makes it easy to handle git
worktrees where .git is a file rather than a dir/symlink.

Bug: https://crbug.com/gerrit/11486
Change-Id: I9f794f1295ad0d98c7c13622f01ded51e4ba7846
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/254074
Tested-by: Mike Frysinger <vapier@google.com>
Reviewed-by: David Pursehouse <dpursehouse@collab.net>
This commit is contained in:
Mike Frysinger 2020-02-09 03:01:56 -05:00 committed by David Pursehouse
parent e7c91889a6
commit f914edca53

View File

@ -1817,6 +1817,18 @@ class Project(object):
# Branch Management ## # Branch Management ##
def GetHeadPath(self):
"""Return the full path to the HEAD ref."""
dotgit = os.path.join(self.worktree, '.git')
if os.path.isfile(dotgit):
# Git worktrees use a "gitdir:" syntax to point to the scratch space.
with open(dotgit) as fp:
setting = fp.read()
assert setting.startswith('gitdir:')
gitdir = setting.split(':', 1)[1].strip()
dotgit = os.path.join(self.worktree, gitdir)
return os.path.join(dotgit, HEAD)
def StartBranch(self, name, branch_merge='', revision=None): def StartBranch(self, name, branch_merge='', revision=None):
"""Create a new branch off the manifest's revision. """Create a new branch off the manifest's revision.
""" """
@ -1856,8 +1868,7 @@ class Project(object):
except OSError: except OSError:
pass pass
_lwrite(ref, '%s\n' % revid) _lwrite(ref, '%s\n' % revid)
_lwrite(os.path.join(self.worktree, '.git', HEAD), _lwrite(self.GetHeadPath(), 'ref: %s%s\n' % (R_HEADS, name))
'ref: %s%s\n' % (R_HEADS, name))
branch.Save() branch.Save()
return True return True
@ -1904,8 +1915,7 @@ class Project(object):
# Same revision; just update HEAD to point to the new # Same revision; just update HEAD to point to the new
# target branch, but otherwise take no other action. # target branch, but otherwise take no other action.
# #
_lwrite(os.path.join(self.worktree, '.git', HEAD), _lwrite(self.GetHeadPath(), 'ref: %s%s\n' % (R_HEADS, name))
'ref: %s%s\n' % (R_HEADS, name))
return True return True
return GitCommand(self, return GitCommand(self,
@ -1938,8 +1948,7 @@ class Project(object):
revid = self.GetRevisionId(all_refs) revid = self.GetRevisionId(all_refs)
if head == revid: if head == revid:
_lwrite(os.path.join(self.worktree, '.git', HEAD), _lwrite(self.GetHeadPath(), '%s\n' % revid)
'%s\n' % revid)
else: else:
self._Checkout(revid, quiet=True) self._Checkout(revid, quiet=True)
@ -3002,7 +3011,7 @@ class Project(object):
if self._bare: if self._bare:
path = os.path.join(self._project.gitdir, HEAD) path = os.path.join(self._project.gitdir, HEAD)
else: else:
path = os.path.join(self._project.worktree, '.git', HEAD) path = self._project.GetHeadPath()
try: try:
with open(path) as fd: with open(path) as fd:
line = fd.readline() line = fd.readline()