mirror of
https://gerrit.googlesource.com/git-repo
synced 2026-05-07 19:39:18 +00:00
project: resolve unborn HEAD robustly in reftable repos
Use `git symbolic-ref` to resolve HEAD before trying to parse .git/HEAD directly which is unreliable for reftable repos. Bug: 476209856 Change-Id: I60185d945c5b43c871945c0126cfdf52194e745d Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/550762 Commit-Queue: Gavin Mak <gavinmak@google.com> Reviewed-by: Mike Frysinger <vapier@google.com> Tested-by: Gavin Mak <gavinmak@google.com>
This commit is contained in:
+18
@@ -3945,6 +3945,24 @@ class Project:
|
|||||||
return self.rev_parse(HEAD)
|
return self.rev_parse(HEAD)
|
||||||
return symbolic_head
|
return symbolic_head
|
||||||
except GitError as e:
|
except GitError as e:
|
||||||
|
# `git rev-parse --symbolic-full-name HEAD` will fail for unborn
|
||||||
|
# branches, so try symbolic-ref before falling back to raw file
|
||||||
|
# parsing.
|
||||||
|
try:
|
||||||
|
p = GitCommand(
|
||||||
|
self._project,
|
||||||
|
["symbolic-ref", "-q", HEAD],
|
||||||
|
bare=True,
|
||||||
|
gitdir=self._gitdir,
|
||||||
|
capture_stdout=True,
|
||||||
|
capture_stderr=True,
|
||||||
|
log_as_error=False,
|
||||||
|
)
|
||||||
|
if p.Wait() == 0:
|
||||||
|
return p.stdout.rstrip("\n")
|
||||||
|
except GitError:
|
||||||
|
pass
|
||||||
|
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"project %s: unparseable HEAD; trying to recover.\n"
|
"project %s: unparseable HEAD; trying to recover.\n"
|
||||||
"Check that HEAD ref in .git/HEAD is valid. The error "
|
"Check that HEAD ref in .git/HEAD is valid. The error "
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import os
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
|
from typing import Optional
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import utils_for_test
|
import utils_for_test
|
||||||
@@ -45,6 +46,9 @@ class FakeProject:
|
|||||||
)
|
)
|
||||||
self.config = git_config.GitConfig.ForRepository(gitdir=self.gitdir)
|
self.config = git_config.GitConfig.ForRepository(gitdir=self.gitdir)
|
||||||
|
|
||||||
|
def RelPath(self, local: Optional[bool] = None) -> str:
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
class ReviewableBranchTests(unittest.TestCase):
|
class ReviewableBranchTests(unittest.TestCase):
|
||||||
"""Check ReviewableBranch behavior."""
|
"""Check ReviewableBranch behavior."""
|
||||||
@@ -98,6 +102,29 @@ class ProjectTests(unittest.TestCase):
|
|||||||
"abcd00%21%21_%2b",
|
"abcd00%21%21_%2b",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@unittest.skipUnless(
|
||||||
|
utils_for_test.supports_reftable(),
|
||||||
|
"git reftable support is required for this test",
|
||||||
|
)
|
||||||
|
def test_get_head_unborn_reftable(self):
|
||||||
|
with tempfile.TemporaryDirectory(prefix="repo-tests") as tempdir:
|
||||||
|
subprocess.check_call(
|
||||||
|
[
|
||||||
|
"git",
|
||||||
|
"-c",
|
||||||
|
"init.defaultRefFormat=reftable",
|
||||||
|
"init",
|
||||||
|
"-q",
|
||||||
|
tempdir,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
fakeproj = FakeProject(tempdir)
|
||||||
|
expected = subprocess.check_output(
|
||||||
|
["git", "-C", tempdir, "symbolic-ref", "-q", "HEAD"],
|
||||||
|
encoding="utf-8",
|
||||||
|
).strip()
|
||||||
|
self.assertEqual(expected, fakeproj.work_git.GetHead())
|
||||||
|
|
||||||
|
|
||||||
class CopyLinkTestCase(unittest.TestCase):
|
class CopyLinkTestCase(unittest.TestCase):
|
||||||
"""TestCase for stub repo client checkouts.
|
"""TestCase for stub repo client checkouts.
|
||||||
|
|||||||
Reference in New Issue
Block a user