info: Report actual checked-out HEAD revision

When `repo info` runs, the reported "Current revision" is resolved using
the manifest's target branch tracking ref (e.g. refs/remotes/goog/main).

Introduce Project.GetHeadRevisionId(), which gets the checked-out HEAD
commit in the worktree, and use it in `repo info` with a fallback to the
old behavior if the project is not checked out.

Bug: 526685287
Change-Id: I72280ce27daa210cada27d722a94e365644f06e0
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/599481
Reviewed-by: Brian Gan <brgan@google.com>
Commit-Queue: Gavin Mak <gavinmak@google.com>
Tested-by: Gavin Mak <gavinmak@google.com>
This commit is contained in:
Gavin Mak
2026-06-22 22:36:20 +00:00
committed by gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com
parent c21a41c7cc
commit 88a7e88e54
4 changed files with 61 additions and 2 deletions
+22
View File
@@ -104,6 +104,28 @@ class ProjectTests(unittest.TestCase):
"abcd00%21%21_%2b",
)
def test_get_head_revision_id(self):
"""Check GetHeadRevisionId behavior."""
with utils_for_test.TempGitTree() as tempdir:
proj = _create_mock_project(tempdir)
# Initially unborn HEAD should return None.
self.assertIsNone(proj.GetHeadRevisionId())
# Create a commit.
with open(os.path.join(tempdir, "readme"), "w") as fp:
fp.write("hello")
proj.work_git.add("readme")
proj.work_git.commit("-m", "initial commit")
# HEAD should resolve to the commit SHA.
commit_sha = proj.work_git.rev_parse("HEAD")
self.assertEqual(commit_sha, proj.GetHeadRevisionId())
# Even if worktree is detached.
proj.work_git.checkout("HEAD~0")
self.assertEqual(commit_sha, proj.GetHeadRevisionId())
@unittest.skipUnless(
utils_for_test.supports_reftable(),
"git reftable support is required for this test",
+24
View File
@@ -199,3 +199,27 @@ def test_text_enables_pager() -> None:
cmd = _get_cmd()
opts, _ = cmd.OptionParser.parse_args([])
assert cmd.WantPager(opts)
def test_get_project_data_uses_head_revision() -> None:
"""_getProjectData should use GetHeadRevisionId if available."""
cmd = _get_cmd()
project = mock.MagicMock()
project.name = "foo"
project.worktree = "/path/to/foo"
project.revisionExpr = "refs/heads/main"
project.GetBranches.return_value = []
# GetHeadRevisionId() returns a SHA, it should be used.
project.GetHeadRevisionId.return_value = "head_sha_12345"
project.GetRevisionId.return_value = "manifest_sha_54321"
data = cmd._getProjectData(project)
assert data["current_revision"] == "head_sha_12345"
project.GetHeadRevisionId.assert_called_once()
# GetHeadRevisionId() is None, fall back to GetRevisionId().
project.GetHeadRevisionId.reset_mock()
project.GetHeadRevisionId.return_value = None
data = cmd._getProjectData(project)
assert data["current_revision"] == "manifest_sha_54321"