mirror of
https://gerrit.googlesource.com/git-repo
synced 2026-07-15 21:27:00 +00:00
sync: Implement fetchcmd for standard Git layouts
Introduce support for `repo.fetchcmd` configuration, allowing users to specify a custom command to fetch project data instead of `_RemoteFetch`. When `repo.fetchcmd` is specified, `repo` will execute it instead of `_RemoteFetch` during the network half of sync. Note that `repo.fetchcmd` requires `repo.uselocalgitdirs` to be enabled. The command is executed in a subshell with project-context environment variables, including the new `REPO_TREV` (target revision resolved to a commit hash) and `REPO_PROJECT_FETCH_URL`. After execution, `repo` verifies that the target commit is available and that the tracking ref and FETCH_HEAD are correctly updated. Tested with: ``` > ~/git-repo/repo init -u https://android-review.googlesource.com/platform/manifest \ --repo-url file:///usr/local/google/home/gavinmak/git-repo \ --groups developers \ --no-repo-verify \ --use-local-gitdirs ... > git config --file .repo/manifests.git/config repo.fetchcmd 'mkdir -p $REPO_PATH && cd $REPO_PATH && if [ ! -d .git ]; then git init && git remote add aosp $REPO_PROJECT_FETCH_URL; fi && git fetch aosp $REPO_TREV && git reset --hard $REPO_TREV && mkdir -p .git/refs/remotes/aosp && echo $REPO_TREV > .git/refs/remotes/aosp/main && echo $REPO_TREV > .git/FETCH_HEAD' > ~/git-repo/repo sync -j32 warning: repo is not tracking a remote branch, so it will not receive updates; run `repo init --repo-rev=stable` to fix. You are currently enrolled in Git submodules experiment (go/android-submodules-quickstart). Use --no-use-superproject to override. Syncing: 100% (4/4), done in 1m15.686s Finalizing sync state... repo sync has finished successfully. ``` Bug: 513329573 Change-Id: I754d3f3c78e86fdeee1a72115297a75b571bc497 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/583883 Reviewed-by: Becky Siegel <beckysiegel@google.com> Tested-by: Gavin Mak <gavinmak@google.com> Commit-Queue: Gavin Mak <gavinmak@google.com>
This commit is contained in:
committed by
gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
e7cac4bca6
commit
ead4b2d7aa
@@ -1286,3 +1286,71 @@ class GetEnvVarsTests(unittest.TestCase):
|
||||
env = proj.GetEnvVars()
|
||||
|
||||
self.assertEqual(env["REPO_LREV"], "")
|
||||
|
||||
|
||||
class FetchCmdTests(unittest.TestCase):
|
||||
"""Tests for fetch_cmd feature."""
|
||||
|
||||
def setUpManifest(self, tempdir):
|
||||
repodir = os.path.join(tempdir, ".repo")
|
||||
manifest_dir = os.path.join(repodir, "manifests")
|
||||
manifest_file = os.path.join(repodir, manifest_xml.MANIFEST_FILE_NAME)
|
||||
os.mkdir(repodir)
|
||||
os.mkdir(manifest_dir)
|
||||
manifest = manifest_xml.XmlManifest(repodir, manifest_file)
|
||||
|
||||
return project.ManifestProject(
|
||||
manifest, "test/manifest", os.path.join(tempdir, ".git"), tempdir
|
||||
)
|
||||
|
||||
def _get_project(self, tempdir):
|
||||
proj = _create_mock_project(
|
||||
tempdir, use_local_gitdirs=True, fetch_cmd="echo hi"
|
||||
)
|
||||
proj.GetRevisionId = mock.MagicMock(return_value="1234abcd")
|
||||
return proj
|
||||
|
||||
def test_fetch_cmd_execution(self):
|
||||
"""Test that fetch_cmd is executed with correct environment."""
|
||||
with utils_for_test.TempGitTree() as tempdir:
|
||||
proj = self._get_project(tempdir)
|
||||
|
||||
proj.bare_git.rev_parse.return_value = "1234abcd"
|
||||
mock_remote = mock.MagicMock()
|
||||
mock_remote.ToLocal.return_value = "refs/remotes/origin/main"
|
||||
proj.GetRemote = mock.MagicMock(return_value=mock_remote)
|
||||
|
||||
with mock.patch("subprocess.run") as mock_run:
|
||||
mock_run.return_value = mock.MagicMock(returncode=0, stderr="")
|
||||
res = proj._CustomFetch()
|
||||
|
||||
self.assertTrue(res)
|
||||
mock_run.assert_called_once()
|
||||
args, kwargs = mock_run.call_args
|
||||
self.assertEqual(args[0], "echo hi")
|
||||
self.assertEqual(kwargs["shell"], True)
|
||||
self.assertEqual(kwargs["cwd"], tempdir)
|
||||
self.assertEqual(kwargs["env"]["REPO_TREV"], "1234abcd")
|
||||
self.assertEqual(
|
||||
kwargs["env"]["REPO_PROJECT_FETCH_URL"],
|
||||
"http://example.com/repo",
|
||||
)
|
||||
|
||||
def test_sync_fetch_cmd_requires_use_local_gitdirs(self):
|
||||
"""Test that fetch_cmd requires use_local_gitdirs."""
|
||||
with utils_for_test.TempGitTree() as tempdir:
|
||||
fakeproj = self.setUpManifest(tempdir)
|
||||
|
||||
class DummyManifest:
|
||||
is_submanifest = False
|
||||
|
||||
def GetDefaultGroupsStr(self, with_platform=False):
|
||||
return ""
|
||||
|
||||
fakeproj.manifest = DummyManifest()
|
||||
|
||||
fakeproj.config.SetString("repo.fetchcmd", "echo hi")
|
||||
fakeproj.config.SetBoolean("repo.uselocalgitdirs", False)
|
||||
|
||||
result = fakeproj.Sync(use_local_gitdirs=False)
|
||||
self.assertFalse(result)
|
||||
|
||||
Reference in New Issue
Block a user