version: read describe and date in one Git call

Git 2.32 added the %(describe) pretty placeholder. Use one log format to
retrieve both repo's describe string and commit date on newer clients,
with the existing describe-plus-log path retained for older Git and
untagged output.

Bug: 553599402
Change-Id: I108346030677b2b90ef8bfb5acea1c45be2c85f2
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/623904
Tested-by: Gavin Mak <gavinmak@google.com>
Commit-Queue: Gavin Mak <gavinmak@google.com>
Reviewed-by: Brian Gan <brgan@google.com>
diff --git a/subcmds/version.py b/subcmds/version.py
index 5c817f1..5c05f90 100644
--- a/subcmds/version.py
+++ b/subcmds/version.py
@@ -14,10 +14,12 @@
 
 import platform
 import sys
+from typing import Any, Tuple
 
 from command import Command
 from command import MirrorSafeCommand
 from git_command import git
+from git_command import git_require
 from git_command import RepoSourceVersion
 from git_command import user_agent
 from git_refs import HEAD
@@ -34,6 +36,22 @@
 %prog
 """
 
+    @staticmethod
+    def _RepoVersion(project: Any) -> Tuple[str, str]:
+        """Return repo's describe string and commit date."""
+        if git_require((2, 32, 0)):
+            output = project.bare_git.log(
+                "-1", "--format=%(describe)%n%cD", HEAD
+            )
+            description, commit_date = output.rstrip("\n").split("\n", 1)
+            if description:
+                return description, commit_date
+
+        return (
+            project.bare_git.describe(HEAD),
+            project.bare_git.log("-1", "--format=%cD", HEAD),
+        )
+
     def Execute(self, opt, args):
         rp = self.manifest.repoProject
         rem = rp.GetRemote()
@@ -41,11 +59,11 @@
 
         # These might not be the same.  Report them both.
         src_ver = RepoSourceVersion()
-        rp_ver = rp.bare_git.describe(HEAD)
+        rp_ver, commit_date = self._RepoVersion(rp)
         print(f"repo version {rp_ver}")
         print(f"       (from {rem.url})")
         print(f"       (tracking {branch.merge})")
-        print(f"       ({rp.bare_git.log('-1', '--format=%cD', HEAD)})")
+        print(f"       ({commit_date})")
 
         if self.wrapper_path is not None:
             print(f"repo launcher version {self.wrapper_version}")
diff --git a/tests/test_subcmds_version.py b/tests/test_subcmds_version.py
new file mode 100644
index 0000000..72935e2
--- /dev/null
+++ b/tests/test_subcmds_version.py
@@ -0,0 +1,52 @@
+# Copyright (C) 2026 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Unittests for subcmds/version.py."""
+
+from unittest import mock
+
+import pytest
+
+from subcmds import version
+
+
+def test_repo_version_uses_one_pretty_format_call(
+    monkeypatch: pytest.MonkeyPatch,
+) -> None:
+    project = mock.MagicMock()
+    project.bare_git.log.return_value = "v2.0-1-g12345678\nTue, 25 Aug\n"
+    monkeypatch.setattr(version, "git_require", lambda _version: True)
+
+    result = version.Version._RepoVersion(project)
+
+    assert result == ("v2.0-1-g12345678", "Tue, 25 Aug")
+    project.bare_git.log.assert_called_once_with(
+        "-1", "--format=%(describe)%n%cD", "HEAD"
+    )
+    project.bare_git.describe.assert_not_called()
+
+
+def test_repo_version_keeps_old_git_fallback(
+    monkeypatch: pytest.MonkeyPatch,
+) -> None:
+    project = mock.MagicMock()
+    project.bare_git.describe.return_value = "v2.0"
+    project.bare_git.log.return_value = "Tue, 25 Aug"
+    monkeypatch.setattr(version, "git_require", lambda _version: False)
+
+    result = version.Version._RepoVersion(project)
+
+    assert result == ("v2.0", "Tue, 25 Aug")
+    project.bare_git.describe.assert_called_once_with("HEAD")
+    project.bare_git.log.assert_called_once_with("-1", "--format=%cD", "HEAD")