From 97f708373d63cd783b9c15f202f4f741a1be3be4 Mon Sep 17 00:00:00 2001 From: Alex Hochheiden Date: Fri, 11 Sep 2026 14:34:37 -0700 Subject: [PATCH] feat(run-task): check out git working trees with parallel checkout git writes the working tree with one thread unless checkout.workers is set. With one worker per core the cold checkout write of the Firefox tree went from 27.9s to 13.3s on a GCP c3d-standard-8 docker worker and from 111.6s to 36.0s on an Azure Standard_F8alds_v7 Windows worker. Warm updates and blobless sparse checkouts did not change, since there the fetch dominates. The setting sits next to safe.directory in the global config, needs git 2.32, and older gits ignore the key. The git docs note that parallel checkout can be slower on spinning disks or machines with very few cores. Fixes #1040 --- src/taskgraph/run-task/run-task | 4 ++++ test/test_scripts_run_task.py | 36 +++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/taskgraph/run-task/run-task b/src/taskgraph/run-task/run-task index 57effaa5b..4e4e28299 100755 --- a/src/taskgraph/run-task/run-task +++ b/src/taskgraph/run-task/run-task @@ -921,6 +921,10 @@ def git_checkout( ] retry_required_command(b"vcs", args, extra_env=env) + workers = os.environ.get("RUN_TASK_GIT_CHECKOUT_WORKERS", "0") + args = ["git", "config", "--global", "checkout.workers", workers] + retry_required_command(b"vcs", args, extra_env=env) + is_sparse = ( has_repo and _git_config(destination_path, "core.sparseCheckout") == "true" ) diff --git a/test/test_scripts_run_task.py b/test/test_scripts_run_task.py index 209e288bd..57420be14 100644 --- a/test/test_scripts_run_task.py +++ b/test/test_scripts_run_task.py @@ -448,6 +448,42 @@ def test_git_checkout( assert current_rev == mock_git_repo[hash_key][-1] +@pytest.mark.parametrize( + "env_value,expected", + ( + pytest.param(None, "0", id="default"), + pytest.param("1", "1", id="disabled"), + pytest.param("4", "4", id="pinned"), + ), +) +def test_git_checkout_enables_parallel_checkout( + monkeypatch, mock_stdin, run_task_mod, mock_git_repo, tmp_path, env_value, expected +): + monkeypatch.delenv("RUN_TASK_GIT_CHECKOUT_WORKERS", raising=False) + if env_value is not None: + monkeypatch.setenv("RUN_TASK_GIT_CHECKOUT_WORKERS", env_value) + destination = tmp_path / "destination" + run_task_mod.git_checkout( + destination_path=destination, + head_repo=mock_git_repo["path"], + base_repo=mock_git_repo["path"], + base_rev=None, + head_ref="main", + head_rev=None, + ssh_key_file=None, + ssh_known_hosts_file=None, + ) + + workers = subprocess.check_output( + ["git", "config", "--global", "--get", "checkout.workers"], + cwd=destination, + universal_newlines=True, + ).strip() + # 0 means one worker per logical core, see + # https://git-scm.com/docs/git-config#Documentation/git-config.txt-checkoutworkers + assert workers == expected + + @pytest.mark.parametrize( "head_ref,head_rev_index", (