)]}'
{
  "log": [
    {
      "commit": "7bba4ee47e72ccfe7838b62869029e2f7436ce39",
      "tree": "39b0975800afe11cecb721046df7c314dd5a302c",
      "parents": [
        "d53a4278f5156d57d71fe401ba87efcd8435886a"
      ],
      "author": {
        "name": "Mike Frysinger",
        "email": "vapier@google.com",
        "time": "Mon Sep 28 22:46:10 2026 -0400"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Oct 05 10:40:31 2026 -0700"
      },
      "message": "vpython: update to uv spec format\n\nChange-Id: I18dca6f8c9c1f9234cfee640f780f1f2e4462ab8\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/635623\nCommit-Queue: Mike Frysinger \u003cvapier@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nTested-by: Mike Frysinger \u003cvapier@google.com\u003e\n"
    },
    {
      "commit": "d53a4278f5156d57d71fe401ba87efcd8435886a",
      "tree": "18c686d155c7b22ec5ca842e9b1ea8fbe59bb449",
      "parents": [
        "5d4149f32e3eb776ab3575a0d8db1ca51d6bb1b2"
      ],
      "author": {
        "name": "Rahul Yadav",
        "email": "yadavrah@google.com",
        "time": "Tue Aug 11 09:38:40 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu Oct 01 03:13:33 2026 -0700"
      },
      "message": "sync: Support manifest-driven default smart sync\n\nAdd support for enabling smart sync by default via the\nsync-smartsync\u003d\"true\" attribute on the manifest \u003cdefault\u003e element.\n\nWhen sync-smartsync is set to true in the manifest defaults:\n- Plain `repo sync` triggers Smart Sync automatically.\n- If that implicit Smart Sync fails (manifest server unreachable, or\n  the returned manifest cannot be parsed), repo silently falls back to\n  a regular ToT sync. The reason is logged with --verbose.\n- `--no-smart-sync` CLI flag overrides the manifest default and\n  syncs to ToT.\n- Passing explicit `-s` / `--smart-sync` forces Smart Sync as before,\n  and its failures are still fatal.\n- `-t`, `--smart-tag`, `-m`, `--manifest-name`, and\n  `--superproject-revision` disable the default smart sync.\n- `-l` / `--local-only` and `--no-manifest-update` skip the manifest\n  server and reuse the existing smart_sync_override.xml, if any.\n\nUpdate docs, completion, regenerate man pages, and add tests for XML\nparsing, serialization, CLI option resolution, and the fallback and\nreuse paths.\n\nBug: 545137090\nChange-Id: If75569c58dd525d170e9801e70ccbf02206a52f2\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/617641\nTested-by: Rahul Yadav \u003cyadavrah@google.com\u003e\nCommit-Queue: Rahul Yadav \u003cyadavrah@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "5d4149f32e3eb776ab3575a0d8db1ca51d6bb1b2",
      "tree": "14a90877d6546df07904bb55cbb01cb7102b5321",
      "parents": [
        "cf499e312af3acb67e086aefd6492e27614314c9"
      ],
      "author": {
        "name": "Victor Pushkarev",
        "email": "corvinus.v@gmail.com",
        "time": "Thu Sep 10 19:13:15 2026 +0300"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed Sep 30 01:11:40 2026 -0700"
      },
      "message": "gc: add --keep-manifest-projects\n\nBy default, `repo gc` treats projects excluded by the configured\nmanifest groups as unused. This matches the active project set, but it\ncan remove cached Git data for projects that might be used again after\nchanging groups.\n\nAdd `--keep-manifest-projects` to keep Git data for projects that are\nstill in the manifests, even if the current groups exclude them or their\ncheckout is missing. Git data for projects no longer in the manifests\ncan still be removed.\n\nChange-Id: I63ae18ce1c6acc2463be86f81921476b12fb27d7\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/629741\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nTested-by: Victor Pushkarev \u003ccorvinus.v@gmail.com\u003e\nCommit-Queue: Victor Pushkarev \u003ccorvinus.v@gmail.com\u003e\n"
    },
    {
      "commit": "cf499e312af3acb67e086aefd6492e27614314c9",
      "tree": "c7a93ff4dc87cea0cc8fcab308d5be280cc5e15d",
      "parents": [
        "cc0546bc71b79af60397957721d4d0b70eac67d7"
      ],
      "author": {
        "name": "Ram Peri",
        "email": "ramperi@google.com",
        "time": "Fri Sep 25 02:31:11 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Sep 28 15:34:54 2026 -0700"
      },
      "message": "sync: record superproject sync analysis state again\n\nSince the multi-manifest change (bdcba7d), _UpdateProjectsRevisionId\nrebinds its superproject_logging_data parameter to a new local dict.\nThe caller keeps its own empty dict and passes it to\nUpdateSyncAnalysisState, so repo.syncstate.superproject.* is never\nwritten to the manifest config or logged to trace2.\n\nDrop the rebinding so the caller\u0027s dict is populated.\n\nAlso record superproject, haslocalmanifests and hassuperprojecttag\nwhen no manifest declares a superproject. Before bdcba7d these keys\nwere logged on every sync. SyncAnalysisState does not remove old\nkeys, so without this a checkout that moves to a manifest without a\nsuperproject keeps reporting the values from its last superproject\nsync.\n\nBug: 565957530\nTest: ./run_tests\nChange-Id: I8796e3a34b9cf4786383d25ecc3ebf0c5409caa3\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/634843\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Ram Peri \u003cramperi@google.com\u003e\nTested-by: Ram Peri \u003cramperi@google.com\u003e\n"
    },
    {
      "commit": "cc0546bc71b79af60397957721d4d0b70eac67d7",
      "tree": "dbd5dfdd6fed136fdd8e8450ce6ab8e5004438ee",
      "parents": [
        "ccf9ce39b8228403d94007d3a1e9f2b153df7e8c"
      ],
      "author": {
        "name": "Mike Frysinger",
        "email": "vapier@google.com",
        "time": "Mon Sep 28 12:27:50 2026 -0400"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Sep 28 10:55:16 2026 -0700"
      },
      "message": "isort: print diff on failures\n\nThis should help users figure out how to fix problems.\n\nChange-Id: I6346e163d06f9a0e52147689c5b329fe7f1366d2\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/635343\nTested-by: Mike Frysinger \u003cvapier@google.com\u003e\nCommit-Queue: Mike Frysinger \u003cvapier@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "ccf9ce39b8228403d94007d3a1e9f2b153df7e8c",
      "tree": "cb5ae83936cdcce97bc251447c7942b1032e9ec8",
      "parents": [
        "9066409c2ddc24bbd2405f66e3358d479a17038f"
      ],
      "author": {
        "name": "Victor Pushkarev",
        "email": "corvinus.v@gmail.com",
        "time": "Thu Sep 17 10:47:00 2026 +0300"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Sat Sep 26 01:17:45 2026 -0700"
      },
      "message": "sync: keep local sync state paths relative to repo root\n\n`LocalSyncState` uses `Project.relpath` to identify projects, but that\npath is relative to each project\u0027s own manifest. Projects in different\nmanifests can have the same relpath, so their fetch and checkout\ntimestamps overwrite each other. This can make a later partial sync look\nlike a full sync.\n\nPruning has a related problem. It treats the stored paths as relative to\nthe current manifest\u0027s topdir, so when sync starts from the outermost\nmanifest it can look for submanifest projects in the wrong place and\nremove valid state.\n\nUse `Project.RelPath(local\u003dFalse)` to identify projects in local sync\nstate and check stored paths from the repo root when pruning.\n\nAdd tests for same-relpath projects, partial-sync detection, and pruning\nwhen sync starts from either the outermost manifest or a submanifest.\n\nChange-Id: I24485c315f1277a14913443674245cedd20820fe\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/632421\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nTested-by: Victor Pushkarev \u003ccorvinus.v@gmail.com\u003e\nCommit-Queue: Victor Pushkarev \u003ccorvinus.v@gmail.com\u003e\n"
    },
    {
      "commit": "9066409c2ddc24bbd2405f66e3358d479a17038f",
      "tree": "8a7d2caf84e28f68d8836e777ba888814baf0a09",
      "parents": [
        "2908f596c5bfce1cc34a49a69cf0ad9f6bc4a025"
      ],
      "author": {
        "name": "Ram Peri",
        "email": "ramperi@google.com",
        "time": "Thu Sep 24 19:53:57 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu Sep 24 13:54:06 2026 -0700"
      },
      "message": "init: don\u0027t suggest --no-use-superproject on failure\n\nWhen the superproject can\u0027t be fetched, repo init warns and tells users\nto re-run repo init with --no-use-superproject. That choice is saved in\nthe checkout config (repo.superproject), so following it disables the\nsuperproject for that checkout until it is re-inited, even though these\nfailures are often transient.\n\nDrop the recommendation and keep the rest of the warning.\n\nThis is the repo init counterpart of reverting\nhttps://gerrit-review.googlesource.com/c/git-repo/+/305622 for repo sync\n(https://gerrit-review.googlesource.com/c/git-repo/+/634804).\n\nBug: 565845573\nChange-Id: I91a6e682ef1d1c6dee07bc7969de88a681e1d239\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/634784\nTested-by: Ram Peri \u003cramperi@google.com\u003e\nReviewed-by: Sam Saccone \u003csamccone@google.com\u003e\nReviewed-by: Arif Kasim \u003carifkasim@google.com\u003e\nCommit-Queue: Ram Peri \u003cramperi@google.com\u003e\n"
    },
    {
      "commit": "2908f596c5bfce1cc34a49a69cf0ad9f6bc4a025",
      "tree": "aa56ab09b418905f037a0bac9125485ed2eca35c",
      "parents": [
        "e1e215a14ea5373419acb8753b6865de19d1f122"
      ],
      "author": {
        "name": "Ram Peri",
        "email": "ramperi@google.com",
        "time": "Thu Sep 24 19:36:52 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu Sep 24 13:53:54 2026 -0700"
      },
      "message": "Revert \"sync: Recommend using --no-use-superproject if sync fails.\"\n\nThis reverts commit f907ced0fead284b733872d9d5fd950996e52e9e.\nOriginal change: https://gerrit-review.googlesource.com/c/git-repo/+/305622\n\nReason for revert: the hint was added when a superproject failure made\nrepo sync exit with an error. Since 8db30d6 the failure is non-fatal\nand sync falls back to fetching normally, and these failures are often\ntransient (e.g. on 2026-09-23 a manifest change added\nexternal/slackhq/compose-lints before the superproject had a commit\nfor it, until the change was reverted ~2h later). Following the hint\nmeans users keep passing --no-use-superproject and bypass the\nsuperproject even after the failure is gone.\n\nThe revert does not apply cleanly after the black reformat, so the\nconflict was resolved by restoring the original message text.\n\nBug: 565845573\nChange-Id: I5efadedd4d3d0002df50493fa29554ba9626fe82\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/634804\nCommit-Queue: Ram Peri \u003cramperi@google.com\u003e\nReviewed-by: Sam Saccone \u003csamccone@google.com\u003e\nTested-by: Ram Peri \u003cramperi@google.com\u003e\n"
    },
    {
      "commit": "e1e215a14ea5373419acb8753b6865de19d1f122",
      "tree": "88446b761a72901bafe5dd1b785b47244c5483ec",
      "parents": [
        "175198b0aa22a54406be2b651020bb53c3c6d2b7"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Wed Sep 23 10:42:00 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed Sep 23 13:27:06 2026 -0700"
      },
      "message": "project: don\u0027t plan a stateless prune without a worktree\n\nSkip stateless prune planning when a project\u0027s worktree directory\ndoes not exist, preventing fetch failures on subsequent syncs.\n\nAlso run _LsRemote() bare so it does not depend on worktree\nexistence.\n\nBug: 565047698\nChange-Id: I385cba4e06813d9113ec7ddc963e8499acffaec5\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/634426\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\n"
    },
    {
      "commit": "175198b0aa22a54406be2b651020bb53c3c6d2b7",
      "tree": "8b7fc4a1baaa812bb82070b75954f565e7909045",
      "parents": [
        "310c99571f49e2d17f79853e69b7c17ff00f1bfc"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Wed Sep 23 10:27:17 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed Sep 23 13:27:01 2026 -0700"
      },
      "message": "sync: skip the bloat check for projects without a worktree\n\nSkip shallow clone bloat checks during --network-only syncs and\nfilter out projects whose worktree directory does not exist on disk.\n\nAlso return None quietly from _GetStatusSnapshot() when a project\nlacks an existing worktree directory.\n\nBug: 565047698\nChange-Id: Ia4c7db36a2bd78bc89e7b72f7a492b901b50efa7\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/634425\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "310c99571f49e2d17f79853e69b7c17ff00f1bfc",
      "tree": "00dff159b20833da38cebf108253b0a1996ce119",
      "parents": [
        "e7d4d97ffc7c33b4203cbae9d5da8f61d8bf8355"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Wed Sep 23 10:25:29 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed Sep 23 13:26:55 2026 -0700"
      },
      "message": "project: don\u0027t rerun git status after a failed snapshot\n\nWhen a status snapshot fails, fall back directly to _IsDirtyLegacy()\ninstead of IsDirty() to avoid running git status twice.\n\nExpose Project.GetDirtyAndHead() so sync bloat checks can inspect\nworktree state without invoking private Project methods.\n\nBug: 565047698\nChange-Id: I6432ed82da88778eec9d151fd5b70bedb1efc62b\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/634424\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "e7d4d97ffc7c33b4203cbae9d5da8f61d8bf8355",
      "tree": "4afdbb36e4918ae4947fc5bdac6c7715b4154896",
      "parents": [
        "8c7e0a683e88cf23f2c4765b26cfa1c917b660f4"
      ],
      "author": {
        "name": "Fredrik de Groot",
        "email": "fredrik.de.groot@haleytek.com",
        "time": "Wed Dec 11 10:13:11 2024 +0100"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Tue Sep 22 23:43:15 2026 -0700"
      },
      "message": "Fix fail in test_repo_trace if trace is disabled\n\nIf env has REPO_TRACE 0, then the test produces:\nFileNotFoundError: No such file or directory: TRACE_FILE_from_test\u0027\nbecause it assumes trace is always enabled.\n\nImprove by enabling trace for this test class.\n\nAlso modify the repo_trace.SetTrace API to take an optional\nTrue/False if needed, still defaults to True though.\n\nChange-Id: I2bb4632eb45ee529fc1785833e0bafd9c36f0875\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/445541\nCommit-Queue: Fredrik de Groot \u003cfredrik.de.groot@haleytek.com\u003e\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nTested-by: Fredrik de Groot \u003cfredrik.de.groot@haleytek.com\u003e\n"
    },
    {
      "commit": "8c7e0a683e88cf23f2c4765b26cfa1c917b660f4",
      "tree": "68a1f325f1700e624520c8863e2afc1027eccbae",
      "parents": [
        "f6f5946422097f2559cf3bc39a69d5fddc838ab8"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Aug 25 08:55:48 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Sep 21 13:40:06 2026 -0700"
      },
      "message": "info: reuse branch snapshots and combine history walks\n\nDerive the current branch from GetBranches so attached HEAD and refs are\nresolved once, including overview reporting. Replace the two\ncomplementary rev-list calls in --all output with one --left-right\nsymmetric-difference walk and partition its records in memory.\n\nBug: 553599402\nChange-Id: I01d5db804cbf591ecc0e08d6605971f0f5a38538\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/634005\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "f6f5946422097f2559cf3bc39a69d5fddc838ab8",
      "tree": "907c50c76bf1a0fc0d5d755913947c154ed09fe0",
      "parents": [
        "6321b26685ff9bdf5858e574dc4967761990ce5b"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Aug 25 08:57:34 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Sep 21 13:40:01 2026 -0700"
      },
      "message": "project: avoid unnecessary sync revision enumeration\n\nSkip the detached-history walk when its count will not be printed, ask\nrev-list --count for upstream gain, and cap the published-but-unmerged\nexistence probe at one commit. These preserve the decisions while\nreducing traversal and output work.\n\nBug: 553599402\nChange-Id: I30f769c9aa5269428ece15ffcb45c50993d7c4b8\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/634004\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\n"
    },
    {
      "commit": "6321b26685ff9bdf5858e574dc4967761990ce5b",
      "tree": "b88176124220df7421cbcfc6855097d18bbcaa50",
      "parents": [
        "7bffc72b5bf6bc8b6065ef6712e589457a3f7f20"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Aug 25 08:58:04 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Sep 21 13:39:56 2026 -0700"
      },
      "message": "project: make fast-forward merges explicit\n\nEvery caller expects _FastForward to reject a merge commit. Always pass\n--ff-only and remove the optional parameter so a violated ancestry\nassumption fails instead of silently creating a merge.\n\nBug: 553599402\nChange-Id: I04690b5ca675cb7d3062df08d5e20cd82f5b9e82\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/634003\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "7bffc72b5bf6bc8b6065ef6712e589457a3f7f20",
      "tree": "0036a6efee10ad0cf382b38c42ca751da2292fcc",
      "parents": [
        "aaadd5da35ce63799f902b3bdecc3091676530c9"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Aug 25 09:01:50 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Sep 21 13:39:51 2026 -0700"
      },
      "message": "project: fold normal stash detection into status\n\nWhen Git 2.35 or newer supplies a stash header, use the same status\nsnapshot for stateless dirty and stash checks. Retain rev-parse for\nearlier clients or when the status snapshot is unavailable.\n\nBug: 543851900\nBug: 553599402\nChange-Id: I6e310459d9c1a3ba7978f7907ae6b7a9bc611749\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/632146\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\n"
    },
    {
      "commit": "aaadd5da35ce63799f902b3bdecc3091676530c9",
      "tree": "22f74767b77fe79a6770e5b71afc4cd7af8c205f",
      "parents": [
        "c9448f986ef952487006e9c2d22989e98655c591"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Aug 25 08:48:50 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Sep 21 13:39:21 2026 -0700"
      },
      "message": "sync: reuse status HEAD in the bloat scan\n\nThe shallow-project bloat check already needs dirty state. Request\nbranch metadata in that same porcelain-v2 snapshot and use branch.oid\ninstead of launching a separate rev-parse, with the existing calls\nretained as a fallback.\n\nBug: 543851900\nBug: 553599402\nChange-Id: I3e7068c2e14c025a53adf92bfe8483b876cfda9d\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/632145\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "c9448f986ef952487006e9c2d22989e98655c591",
      "tree": "e0d4b6cbfdaf17295cc81ef442410e818d792e0c",
      "parents": [
        "530258d08ebcd61d8b8e96abc3a973f83bbfa81f"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Aug 25 08:47:56 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Sep 21 13:39:16 2026 -0700"
      },
      "message": "project: render worktree status from one snapshot\n\nUse porcelain-v2 branch and path records to replace the status display\nfan-out with one Git process on Git 2.11 and newer. Preserve the legacy\nrenderer for older clients, force rename and ahead/behind behavior where\nsupported, and fall back to the old divergence query only when status\ncannot supply branch.ab.\n\nBug: 543851900\nBug: 553599402\nChange-Id: Ic760360f4f48ab9320abf69dbbb7310dab4ac649\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/632144\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "530258d08ebcd61d8b8e96abc3a973f83bbfa81f",
      "tree": "e968f07d1045fe0bc1ab5a984c60b456822d4420",
      "parents": [
        "c1566487a800935a01a91050f49a9b1ab0799ae9"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Thu Sep 17 22:07:44 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Sep 21 13:37:38 2026 -0700"
      },
      "message": "project: use one status snapshot for dirty checks\n\nOn Git 2.11 and newer, replace update-index, diff-index, diff-files, and\nls-files fan-out with one porcelain-v2 snapshot for IsDirty,\nUncommittedFiles, and HasChanges. Preserve category ordering and\nduplicate staged-plus-unstaged paths, and keep the exact legacy path for\nolder Git or a failed snapshot.\n\nBug: 543851900\nBug: 553599402\nChange-Id: I309e39977e1f1d4ee6115f488d6aabb83ec3d83c\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/632143\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "c1566487a800935a01a91050f49a9b1ab0799ae9",
      "tree": "6989d64aa57507c8deebad7e6aac61e61509851a",
      "parents": [
        "22f820de17708afe7a4f0931aee9b6ee1880525e"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Aug 25 08:43:29 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Sep 21 13:36:55 2026 -0700"
      },
      "message": "git_status: parse one porcelain v2 worktree snapshot\n\nAdd a strict, NUL-aware parser for porcelain v2 records, including\nordinary changes, renames, conflicts, untracked paths, branch\ndivergence, and stash metadata. The reader is gated on Git 2.11, opts\ninto newer flags only when supported, and preserves arbitrary pathname\nbytes.\n\nBug: 543851900\nBug: 553599402\nChange-Id: Ibae3e1056fd9866f3cb6d490745d377cda1e8fef\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/632142\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\n"
    },
    {
      "commit": "22f820de17708afe7a4f0931aee9b6ee1880525e",
      "tree": "b328134deffa99fd68367da0ba4ae90325e73c72",
      "parents": [
        "4c37f588069d3a62b416ffcc25184119cd21e59e"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Aug 25 08:39:18 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Sep 21 13:36:47 2026 -0700"
      },
      "message": "git_command: allow lossless capture of machine output\n\nNUL-delimited Git formats may contain path bytes that are not valid\nUTF-8. Add an opt-in byte capture mode so parsers can preserve those\nbytes instead of receiving backslash replacements, while continuing to\ndecode stderr for diagnostics.\n\nBug: 543851900\nBug: 553599402\nChange-Id: Ia9dfcde065a0f6f72c785a4b96896f346e17510a\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/632141\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\n"
    },
    {
      "commit": "4c37f588069d3a62b416ffcc25184119cd21e59e",
      "tree": "eca93e12e8b3de9bfcb48b7d449591d9aebf18b4",
      "parents": [
        "c86ddc1628981a96391700c041f8493e145aa4c8"
      ],
      "author": {
        "name": "Sam Saccone",
        "email": "samccone@google.com",
        "time": "Thu Sep 03 18:31:58 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Sep 21 09:19:39 2026 -0700"
      },
      "message": "project: pass --no-filter and --no-tags in DownloadPatchSet\n\nIn partial clone checkouts (e.g. --filter\u003dblob:none or blob:limit\u003d10k),\nDownloadPatchSet previously invoked `git fetch \u003cremote\u003e \u003cref\u003e` without\nexplicit filter overrides. Consequently, git fetch applied the\nconfigured partial clone filter from the remote and omitted the blobs\nfor the incoming change.\n\nWhen repo download subsequently checks out, cherry-picks, or merges the\ndownloaded commit, Git discovers that the required blobs are missing\nlocally and triggers on-demand unadvertised object fetches to the\npromisor remote (POST /git-upload-pack with `want \u003cblob_sha\u003e`). On large\nrepositories, server-side reachability validation for unadvertised\nobjects can result in expensive graph traversals, proxy/gateway timeouts\n(such as HTTP 502 or connection drops), and client fetch failures:\n  fatal: expected \u0027packfile\u0027\n  fatal: could not fetch \u003csha\u003e from promisor remote\n\nPass --no-filter (when Git \u003e\u003d 2.17.0) and --no-tags when fetching patch\nsets in DownloadPatchSet. Because the change ref is an advertised ref\ntip, fetching with --no-filter allows the server to generate a complete\npackfile containing all required blobs upfront without requiring\nunadvertised object reachability checks. All blobs are present in the\nlocal object database prior to checkout or cherry-pick, completely\npreventing on-demand promisor queries.\n\nTAG\u003dagy\nCONV\u003dbdc489e3-b20b-4ef3-b32e-549dbe21fc6c\n\nGoogle-Bug-Id: b/532920848\nTest: pytest tests/test_project.py\nChange-Id: Ic6118e4edeb754f0467e0580fd1d0965a6553153\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/625621\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nTested-by: Sam Saccone \u003csamccone@google.com\u003e\nCommit-Queue: Sam Saccone \u003csamccone@google.com\u003e\n"
    },
    {
      "commit": "c86ddc1628981a96391700c041f8493e145aa4c8",
      "tree": "a5dfc50a00b243ab76c366e90677c0612c1b4d6a",
      "parents": [
        "c638b54e19f4765904613f729b2c9059fc4799d2"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Thu Sep 17 22:07:03 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu Sep 17 17:21:32 2026 -0700"
      },
      "message": "project: rename UncommitedFiles to UncommittedFiles\n\nFix typo in UncommitedFiles across project.py and HasChanges.\n\nBug: 553599402\nChange-Id: I2b9b606b4c9a47fd998e50cca976545fcd783771\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/632881\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "c638b54e19f4765904613f729b2c9059fc4799d2",
      "tree": "6f702cd0b4db264a8c1042d6a4e8d14f7a55f18e",
      "parents": [
        "fb4a91060ea34a939bb5ab6ffc494d1aa25e1979"
      ],
      "author": {
        "name": "Victor Pushkarev",
        "email": "corvinus.v@gmail.com",
        "time": "Tue Sep 15 16:07:01 2026 +0300"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed Sep 16 04:54:02 2026 -0700"
      },
      "message": "command: preserve project filters in regex selection\n\n`FindProjects` gets its candidate projects from `GetProjects` and then\napplies regex matching. However, it only forwards `all_manifests`, so\nother project filters are lost on regex paths.\n\nAs a result, `repo forall -r/-i --groups` falls back to the configured\ngroup selection instead of using the requested groups.\nSimilarly, `repo list -r --groups` ignores the requested groups, and\n`repo list -r --all` still excludes projects without a checkout.\n\nPass `groups` and `missing_ok` through `FindProjects`, and forward the\nexisting options from `forall` and `list`. When no group override is\ngiven, keep using each manifest\u0027s effective groups.\n\nAdd regression tests for `FindProjects` and both command paths.\n\nChange-Id: I5dfc22172fdd81de5312a84433867300a1342aec\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/631281\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Victor Pushkarev \u003ccorvinus.v@gmail.com\u003e\nTested-by: Victor Pushkarev \u003ccorvinus.v@gmail.com\u003e\n"
    },
    {
      "commit": "fb4a91060ea34a939bb5ab6ffc494d1aa25e1979",
      "tree": "845bda40ab02eea4db9c372894ae634fb1b8d920",
      "parents": [
        "4b3ada1781c7dc855858582a2b8f47fb0fc7f412"
      ],
      "author": {
        "name": "Victor Pushkarev",
        "email": "corvinus.v@gmail.com",
        "time": "Mon Sep 14 18:56:00 2026 +0300"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed Sep 16 04:53:31 2026 -0700"
      },
      "message": "tests: avoid losing trace2 socket readiness signal\n\nThe trace2 socket test uses a Condition to wait for its server to start\nlistening. If the server calls notify() before the test starts waiting,\nthe notification is lost and the test waits for the full 120-second\ntimeout before continuing.\n\nUse an Event for the readiness signal instead.\nOnce the server starts listening, the event stays set, so the test can\ncontinue immediately even if the server becomes ready before the test\nstarts waiting.\n\nChange-Id: I0e8e192d997c8bd785bcefa5d5b91493f93863e8\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/630861\nTested-by: Victor Pushkarev \u003ccorvinus.v@gmail.com\u003e\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Victor Pushkarev \u003ccorvinus.v@gmail.com\u003e\n"
    },
    {
      "commit": "4b3ada1781c7dc855858582a2b8f47fb0fc7f412",
      "tree": "96dfe0d012b1c66fa4ab941526a77d1b103d06c1",
      "parents": [
        "a468ea7752cddd67fa2242ef038ac96f53c35a6a"
      ],
      "author": {
        "name": "Victor Pushkarev",
        "email": "corvinus.v@gmail.com",
        "time": "Thu Sep 03 15:31:49 2026 +0300"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed Sep 16 04:51:54 2026 -0700"
      },
      "message": "sync: keep generated jobs-checkout help host-independent\n\nThe default shown for `--jobs-checkout` comes from `DEFAULT_LOCAL_JOBS`,\nwhich depends on the host CPU count. As a result, regenerating the sync\nand smartsync manpages on a different machine can change their output\neven though repo\u0027s behavior has not changed.\n\nUse shared CPU-based help formatting for `--jobs` and `--jobs-checkout`.\nInteractive help still shows the actual default, while generated\nmanpages describe it without including a host-specific value.\nRuntime job selection is unchanged.\n\nAdd coverage for both help modes and regenerate the affected manpages.\n\nChange-Id: Ia60e6fcc17b6f4618c52a76217c128eddead8848\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/625381\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nCommit-Queue: Victor Pushkarev \u003ccorvinus.v@gmail.com\u003e\nTested-by: Victor Pushkarev \u003ccorvinus.v@gmail.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "a468ea7752cddd67fa2242ef038ac96f53c35a6a",
      "tree": "42dd5085036f44d3559a992ee12b465850e5c095",
      "parents": [
        "c2c330ba4a92c915f0180457f0d7ee29031bb253"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Thu Sep 03 22:55:57 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Tue Sep 15 12:53:01 2026 -0700"
      },
      "message": "sync: implement reprojectcmd for the local half\n\nAdd `repo.reprojectcmd`, the checkout counterpart to `repo.fetchcmd`.\nWhen set, `repo sync` runs this command instead of Git to materialize a\nproject\u0027s index and worktree at the target tree, while `repo` handles\nref updates directly via `git update-ref`.\n\nThis replaces Git\u0027s tree materialization steps: detaching HEAD,\nfast-forwarding, and hard-resetting. Rebasing is not delegated, and the\ncommand is skipped if HEAD is already at the target, if HEAD is ahead of\nthe target during fast-forward, or for MetaProjects.\n\nThe command runs in a subshell with project environment variables (such\nas `REPO_TREV`). Before running, `repo` ensures no operation is in\nprogress and no staged changes exist. Worktree collision detection is\ndelegated to the command (preserving benign unstaged/untracked edits).\nAfterward, `repo` verifies that HEAD was untouched and that the index\nmatches the target tree.\n\nLike `repo.fetchcmd`, this requires `repo.uselocalgitdirs`. Nested\nprojects and submodules are unsupported; `repo sync` fails if the\nmanifest contains any while `repo.reprojectcmd` is enabled.\n\nVerified end-to-end with repo init using local-gitdirs, repo.fetchcmd,\nand repo.reprojectcmd (\u0027git -C $REPO_PATH read-tree -m -u $REPO_TREV\u0027):\n  * Verified detached HEAD checkout and correct reflog generation across\n    projects.\n  * Verified benign unstaged edits and untracked files survive checkout.\n  * Verified conflicting untracked files fail with exit 128 without\n    clobbering worktree.\n  * Verified staged changes fail upfront before reprojectcmd is executed.\n\nBug: 513329573\nChange-Id: I964d24d22dccffc05a9b991ad69f3a7e93268c01\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/626281\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "c2c330ba4a92c915f0180457f0d7ee29031bb253",
      "tree": "bb3ec8743022d0c220b0093d0f42c4fb6c384abf",
      "parents": [
        "cc88be34d214418511c13f2284ecdb22245fb650"
      ],
      "author": {
        "name": "Brian Gan",
        "email": "brgan@google.com",
        "time": "Mon Sep 14 14:14:24 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Sep 14 13:27:19 2026 -0700"
      },
      "message": "project: report why refreshing the index failed\n\n\"repo status\" aborts the whole tree when one project fails, without\nsaying why. The three callers that refresh the index stat cache pass -q,\nwhich suppresses git\u0027s diagnosis when it cannot create the index lock;\ngit then exits 128 with both streams empty. A stale lock, a permissions\nproblem on the gitdir and a full disk all reach that same silent exit,\nyet each needs a different remedy.\n\nRoute the three identical call sites through one helper that keeps -q\nfor the refresh itself. When that fails, it repeats the command without\n-q to obtain git\u0027s diagnosis. The command still fails, which is correct,\nbut the user is now told why.\n\nKeeping -q on the common path matters: without it git exits 1 whenever\npaths hold uncommitted changes, which would report a failure to\ntelemetry for every modified project, even if we treat it as benign in\nthe code. The retry accepts that 1, since --unmerged makes git skip\nconflicted paths rather than count them, so nothing else yields it.\n\nThe similar call in subcmds/sync.py is unchanged: it passes different\nflags, without --unmerged, so exit 1 cannot be assumed benign there.\n\nBug: 560289756\nChange-Id: I2e1024c84454f86076081f2d7f155728b1aa35c6\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/630641\nTested-by: Brian Gan \u003cbrgan@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Brian Gan \u003cbrgan@google.com\u003e\n"
    },
    {
      "commit": "cc88be34d214418511c13f2284ecdb22245fb650",
      "tree": "83e205c55a3f20a1af71c2831ed413ba66b59541",
      "parents": [
        "16cfb53e0ab9da8f40740885e5b287a0d912446c"
      ],
      "author": {
        "name": "Victor Pushkarev",
        "email": "corvinus.v@gmail.com",
        "time": "Tue Sep 01 19:38:49 2026 +0300"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Fri Sep 11 01:54:27 2026 -0700"
      },
      "message": "command: fix group selection across submanifests\n\nWhen GetProjects walks all manifests without explicit groups, it\nresolves the effective groups once from the selected manifest and reuses\nthem for projects from child manifests. This can ignore a child\nmanifest\u0027s own group selection and include projects that should be\nexcluded.\n\nWhen no groups are specified, resolve them from each project\u0027s owning\nmanifest. Explicit groups still apply to all projects in the call, and\nsingle-manifest behavior remains unchanged.\n\nAdd regression tests for per-manifest group selection, explicit\noverrides, and name lookup across manifests.\n\nBug: 382086294\nChange-Id: Id5c7e52410431b86b395f489cfd494ca05620975\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/624821\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Victor Pushkarev \u003ccorvinus.v@gmail.com\u003e\nTested-by: Victor Pushkarev \u003ccorvinus.v@gmail.com\u003e\n"
    },
    {
      "commit": "16cfb53e0ab9da8f40740885e5b287a0d912446c",
      "tree": "fd17243475ef56716f2fed58f6bf3981c705941b",
      "parents": [
        "578b57c9753a40d09c899ec41e0f7a839d6d208e"
      ],
      "author": {
        "name": "Victor Pushkarev",
        "email": "corvinus.v@gmail.com",
        "time": "Fri Sep 04 14:54:22 2026 +0300"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Fri Sep 11 01:52:38 2026 -0700"
      },
      "message": "release: update-manpages: restore __main__ guard\n\nThe update-manpages wrapper calls update_manpages.main() unconditionally.\nWith spawn and forkserver, multiprocessing re-executes the directly run\nmain script as __mp_main__.\nThe wrapper then calls main() again and tries to create another Pool\nwhile the child is still starting.\n\nProtect the entrypoint with __main__ guard. On Linux, this was mostly\nhidden while fork was the default start method; Python 3.14 now defaults\nto forkserver there. Normal command-line behavior is unchanged.\n\nAdd a regression test that mirrors multiprocessing\u0027s __mp_main__\nexecution path and checks that it does not call update_manpages.main().\n\nChange-Id: I28fdb18ccf2e4d61605cc072b4de52b6eb561335\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/626841\nTested-by: Victor Pushkarev \u003ccorvinus.v@gmail.com\u003e\nCommit-Queue: Victor Pushkarev \u003ccorvinus.v@gmail.com\u003e\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "578b57c9753a40d09c899ec41e0f7a839d6d208e",
      "tree": "853ccdd25ebd363968c64a1ce36c52ff8ed021df",
      "parents": [
        "fe2c23f8e2f00d6952a4e41f244f46598ba87461"
      ],
      "author": {
        "name": "Fredrik de Groot",
        "email": "fredrik.de.groot@haleytek.com",
        "time": "Mon Dec 15 09:08:00 2025 +0100"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu Sep 10 23:17:12 2026 -0700"
      },
      "message": "manifest_xml: Improve error message on base check fail\n\nPrevious error had a scent of alien blob to it\ndue to dumping the list in a single long line, so\nimprove print for human readability.\n\nExample of new fail:\n\nerror: in `manifest`: detected base-revision mismatch, updates needed:\nremove-project name build/make:\n  base fccb6b3e884b4b964e795f5f8865f6bbb4722b5a vs revision 6e9a0c16f20d1cfcf08b8b9cb42301b6c9712862\nremove-project path build/soong:\n  base 16b3c9ca0679bb376966866afb849322c8aec79f vs revision b7490575c16b87d861a532b03bd1b2d076b6fa0b\nextend-project name platform/system/sepolicy:\n  base c2652856e9f0e0433d78cfb481efe392d6f5dbc4 vs revision cf9a73f92f503ffc4bd3e726164babfb40a9fcaf\n\nTest: repo manifest \u003e /dev/null \u0026\u0026 echo \u0027Nice \u003d)\u0027\n      on various good and bad test manifests\nChange-Id: I8d741e11c69ef9e4f8cf09e32aa0868b6daa5acd\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/619921\nTested-by: Fredrik de Groot \u003cfredrik.de.groot@haleytek.com\u003e\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Fredrik de Groot \u003cfredrik.de.groot@haleytek.com\u003e\n"
    },
    {
      "commit": "fe2c23f8e2f00d6952a4e41f244f46598ba87461",
      "tree": "21ab2de162df140bf33f3e342a4b146fd8ad6867",
      "parents": [
        "d27d6829a84f488b7253ea693dcc429076c33914"
      ],
      "author": {
        "name": "Arif Kasim",
        "email": "arifkasim@google.com",
        "time": "Wed Aug 26 22:03:28 2026 -0400"
      },
      "committer": {
        "name": "Arif Kasim",
        "email": "arifkasim@google.com",
        "time": "Wed Sep 09 12:10:24 2026 -0700"
      },
      "message": "upload: bypass branch editor with explicit branch and -y\n\nWhen uploading across multiple projects with --yes and an explicit\nbranch specified (via --current-branch / -c or --branch / --br),\nrepo previously still opened the interactive branch selection editor.\n\nIf an explicit branch and --yes are provided, bypass the interactive\neditor and upload all matching pending branches directly.\n\nBug: 553024110\nTest: python3 -m pytest tests/\nTest: flake8 subcmds/upload.py tests/test_subcmds_upload.py\nTest: isort --check subcmds/upload.py tests/test_subcmds_upload.py\nChange-Id: I104619603f6e0539d05b01d3eb0292a9145d58db\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/622661\nTested-by: Arif Kasim \u003carifkasim@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "d27d6829a84f488b7253ea693dcc429076c33914",
      "tree": "8ca77dd2aa718648a449107c0b264d4d7127288c",
      "parents": [
        "0ea57e2eedbeae43e03c50b3aca4b890238d639f"
      ],
      "author": {
        "name": "Rahul Yadav",
        "email": "yadavrah@google.com",
        "time": "Tue Sep 01 15:45:32 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu Sep 03 02:15:23 2026 -0700"
      },
      "message": "project: check upstream ref ancestry for non-shallow clones\n\nIn _CheckForImmutableRevision, commit d9cc0a15 restricted upstream ref\nvalidation strictly to superprojects (if use_superproject) to prevent\nshallow clones with an upstream attribute from failing ancestry checks\nand falling back to full clones.\n\nHowever, restricting this check exclusively to superprojects broke\nnon-shallow projects with pinned immutable revisions (such as in Smart\nSync, `repo sync -t \u003cBUILD_ID\u003e`, or pinned manifests): When the target\ncommit already exists in the local Git object store (for instance,\nprefetched into refs/prefetch/ by a background daemon or via shared\nobject dirs), _CheckForImmutableRevision returned True without verifying\nthat the local tracking ref (refs/remotes/\u003cremote\u003e/\u003cupstream\u003e) is\npresent and reaches the revision. As a result, _RemoteFetch skipped\nfetching the upstream branch, leaving the local tracking ref stale or\nmissing. Subsequent `repo start` branches tracking that remote branch\ndiverged, causing `repo upload` to attempt uploading all intermediate\ncommits between the stale tracking ref and HEAD.\n\nRestore upstream ancestry validation in _CheckForImmutableRevision for\nnon-shallow projects when upstream is specified. Also pass the sync\ndepth into _CheckForImmutableRevision call sites so shallow checkouts\ncontinue to skip upstream verification and avoid triggering un-shallow\nfallbacks.\n\nTest: PYTHONPATH\u003d. pytest tests/test_project.py\nChange-Id: Ib5bdf41810bb06c8ed053447209ddc2e488f3913\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/624361\nTested-by: Rahul Yadav \u003cyadavrah@google.com\u003e\nCommit-Queue: Rahul Yadav \u003cyadavrah@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "0ea57e2eedbeae43e03c50b3aca4b890238d639f",
      "tree": "9fc6dfaa84b6e303bc936b75b35d8b5ab1351c76",
      "parents": [
        "ba8ddf396ce7888a6a502c1ec45d50ddef3ee341"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Aug 25 09:02:22 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed Sep 02 17:46:23 2026 -0700"
      },
      "message": "project: gate the default-branch query by Git version\n\nGIT_DEFAULT_BRANCH support was added to git var in Git 2.35. Skip that\nguaranteed failure on older supported clients and read\ninit.defaultBranch directly, reducing their fallback from two processes\nto one.\n\nBug: 553599402\nChange-Id: I079e9e6057b56afa41b685317a106fc9cdbad8a2\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/623907\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\n"
    },
    {
      "commit": "ba8ddf396ce7888a6a502c1ec45d50ddef3ee341",
      "tree": "dc75385239098e71837393701005853450d3e2fa",
      "parents": [
        "d88ce8d9520fa9eeccc891151d40202999376599"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Aug 25 09:03:57 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed Sep 02 17:46:01 2026 -0700"
      },
      "message": "git_superproject: resolve one negotiation ref directly\n\nThe superproject only needs one branch tip or HEAD OID. Resolve that ref\nwith one quiet rev-parse instead of constructing GitRefs, which loads\nthe entire namespace and resolves HEAD in two or three processes on\nolder clients.\n\nBug: 553599402\nChange-Id: I162d1133ebd1941e9de5aca43929fd5af17386ef\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/623906\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "d88ce8d9520fa9eeccc891151d40202999376599",
      "tree": "deae8d59db324b024834bb6c7558235b53eca3ea",
      "parents": [
        "5e8d2a6e3a779e700cbd229b8261e83b4eb24f8d"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Aug 25 09:01:03 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed Sep 02 17:45:55 2026 -0700"
      },
      "message": "upload: reuse the worker current-branch result\n\nCarry the current branch through _GatherOne so the parent can report a\nfailed current-branch upload without resolving HEAD a second time.\n\nBug: 553599402\nChange-Id: I3fc54be6c10c30470e14f792ff68c0a396519327\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/623905\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "5e8d2a6e3a779e700cbd229b8261e83b4eb24f8d",
      "tree": "3ee8d5be185fbd57a24fb089c548281c0e199f39",
      "parents": [
        "e59c9cde99172ba5f45964c18540476fd9f43f27"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Aug 25 09:00:33 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed Sep 02 17:45:49 2026 -0700"
      },
      "message": "version: read describe and date in one Git call\n\nGit 2.32 added the %(describe) pretty placeholder. Use one log format to\nretrieve both repo\u0027s describe string and commit date on newer clients,\nwith the existing describe-plus-log path retained for older Git and\nuntagged output.\n\nBug: 553599402\nChange-Id: I108346030677b2b90ef8bfb5acea1c45be2c85f2\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/623904\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\n"
    },
    {
      "commit": "e59c9cde99172ba5f45964c18540476fd9f43f27",
      "tree": "b29e2ce4077b35a449272085ef6768615ce25d9c",
      "parents": [
        "83428a9b260a660c6848905d17f6b3028fad9009"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Aug 25 08:59:37 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed Sep 02 17:43:55 2026 -0700"
      },
      "message": "cherry_pick: resolve and read commits in one process\n\nSend a typed revision expression to cat-file --batch over stdin and\nparse its object header and exact byte length. This safely resolves the\ncommit OID and retrieves its raw message in one Git process instead of\nseparate rev-parse and cat-file calls.\n\nBug: 553599402\nChange-Id: I764894323ec28e134f2523bd1d5694738b6b52d0\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/623903\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "83428a9b260a660c6848905d17f6b3028fad9009",
      "tree": "36af6c4202aaf71b04dde0d96bbeecea1a52a8ac",
      "parents": [
        "948abc85bcfd3f73d6cec4160506af325f721b71"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Aug 25 08:53:53 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed Sep 02 17:43:48 2026 -0700"
      },
      "message": "rebase: delegate automatic stashing to Git\n\nGit --autostash predates repo\u0027s minimum supported client. Pass it\ndirectly to rebase instead of probing the index and separately running\nstash and stash pop, reducing the dirty path from four Git processes to\none and correctly covering staged-only changes.\n\nBug: 553599402\nChange-Id: I0d6d59b17996576310498e9378e49380d355236e\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/623902\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "948abc85bcfd3f73d6cec4160506af325f721b71",
      "tree": "eac286d41867ca68089f940191ae2b8c19e81e61",
      "parents": [
        "c63a2f92fa9c01b1a58608a35f968da827b9ac3e"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Aug 25 09:04:41 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed Sep 02 17:41:05 2026 -0700"
      },
      "message": "git_config: recognize only complete object IDs\n\nFull Git object IDs are exactly 40 hexadecimal digits for SHA-1 or 64\nfor SHA-256. Stop treating every intermediate length as immutable, which\ncould bypass normal ref resolution for invalid revision strings.\n\nBug: 553599402\nChange-Id: I41b4ce6b2bfe2a2d8b351c7f040ec0cf469b474b\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/623901\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "c63a2f92fa9c01b1a58608a35f968da827b9ac3e",
      "tree": "076fd007d8833d48ffcd5541d9fcd3270c355656",
      "parents": [
        "0039e390000306a76388d2d2205ed72ab6148b06"
      ],
      "author": {
        "name": "kimhappy",
        "email": "hwanhee.kim@laplacian.cc",
        "time": "Thu Aug 27 10:56:16 2026 +0900"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Tue Sep 01 19:13:52 2026 -0700"
      },
      "message": "sync: tell apart same-path submanifest projects\n\nInterleaved sync remembers which projects are done and which ones are\nstill pending by Project.relpath, and lists failing projects by it as\nwell. That path is relative to the project\u0027s own (sub)manifest though,\nso once several manifests are synced together two projects can share\nit, and the sets no longer tell them apart.\n\nThe damage is done when a project turns up in a later pass, e.g. a\nsubmodule that is only derived once its parent has been synced: its\npath is already recorded as finished, so it is left out of every pass\nthat follows and never synced, while sync still reports success. With\nan outer manifest holding\n\n  \u003cproject name\u003d\"a\" path\u003d\"a\" sync-s\u003d\"true\"/\u003e\n\nwhere a carries a submodule at b, and a submanifest at sub/ holding\n\n  \u003cproject name\u003d\"sub-ab\" path\u003d\"a/b\"/\u003e\n\na fresh `repo sync` checks out sub/a/b but never a/b. Failing projects\nare reported under the same ambiguous path, and the stall detection\nmerges them too.\n\nUse RelPath(local\u003dopt.this_manifest_only) instead, which is unique\nwithin the set of projects being synced and is what GetProjects() and\nthe other subcommands already use.\n\nSpotted during the review of I30395b8a16a9154f60972e1f408a066af64ba77c.\n\nChange-Id: I5fa694b968774667be6060d9722cb57acbd2b579\nSigned-off-by: kimhappy \u003chwanhee.kim@laplacian.cc\u003e\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/622641\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\n"
    },
    {
      "commit": "0039e390000306a76388d2d2205ed72ab6148b06",
      "tree": "92de7b9275bbb89638d2675189e925867db41647",
      "parents": [
        "5f378458d2568f56927522518aff6ffd7db60678"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Aug 25 08:56:44 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Aug 31 13:26:22 2026 -0700"
      },
      "message": "project: carry current state from the ref snapshot\n\nAttach the current marker computed by GetBranches to uploadable and\nprunable branches. Overview and prune reporting can then reuse that\nresult instead of resolving HEAD once per displayed branch.\n\nBug: 553599402\nChange-Id: Ie3e23d08d0caf66c47cc12d7295ec4b6a834560c\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/623184\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "5f378458d2568f56927522518aff6ffd7db60678",
      "tree": "f5b1732d94a928aa5ee85f029d909529e6b5ec6e",
      "parents": [
        "d27034bf625d762fee2a246b53a9f91e3fe0e5cc"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Aug 25 08:53:15 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Aug 31 13:25:40 2026 -0700"
      },
      "message": "project: reuse ref OIDs in branch maintenance\n\nLoad refs before resolving the current branch, compare cached HEAD and\nmanifest OIDs instead of walking their symmetric difference, and reuse\nthe snapshot when preserving bare HEAD. Apply the same HEAD reuse to\nabandon and MetaProject checks, and bound the latter revision walk to\none commit.\n\nBug: 553599402\nChange-Id: I715e65dcfa02c0df4aaa08da5b7bfbb04ca17725\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/623183\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "d27034bf625d762fee2a246b53a9f91e3fe0e5cc",
      "tree": "de3235f2dc129754cc5332496fad5ba7476e497b",
      "parents": [
        "6541729a1844d4a7f4768576a57c48fed23a90bf"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Aug 25 08:51:03 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Aug 31 12:34:53 2026 -0700"
      },
      "message": "project: centralize safe branch and commit resolution\n\nResolve commit-ish values through one typed helper using rev-parse\n--verify --quiet and, on Git 2.30+, --end-of-options. Reject option-like\nrevisions on older clients, reuse the helper for project and manifest\nresolution, and validate user branch names with check-ref-format\n--branch.\n\nBug: 553599402\nChange-Id: I2dda49ff3e781cec14d3b84263a8dace06b4073f\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/623182\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\n"
    },
    {
      "commit": "6541729a1844d4a7f4768576a57c48fed23a90bf",
      "tree": "b293b6dc031c5ca211c974cedf39e076c5343d69",
      "parents": [
        "b85e76a86a0d8064be5500f65d1a71c49aa00c22"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Aug 25 08:38:35 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Aug 31 12:33:39 2026 -0700"
      },
      "message": "project: reuse loaded refs when resolving HEAD\n\nWhen the regular checkout has already loaded GitRefs, derive its current\nbranch and HEAD object from that snapshot instead of spawning\nsymbolic-ref or rev-parse again. Keep linked Git worktrees on their\nworktree-specific HEAD path because the shared repository HEAD is not\nauthoritative for them.\n\nBug: 543851900\nBug: 553599402\nChange-Id: Iec456be5f3c279865b4165a75d1c6df36e331dbc\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/623181\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "b85e76a86a0d8064be5500f65d1a71c49aa00c22",
      "tree": "50ddb5d7eecbd036f0059d13965000e80eb1b61c",
      "parents": [
        "e5bbb5c9e646a8c8068203596f628d20a7a58c43"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Aug 25 08:37:28 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Aug 31 11:57:39 2026 -0700"
      },
      "message": "git_refs: load HEAD with the ref snapshot on Git 2.45\n\nUse for-each-ref --include-root-refs to resolve attached and detached\nHEAD in the same process as refs/* on Git 2.45 and newer. Limit the\npatterns to HEAD and refs so volatile pseudo-refs do not enter the\ncache, and retain the existing fallback for older Git and unborn HEADs.\n\nBug: 543851900\nBug: 553599402\nChange-Id: Ie091ca0757f21ec6b1e19d49e09d160e055ec639\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/622981\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "e5bbb5c9e646a8c8068203596f628d20a7a58c43",
      "tree": "0d1517aeb9bb6d74e60484300f9f2cdbc8a683f6",
      "parents": [
        "4fe87617ff4ea1726ef43d072e7ef4f0178fa663"
      ],
      "author": {
        "name": "James Hawkins",
        "email": "jhawkins@google.com",
        "time": "Fri Aug 28 08:19:55 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Fri Aug 28 16:07:01 2026 -0700"
      },
      "message": "upload: prune ref scans for untouched projects and specific branches\n\nBenchmark (100 untouched projects):\n* GetUploadableBranches: 0.985s -\u003e 0.0004s (2,200x faster)\n* repo upload (3,045 projects): saves ~2.5s of redundant ref scans\n\nDuring `repo upload`, `GetUploadableBranches()` currently scans\n`self._allrefs` across all projects in the workspace. In large\nmanifests (e.g. Android with 3,000+ projects), `self._allrefs`\nexecutes `git for-each-ref`, `git symbolic-ref`, and full filesystem\nmtime traversals on thousands of projects where no local branch was\never started or modified.\n\nAny branch that can be uploaded for review must have upstream tracking\nconfigured via `[branch \"...\"]` sections in `.git/config`\n(otherwise `branch.LocalMerge` is None and `GetUploadableBranch`\nreturns None).\n\nThis patch introduces early-pruning fast paths:\n1. When no branch subsections exist in `.git/config`\n   (or only 2-part keys like `branch.autosetupmerge`), return []\n   immediately without touching `_allrefs`.\n2. When a `selected_branch` is specified (e.g. `repo upload --br\u003d...`),\n   query `branch.LocalMerge`, `refs/heads/\u003cbranch\u003e`, and\n   `refs/published/\u003cbranch\u003e` directly, skipping the whole-tree\n   ref scan.\n3. In `subcmds/upload.py`, optimize `_GetMergeBranch` to resolve the\n   merge branch in-memory via `project.CurrentBranch` and\n   `project.GetBranch()` instead of spawning two `GitCommand`\n   processes.\n\nTest: ./run_tests tests/test_project.py tests/test_subcmds_upload.py\nChange-Id: I3c2c9d63a68a393d478e1fb50f548ec8b7d44639\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/623021\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nCommit-Queue: James Hawkins \u003cjhawkins@google.com\u003e\nTested-by: James Hawkins \u003cjhawkins@google.com\u003e\n"
    },
    {
      "commit": "4fe87617ff4ea1726ef43d072e7ef4f0178fa663",
      "tree": "9010fed126bf1b27f62483d93c2f79dd4a3d182a",
      "parents": [
        "d7299422ae593e4b53a7f1e9526a66512039ece1"
      ],
      "author": {
        "name": "James Hawkins",
        "email": "jhawkins@google.com",
        "time": "Fri Aug 28 21:06:05 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Fri Aug 28 16:03:06 2026 -0700"
      },
      "message": "project: read HEAD directly in-memory to avoid subprocesses\n\nBenchmark:\n* repo upload frameworks/base: 2.84s -\u003e 0.50s (-82.3%, 5.6x faster)\n* repo upload (3,045 projects): 7.66s -\u003e 5.24s (-31.6%, 2.42s saved)\n\nFrom repo\u0027s inception through v2.56, GetHead() directly read the\n`.git/HEAD` file in Python. In commit 52bab0ba (\"project: Use git\nrev-parse to read HEAD\"), this was replaced with git subprocess calls\non the premise that git provides a dedicated command. However, in\nlarge multi-project workspaces (such as Android with 3,000+ projects),\nspawning thousands of git processes introduced severe latency\nregressions during `repo upload` and `repo status`.\n\nFurthermore, switching to subprocesses broke detached HEADs and\nunborn branches (fixed in commits 7f7d70ef and 8c3585f3 by re-adding\nthe v2.56 file-reading logic as an error recovery fallback).\n\nThis patch restores fast in-memory reading as the primary path, while\nadding modern defensive safeguards:\n* Symbolic refs (`ref: refs/heads/...`): Strips whitespace and tabs\n  and returns the ref directly in memory.\n* Detached HEAD: Validates 40-char SHA-1 and 64-char SHA-256 commit\n  hashes via git_config.IsId(), normalizing to lowercase.\n* Symlinks: Detects filesystem symlinks via os.path.islink() and\n  safely falls back to git symbolic-ref.\n* Fallback: Catches (OSError, AssertionError) and transparently falls\n  back to native git commands for reftables, unexpected layouts, or\n  filesystem errors. Unifies recovery fallback parsing with the fast\n  path (CRLF/tabs, lowercase hashes, and consistent RelPath errors).\n\nIn addition, this change substantially expands test coverage in\ntests/test_project.py, adding comprehensive unit tests for symbolic\nrefs, whitespace/tabs, CRLF line endings, SHA-1, SHA-256, uppercase\nhash normalization, symlinks, corrupted worktrees, and fallback\nrobustness.\n\nTest: ./run_tests tests/test_project.py\nChange-Id: Ib5c2530117c6939e4b9293feda81aa745c003c6a\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/623001\nCommit-Queue: James Hawkins \u003cjhawkins@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nTested-by: James Hawkins \u003cjhawkins@google.com\u003e\n"
    },
    {
      "commit": "d7299422ae593e4b53a7f1e9526a66512039ece1",
      "tree": "84a63ec8013e93bde092c2f0bf157efb054db981",
      "parents": [
        "3f087a8dd94c1e54eb8cda34c4923382607413a8"
      ],
      "author": {
        "name": "kimhappy",
        "email": "hwanhee.kim@laplacian.cc",
        "time": "Thu Aug 27 03:04:21 2026 +0900"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu Aug 27 16:22:54 2026 -0700"
      },
      "message": "sync: skip submodules removed from their parent\n\nThe submodules to sync are derived from their parent before it is\nfetched, so one that the parent\u0027s new revision no longer holds a gitlink\nfor is still synced. Interleaved sync then fails to check it out,\nbecause `git submodule init` no longer knows that path:\n\n  error: Cannot checkout a/c\n  error: pathspec \u0027.../a/c\u0027 did not match any file(s) known to git\n\nReport such submodules while the gitlinks are read again, and leave them\nout of the fetch and of the checkout, so the usual project list update\nremoves them from the working tree. Phased sync already left them out of\nthe checkout, but still fetched them.\n\nNothing is reported as removed while the gitlinks of a parent cannot be\nread, since a missing gitlink cannot be told apart from a fetch that did\nnot happen.\n\nBug: 550074864\nChange-Id: Ia429b35c12758a68e4df73665e5512a201af658a\nSigned-off-by: kimhappy \u003chwanhee.kim@laplacian.cc\u003e\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/621681\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\n"
    },
    {
      "commit": "3f087a8dd94c1e54eb8cda34c4923382607413a8",
      "tree": "8ace5594271ad4cf86e111355861585bc9f88889",
      "parents": [
        "3a6e25af7537181aae251951b8aabe7748c3aee5"
      ],
      "author": {
        "name": "kimhappy",
        "email": "hwanhee.kim@laplacian.cc",
        "time": "Thu Aug 27 03:04:15 2026 +0900"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu Aug 27 16:22:49 2026 -0700"
      },
      "message": "sync: fetch submodules after their parent repository\n\nPhased sync fetches every project at once, so a submodule is fetched at\nthe gitlink that was read before its parent was fetched. With -c that\nstale revision is already present, the fetch is skipped as an immutable\nrevision, and the checkout then fails on the revision the reloaded\nmanifest resolved:\n\n  error: Cannot checkout a/b\n  fatal: bad object 5556dad99da5df7e53303c5732aacc8782493e03\n\nFetch in batches, holding a submodule back until the project holding its\ngitlink is fetched, and read the gitlinks again between batches. A\nmanifest without submodules keeps its single batch.\n\nBug: 550074864\nChange-Id: I04c2eb1ca81ab25b4df2c03c5dc048d2e4ecdcb8\nSigned-off-by: kimhappy \u003chwanhee.kim@laplacian.cc\u003e\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/621663\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\n"
    },
    {
      "commit": "3a6e25af7537181aae251951b8aabe7748c3aee5",
      "tree": "5000ea657357c0c50fa4176aa48775e7d41d6a86",
      "parents": [
        "41c2597509e3e2228688668fbfb2d8bcfb5891b1"
      ],
      "author": {
        "name": "kimhappy",
        "email": "hwanhee.kim@laplacian.cc",
        "time": "Thu Aug 27 03:04:10 2026 +0900"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu Aug 27 16:22:43 2026 -0700"
      },
      "message": "sync: check out submodules at the parent\u0027s new revision\n\nInterleaved sync processes projects in hierarchical levels, so a\nsubmodule is only handled after the project holding its gitlink has been\nfetched and checked out. Its revision, however, is still the one read\nbefore that parent was fetched, so the submodule is synced to the\nrevision of the previous sync and only catches up on the next one.\n\nRead the gitlinks again right before a level is dispatched. The parent\nis done by then, so its submodules are fetched and checked out at the\nrevision the parent now points at. Sibling submodules are spread over\nseveral levels, so the gitlinks read for one level are carried over to\nthe next ones and every project is only read once per pass.\n\nBug: 550074864\nChange-Id: I30395b8a16a9154f60972e1f408a066af64ba77c\nSigned-off-by: kimhappy \u003chwanhee.kim@laplacian.cc\u003e\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/621662\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\n"
    },
    {
      "commit": "41c2597509e3e2228688668fbfb2d8bcfb5891b1",
      "tree": "f6cdd39e80c2c5695a2fd37fd53aa2d63f803455",
      "parents": [
        "e6ad7080098a0db0cb304812c8603856da2bebf2"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Wed Aug 26 18:42:59 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu Aug 27 12:43:00 2026 -0700"
      },
      "message": "project: don\u0027t use dest-branch or tags as SHA-1 upstream fallback\n\nhttps://gerrit-review.googlesource.com/614762 resolves a fallback\nupstream for a SHA-1-pinned project that has no explicit upstream, so\n--current-branch can narrow the fetch to one branch instead of fetching\nall heads.\n\nIt drew that fallback from dest-branch and from the manifest \u003cdefault\u003e\nupstream, dest-branch, and revision. dest-branch and tags are not valid\nfallback candidates:\n\n* dest-branch is the review destination for upload, not a fetch\n  source.\n* Tags are meant to be immutable snapshots of a single tagged commit,\n  and fetching it cannot retrieve an arbitrary pinned SHA-1.\n\nRestrict the fallback to branch heads resolved from the manifest\nupstream and revision defaults, and drop dest-branch entirely.\n\nBug: 541240657\nBug: 544041102\nChange-Id: I89ae86891ee166f4c340553ac5a9068efcc18461\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/622541\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\n"
    },
    {
      "commit": "e6ad7080098a0db0cb304812c8603856da2bebf2",
      "tree": "748d6b5e3983a874c34177da480330f676b29ba2",
      "parents": [
        "09914bcab7d1d5570c20a52d1861957145da8a5a"
      ],
      "author": {
        "name": "Rahul Yadav",
        "email": "yadavrah@google.com",
        "time": "Fri Aug 14 15:09:22 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu Aug 27 03:28:58 2026 -0700"
      },
      "message": "hooks: add --fix option to auto-apply hook fixes\n\nPass the --fix flag as a keyword argument \"fix\" to the hook main\nfunction. This allows hooks (such as git-repohooks) to decouple\nautomated fix application from the -y/--yes flag so that -y can\nanswer yes to upload confirmation prompts without triggering file\nmutations.\n\nCompanion change in git-repohooks:\nhttps://gerrit-review.googlesource.com/c/git-repohooks/+/621761\n\nBug: 546510319\nTest: python3 -m pytest tests/test_hooks.py\n\nChange-Id: If0288d4791fc0a2aba6e88854e3aa81b0923b664\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/619281\nCommit-Queue: Rahul Yadav \u003cyadavrah@google.com\u003e\nTested-by: Rahul Yadav \u003cyadavrah@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "09914bcab7d1d5570c20a52d1861957145da8a5a",
      "tree": "0f9488ef64d251f5cf356f75913666ccb38e30a0",
      "parents": [
        "3f1775607ffe67548fc5b43a0ce2021002069ee6"
      ],
      "author": {
        "name": "Ram Peri",
        "email": "ramperi@google.com",
        "time": "Fri Aug 07 21:54:45 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed Aug 26 10:19:42 2026 -0700"
      },
      "message": "Add detailed upload context to Trace2 telemetry\n\nThis patch intercepts the output during a successful upload\nexecution to capture the generated CL URLs. It logs a dynamically\nconstructed \"repo.uploadstate\" data event to the active trace2\nlog containing:\n- Uploaded CL URLs\n- Target remote name\n- Source branch\n- Modified files\n\nTest:\n1. ./run_tests\n2. pytest tests/test_project.py\n3. Manual verification:\n- Created a dummy branch `test_upload_branch` in a project with local file changes.\n- Invoked repo upload passing an explicit trace output directory:\n  `repo --git-trace2-event-log\u003d/tmp/trace2out upload --dry-run --no-verify art`\n- Verified the injected payload successfully appeared on disk within the generated log:\n  ```json\n  {\"event\":\"data\",...\"key\":\"repo.uploadstate/cls\",\"value\":\"\"}\n  {\"event\":\"data\",...\"key\":\"repo.uploadstate/remote\",\"value\":\"goog\"}\n  {\"event\":\"data\",...\"key\":\"repo.uploadstate/branch\",\"value\":\"test_upload_branch\"}\n  {\"event\":\"data\",...\"key\":\"repo.uploadstate/files\",\"value\":\"dummy_file.txt\"}\n  ```\n  (cls is correctly blank on --dry-run but populates on real HTTP pushes)\n\nBug: 543953499\nChange-Id: I9c402a32d01d156d42cf24eaa2e60e22710b5e6f\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/616581\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nTested-by: Ram Peri \u003cramperi@google.com\u003e\nCommit-Queue: Ram Peri \u003cramperi@google.com\u003e\n"
    },
    {
      "commit": "3f1775607ffe67548fc5b43a0ce2021002069ee6",
      "tree": "ad115a2937527f99511ef037d6d1035715bb6d73",
      "parents": [
        "b85886fa9f5b4e2189cc5b2f40bd0a80459d4c77"
      ],
      "author": {
        "name": "kimhappy",
        "email": "hwanhee.kim@laplacian.cc",
        "time": "Tue Aug 25 13:02:01 2026 +0900"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Tue Aug 25 19:39:51 2026 -0700"
      },
      "message": "project: allow re-reading submodule gitlinks\n\nA discovered submodule becomes a project whose revision is the gitlink\nread from its parent at manifest load time, which is before the parent\nhas been fetched. Remember which gitlink a submodule was derived from,\nand add a way to read those gitlinks again, so that callers can resolve\na submodule revision once its parent is up-to-date.\n\nA revision that is set does not have to be fetched, so verify its\nobjects are really there. Without them a submodule that was removed\ncannot be told apart from one that was never fetched, which the caller\nhas to know about.\n\nBug: 550074864\nChange-Id: I4f35d53607126508eec6f02158a3fb604917a199\nSigned-off-by: kimhappy \u003chwanhee.kim@laplacian.cc\u003e\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/621661\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "b85886fa9f5b4e2189cc5b2f40bd0a80459d4c77",
      "tree": "8ff38152b13b3a9df4c9840294a5f2bf7d069431",
      "parents": [
        "d9da609d8c120bb882a43196a4a6b7f183418304"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Mon Aug 10 15:29:43 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Aug 10 13:37:04 2026 -0700"
      },
      "message": "project: skip manifest default fallback for MetaProjects\n\nAvoid loading manifest.xml during repo init when syncing a manifest\ncommit SHA. Override _GetUpstreamFallback and _SharingProjectHasShallow\nin MetaProject to prevent premature manifest parsing.\n\nBug: 544041102\nChange-Id: I7aa54a7c1282e5bfe811d59e977b44163a37653c\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/617081\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\n"
    },
    {
      "commit": "d9da609d8c120bb882a43196a4a6b7f183418304",
      "tree": "201579df7c4462b3a603448ed2bcc65a731e5162",
      "parents": [
        "4bec297eb6e5f30ea2fe2a2d8a92054cafa30e4f"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Aug 04 20:13:19 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Tue Aug 04 15:00:19 2026 -0700"
      },
      "message": "project: preserve -c optimization when revision is a SHA-1\n\nAvoid disabling --current-branch when syncing a SHA-1 revision without\nan explicit project upstream (e.g., smart tags). Resolve a fallback\nupstream from dest-branch or manifest defaults so -c only fetches the\ntarget branch.\n\nBug: 541240657\nChange-Id: Ib44b6a732131210e1ec3a3136747d1a19bc5aa18\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/614762\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "4bec297eb6e5f30ea2fe2a2d8a92054cafa30e4f",
      "tree": "9eb41f64c61e43c2665156165264f840de230ec6",
      "parents": [
        "54fa31cd844b3de887a1915755b110287a4d2bcb"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue May 19 02:07:33 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Tue Aug 04 11:38:03 2026 -0700"
      },
      "message": "command: Respect smart sync override declaratively by default\n\nIntroduce a `RESPECT_SMART_SYNC_OVERRIDE` class attribute to the base\n`Command` class, defaulting to `True`. This allows subcommands to\nautomatically respect the smart sync override manifest if it exists.\n\nThe override is applied in `CommonValidateOptions` before any\nsubcommand-specific validation or execution occurs. The `sync` and\n`init` commands explicitly opt out.\n\nThis ensures all workspace-aware subcommands consistently align with the\nactive smart sync override manifest. It also fixes a bug in\nmulti-manifest setups where running a command from a submanifest would\nnot apply the override to the outer manifest, causing inconsistency when\nresolving projects across all manifests.\n\nBug: 279204331\nChange-Id: I9426e90a13a77ce6bd94b4a82efda4d485cbe116\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/585081\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "54fa31cd844b3de887a1915755b110287a4d2bcb",
      "tree": "ba113b235b162de2fd2a355d022abe822a7d7489",
      "parents": [
        "29b6630a6532b20fc26c7b44d8fa69fd4db390a0"
      ],
      "author": {
        "name": "Brian Gan",
        "email": "brgan@google.com",
        "time": "Thu Jul 30 23:21:22 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu Jul 30 17:00:00 2026 -0700"
      },
      "message": "project: derive HEAD fallback from git\u0027s own default branch\n\nWhen the default branch cannot be determined dynamically, repo fell back\nto a hardcoded \"refs/heads/master\". This can point at a branch that does\nnot exist on the server, since projects increasingly default to \"main\".\nRather than swap one hardcoded name for another, ask git itself what it\nwould use.\n\nBug: 483758905\nChange-Id: Ic66712acea98f8e548a2d6d8211865ee5c416b4d\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/612845\nTested-by: Brian Gan \u003cbrgan@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Brian Gan \u003cbrgan@google.com\u003e\n"
    },
    {
      "commit": "29b6630a6532b20fc26c7b44d8fa69fd4db390a0",
      "tree": "32896087c363fa9d73b6fc01c4bb6bb2a269d235",
      "parents": [
        "0b82311632d14d3f49675fb6a017c20f7a7dee37"
      ],
      "author": {
        "name": "Brian Gan",
        "email": "brgan@google.com",
        "time": "Wed Jul 29 23:25:20 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu Jul 30 10:01:58 2026 -0700"
      },
      "message": "project: make GetHead file-read fallback reftable-aware\n\nWhen both `git symbolic-ref` and `git rev-parse` fail to resolve HEAD,\nGetHead falls back to reading .git/HEAD directly. With the \"reftable\" ref\nbackend, .git/HEAD is only a stub pointing at the \"refs/heads/.invalid\"\nplaceholder while the real HEAD lives in the reftable stack. Reading the\nstub returned that bogus placeholder value.\n\nDetect the placeholder and treat HEAD as unresolvable (raising\nNoManifestException) instead of returning the invalid ref.\n\nBug: 483758905\nChange-Id: Ia0a825c0d1874686b98c5ddcdea6dc26c0d46784\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/612882\nTested-by: Brian Gan \u003cbrgan@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Brian Gan \u003cbrgan@google.com\u003e\n"
    },
    {
      "commit": "0b82311632d14d3f49675fb6a017c20f7a7dee37",
      "tree": "265e41f241585ae11afd6f4b12dfa0e9a60ef726",
      "parents": [
        "06c4f9e1cca33a51b5396de2d1d975648e9f2ce4"
      ],
      "author": {
        "name": "Andrew Chant",
        "email": "achant@google.com",
        "time": "Fri Jul 17 15:09:06 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Tue Jul 21 13:42:38 2026 -0700"
      },
      "message": "sync: allow syncing groups with repo sync -g group\n\nSimilar to how repo init -g can restrict repo syncs to\na subset of the manifest globally, allow \"repo sync -g\" to only sync a\nsubset of projects from the manifest when running that specific\nsync command.\n\nChange-Id: I4929aad109de05c73a7db42bb27fd8d47eea32fc\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/609481\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nCommit-Queue: Andrew Chant \u003cachant@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nTested-by: Andrew Chant \u003cachant@google.com\u003e\n"
    },
    {
      "commit": "06c4f9e1cca33a51b5396de2d1d975648e9f2ce4",
      "tree": "0db9673ac4ba01d024d5e23b62a4c009c89a0055",
      "parents": [
        "dd1130352be015979413da0caa3cbd882ee5bf87"
      ],
      "author": {
        "name": "Andrew Chant",
        "email": "achant@google.com",
        "time": "Tue Jul 21 10:07:14 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Tue Jul 21 13:42:30 2026 -0700"
      },
      "message": "git_superproject: don\u0027t filter rewritten manifest\n\nWhen creating the superproject manifest, take all groups\nfrom the original manifest, including notdefault.\n\nUsing the ManifestGroupsStr will inadvertantly filter out\nnotdefault projects from the superproject manifest.\n\nChange-Id: If3daf41e9a6572348de9182fe8679b90d3cec833\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/610021\nCommit-Queue: Andrew Chant \u003cachant@google.com\u003e\nTested-by: Andrew Chant \u003cachant@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "dd1130352be015979413da0caa3cbd882ee5bf87",
      "tree": "d603401070867fdef220e1b75eb0b70b85b40fb3",
      "parents": [
        "eeba6f268d0220bc928ed7af41d310dfbe215205"
      ],
      "author": {
        "name": "Josef Malmström",
        "email": "josef.malmstrom@arm.com",
        "time": "Thu Jul 16 11:09:40 2026 +0200"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Tue Jul 21 00:19:21 2026 -0700"
      },
      "message": "sync: Deprecate fetch-submodules flag names\n\nThe names for flags --fetch-submodules / --no-fetch-submodules are\nmisleading, since they impact the full sync operation (fetch and\ncheckout), not just the fetching.\n\nIntroduce new flags --recurse-submodules / --no-recurse-submodules\nand treat the old ones as deprecated aliases.\n\nChange-Id: I78339a3e0496a855c222c1869b27b578507886a7\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/608881\nCommit-Queue: Josef Malmstrom \u003cJosef.Malmstrom@arm.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nTested-by: Josef Malmstrom \u003cJosef.Malmstrom@arm.com\u003e\n"
    },
    {
      "commit": "eeba6f268d0220bc928ed7af41d310dfbe215205",
      "tree": "60dbb9793ede294214181e175c9c92a8d6fc6ae9",
      "parents": [
        "1729aaebaed8912cec20e5191d961400c08e98b1"
      ],
      "author": {
        "name": "Rahul Yadav",
        "email": "yadavrah@google.com",
        "time": "Fri Jul 10 08:39:24 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Jul 20 07:56:03 2026 -0700"
      },
      "message": "hooks: pass yes flag when available\n\nPass the -y flag as a keyword argument \"yes\" to the hook main function.\nThis allows upload hooks (such as auto-fixers) to automatically\napply fixes when the -y flag is passed, rather than prompting the user.\n\nBug: 498893733\nChange-Id: I12096029aa3af471ba9175314d749deb0ebd1007\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/605261\nCommit-Queue: Rahul Yadav \u003cyadavrah@google.com\u003e\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nTested-by: Rahul Yadav \u003cyadavrah@google.com\u003e\n"
    },
    {
      "commit": "1729aaebaed8912cec20e5191d961400c08e98b1",
      "tree": "dd79e3469727929b249e492e0819f2408a2f8851",
      "parents": [
        "978adb7ea504ae5c9238d03cea63f916035765c4"
      ],
      "author": {
        "name": "Ajay Gupta",
        "email": "ajagup@qti.qualcomm.com",
        "time": "Fri Apr 17 12:43:57 2026 +0530"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu Jul 16 11:51:00 2026 -0700"
      },
      "message": "project: Skip superproject upstream check for MetaProjects\n\nThe superproject-gated upstream check in _CheckForImmutableRevision\nonly applies to user projects listed in the manifest. MetaProjects\n(ManifestProject and RepoProject) never participate in a superproject\nrelationship, so evaluating git_superproject.UseSuperproject(...,\nself.manifest) for them serves no purpose and, worse, calls the\nmanifest.superproject property which forces a manifest load.\n\nDuring repo init, ManifestProject._ConfigureDependencies calls\nself.Sync_NetworkHalf before manifest.xml has been linked into\n.repo/. That reaches _CheckForImmutableRevision, which triggered the\nmanifest load and failed with:\n\n  ManifestParseError: .../.repo/manifest.xml: [Errno 2] No such file\n  or directory\n\nbreaking fresh repo init with SHA-based --manifest-branch combined\nwith --manifest-upstream-branch.\n\nFactor the \"should we consult the superproject for upstream?\"\ndecision into a small overridable hook, _UseSuperprojectForUpstream.\nProject\u0027s default delegates to git_superproject.UseSuperproject;\nMetaProject overrides it to return False, localizing the\nMetaProject-specific behavior to MetaProject.\n\nTest verifies that calling _CheckForImmutableRevision on a\nManifestProject whose manifest.xml is not yet on disk returns False\nwithout raising and does not create the file.\n\nChange-Id: I22059109243d914036c06c6fe0081a5aba05da89\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/574201\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Ajay Gupta \u003cajagup@qti.qualcomm.com\u003e\nTested-by: Ajay Gupta \u003cajagup@qti.qualcomm.com\u003e\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nReviewed-by: Nasser Grainawi \u003cnasser.grainawi@oss.qualcomm.com\u003e\n"
    },
    {
      "commit": "978adb7ea504ae5c9238d03cea63f916035765c4",
      "tree": "2c75b3585c3f13dab843667a0842376fada75cbc",
      "parents": [
        "0398c6718e8a17c374d868fbf253530bbc6ca13c"
      ],
      "author": {
        "name": "Josef Malmström",
        "email": "josef.malmstrom@arm.com",
        "time": "Mon Jul 13 12:50:52 2026 +0200"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu Jul 16 01:19:51 2026 -0700"
      },
      "message": "sync: Add CLI flag for globally disabling submodule fetch\n\nA global setting for disabling fetching of submodules is useful\nsince this can currently otherwise only be done by modifying\nthe manifest, or by explicitly providing projects on command line.\n\nAdd this setting as --no-fetch-submodules to mirror the existing\n--fetch-submodules.\n\nChange-Id: Ic727c54f11a594aa52315751284b87138cf246bb\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/607641\nCommit-Queue: Josef Malmstrom \u003cJosef.Malmstrom@arm.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nTested-by: Josef Malmstrom \u003cJosef.Malmstrom@arm.com\u003e\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\n"
    },
    {
      "commit": "0398c6718e8a17c374d868fbf253530bbc6ca13c",
      "tree": "872ceb12d035484f9f7d1b35ad61971dbfe75a75",
      "parents": [
        "3bb4871c4407c9029be9741ec40f261f1ead377d"
      ],
      "author": {
        "name": "Brian Gan",
        "email": "brgan@google.com",
        "time": "Tue Jul 07 21:19:56 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Tue Jul 07 14:55:56 2026 -0700"
      },
      "message": "color: Replace anonymous sentinel with named class\n\nReplace the bare `object()` sentinel used for `_CHECK_CONSOLE` with an\ninstance of a dedicated `_CheckConsoleSentinel` class. This gives the\nsentinel a meaningful repr and type, making it easier to identify in\ndebugging output and type checks compared to an opaque `\u003cobject\u003e`.\n\nChange-Id: I916521d47ba13207e29a2412e00f3576aff8afff\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/605021\nCommit-Queue: Brian Gan \u003cbrgan@google.com\u003e\nTested-by: Brian Gan \u003cbrgan@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "3bb4871c4407c9029be9741ec40f261f1ead377d",
      "tree": "bb7b0ce7d12620a22c66ed74a68bea1e667a5180",
      "parents": [
        "35bbf701d04de5c6a71937279bc3d16f6ce36808"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Jul 07 18:53:21 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Tue Jul 07 13:40:52 2026 -0700"
      },
      "message": "rebase: Resolve revisionExpr to tracking branch for --onto-manifest\n\nWhen running `repo rebase -m` (`--onto-manifest`), the command uses the\nraw `revisionExpr` from the manifest (e.g. `main`) directly as the\n`--onto` target. This can fail or behave incorrectly if it should\nreference the local tracking branch (e.g. `refs/remotes/\u003cremote\u003e/main`).\n\nResolve `project.revisionExpr` to its local tracking branch using\n`project.GetRemote().ToLocal()`. Fall back to using the raw\n`revisionExpr` value if the resolution fails (raising a `GitError`).\n\nBug: 532028666\nChange-Id: I4c1bca1374a5842688be227f6aa2afffcdad5397\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/604941\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "35bbf701d04de5c6a71937279bc3d16f6ce36808",
      "tree": "dd85fb9c0d2fcaa8b5685fe8e775ca1cf6ab17a3",
      "parents": [
        "881af15cdc4a72894adc9e6b9504e6ca6d4d7c8e"
      ],
      "author": {
        "name": "Brian Gan",
        "email": "brgan@google.com",
        "time": "Tue Jun 30 21:38:51 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed Jul 01 15:59:45 2026 -0700"
      },
      "message": "color: Treat \"true\" and \"yes\" as \"auto\", not \"always\"\n\nPer the git documentation for color.ui [1], setting color.ui to \"true\"\n(or \"yes\") should behave identically to \"auto\", enabling color only\nwhen output is written to a terminal or an active pager. Previously,\nrepo was equating \"true\" and \"yes\" with \"always\", which caused color\nescape codes to be emitted unconditionally, even when output was piped\nor redirected.\n\nReplace the duplicated string-matching logic in SetDefaultColoring and\nColoring.__init__ with a single CONFIG_TO_COLOR_SETTING dict that maps\nall git color config values to their behavior. This makes the mapping\neasy to verify against the git docs and impossible to get out of sync\nbetween the two call sites.\n\nAdded tests for SetDefaultColoring and Coloring.__init__ covering\nall color mode values (auto, true, yes, always, never, no, false),\ncase insensitivity, TTY vs pipe behavior, active pager detection,\nand unrecognised input.\n\n[1] https://git-scm.com/docs/git-config#Documentation/git-config.txt-colorui\n\nBug: 295841573\nChange-Id: I8a04b9c7e4154de37ed7518c010233039e0afdc9\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/602981\nTested-by: Brian Gan \u003cbrgan@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Brian Gan \u003cbrgan@google.com\u003e\n"
    },
    {
      "commit": "881af15cdc4a72894adc9e6b9504e6ca6d4d7c8e",
      "tree": "fcd849fb32ca010487ffc4e32a23f3de1637437b",
      "parents": [
        "fbc9c7919246ea74c295be888db4ae332cced202"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Wed Jul 01 15:39:44 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed Jul 01 15:45:23 2026 -0700"
      },
      "message": "agents: run review agents manually\n\nThe review agents are broken right now, so don\u0027t run them automatically.\nThey should still be runnable on demand.\n\nChange-Id: I22e5ff46f917a49d0c267a0b1e8c63ae2165347d\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/603461\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nCommit-Queue: Brian Gan \u003cbrgan@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nTested-by: Brian Gan \u003cbrgan@google.com\u003e\n"
    },
    {
      "commit": "fbc9c7919246ea74c295be888db4ae332cced202",
      "tree": "16ae236200c38405f54de49ac37d1499be92b70a",
      "parents": [
        "ead4b2d7aa86fde803066f59c1dda94aefe2b9fe"
      ],
      "author": {
        "name": "Brian Gan",
        "email": "brgan@google.com",
        "time": "Tue Jun 30 21:11:54 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Tue Jun 30 15:35:57 2026 -0700"
      },
      "message": "tests: Fix test compatibility with Python 3.14 forkserver\n\nPython 3.14 changed the default multiprocessing start method on Linux\nfrom \"fork\" to \"forkserver\". The test_forall_all_projects_called_once\ntest uses mock.patch.object on Project.GetRevisionId, but class-level\nmock patches do not survive into forkserver worker processes because\nthey start from a clean Python interpreter rather than inheriting the\nparent\u0027s memory.\n\nReplace the mock with setting revisionId directly on each Project\ninstance so GetRevisionId() short-circuits without touching git.\nThis works with any multiprocessing start method since the string\nattribute is part of the Project objects stored in _parallel_context,\nwhich is properly serialized to workers via initargs.\n\nBug: 425319437\nChange-Id: Icd3bbd010921d7652bb2425fad85974df9198367\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/602941\nTested-by: Brian Gan \u003cbrgan@google.com\u003e\nCommit-Queue: Brian Gan \u003cbrgan@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "ead4b2d7aa86fde803066f59c1dda94aefe2b9fe",
      "tree": "7f1f0792f9435263a4e85a7effd97834164de32d",
      "parents": [
        "e7cac4bca6b8e4276a5a64287653b5c56555d6f4"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Mon Jun 15 23:23:04 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Tue Jun 30 13:20:15 2026 -0700"
      },
      "message": "sync: Implement fetchcmd for standard Git layouts\n\nIntroduce support for `repo.fetchcmd` configuration, allowing users to\nspecify a custom command to fetch project data instead of\n`_RemoteFetch`.\n\nWhen `repo.fetchcmd` is specified, `repo` will execute it instead of\n`_RemoteFetch` during the network half of sync. Note that\n`repo.fetchcmd` requires `repo.uselocalgitdirs` to be enabled.\n\nThe command is executed in a subshell with project-context environment\nvariables, including the new `REPO_TREV` (target revision resolved to a\ncommit hash) and `REPO_PROJECT_FETCH_URL`.\n\nAfter execution, `repo` verifies that the target commit is available and\nthat the tracking ref and FETCH_HEAD are correctly updated.\n\nTested with:\n```\n\u003e ~/git-repo/repo init -u https://android-review.googlesource.com/platform/manifest \\\n    --repo-url file:///usr/local/google/home/gavinmak/git-repo \\\n    --groups developers \\\n    --no-repo-verify \\\n    --use-local-gitdirs\n...\n\n\u003e git config --file .repo/manifests.git/config repo.fetchcmd \u0027mkdir -p $REPO_PATH \u0026\u0026 cd $REPO_PATH \u0026\u0026 if [ ! -d .git ]; then git init \u0026\u0026 git remote add aosp $REPO_PROJECT_FETCH_URL; fi \u0026\u0026 git fetch aosp $REPO_TREV \u0026\u0026 git reset --hard $REPO_TREV \u0026\u0026 mkdir -p .git/refs/remotes/aosp \u0026\u0026 echo $REPO_TREV \u003e .git/refs/remotes/aosp/main \u0026\u0026 echo $REPO_TREV \u003e .git/FETCH_HEAD\u0027\n\n\u003e ~/git-repo/repo sync -j32\nwarning: repo is not tracking a remote branch, so it will not receive updates; run `repo init --repo-rev\u003dstable` to fix.\nYou are currently enrolled in Git submodules experiment (go/android-submodules-quickstart).  Use --no-use-superproject to override.\n\nSyncing: 100% (4/4), done in 1m15.686s\nFinalizing sync state...\nrepo sync has finished successfully.\n```\n\nBug: 513329573\nChange-Id: I754d3f3c78e86fdeee1a72115297a75b571bc497\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/583883\nReviewed-by: Becky Siegel \u003cbeckysiegel@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "e7cac4bca6b8e4276a5a64287653b5c56555d6f4",
      "tree": "e8ca4cb8a677489515a3bd914614aae2fb445f55",
      "parents": [
        "91986011b012ca7cf881246976282dd581b88ad3"
      ],
      "author": {
        "name": "Brian Gan",
        "email": "brgan@google.com",
        "time": "Mon Jun 29 20:15:53 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Tue Jun 30 11:13:14 2026 -0700"
      },
      "message": "status: Show ahead/behind info for local branches\n\nWhen viewing `repo status`, it is difficult to distinguish between branches that have active unpushed changes and stale branches that are fully synced. Previously, developers had to run commands like `repo forall -c \"git status\"` to see their ahead/behind counts.\n\nThis change updates Project.PrintWorkTreeStatus to automatically calculate and display the number of commits a branch is ahead and/or behind its upstream tracking branch. We use `git rev-list --left-right --count` to fetch this information natively and efficiently.\n\nIf the branch is completely synced with upstream, no extra text is shown.\n\nAdded tests for ahead-only, behind-only, diverged, no-tracking, and fully-synced branch states.\n\nBug: 319412954\nChange-Id: I23879b2d472c7a7e11d01b565428a84b1b4f09c1\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/602423\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nTested-by: Brian Gan \u003cbrgan@google.com\u003e\nCommit-Queue: Brian Gan \u003cbrgan@google.com\u003e\n"
    },
    {
      "commit": "91986011b012ca7cf881246976282dd581b88ad3",
      "tree": "d4791c5b21e2f667946815dfe43c4dc1fcd5079a",
      "parents": [
        "a27dbcdb7bba1b8a2cc84112fa31c8f9f818604e"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Mon Jun 29 10:42:01 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Tue Jun 30 09:19:35 2026 -0700"
      },
      "message": "info: Parallelize project data gathering for JSON output\n\nhttps://gerrit-review.googlesource.com/c/git-repo/+/581921 parallelized\n`repo info` for text output. This commit does the same for JSON output\nformat.\n\nBenchmarked `repo info --format\u003djson` on an Android workspace with ~3k\nprojects (N\u003d3):\n- Before (sequential): 1m 30s average\n- After (parallelized): 46s average (~2x speedup)\n\nVerified that the JSON output is identical before and after.\n\nBug: 526685287\nChange-Id: If573223aba584f8b932f87d29e34ed565c5c930a\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/601861\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "a27dbcdb7bba1b8a2cc84112fa31c8f9f818604e",
      "tree": "f68592217a0d606d0cdc418efa2d7c825c80df6d",
      "parents": [
        "547dc9985ca6d401284b7ee0018721e8aa3324d3"
      ],
      "author": {
        "name": "Rahul Yadav",
        "email": "yadavrah@google.com",
        "time": "Mon Jun 29 09:27:57 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Tue Jun 30 04:44:38 2026 -0700"
      },
      "message": "git_trace2_event_log: Fix index out of range on empty config values\n\nIn git_trace2_event_log_base.py\u0027s GetDataEventName method, it parses\nvalue to identify if it represents a JSON list. When a config key has an\nempty string value, GetDataEventName evaluates value[0], which raises\nIndexError: string index out of range.\n\nThis change fixes the crash by checking if the value is a string and using\nstartswith/endswith to check for JSON lists instead of direct indexing.\n\nTest: PYTHONPATH\u003d. pytest tests/test_git_trace2_event_log.py\n\nBug: 512518342\nTAG\u003dagy\nCONV\u003dff5d70d7-e5b3-42b3-8f16-23b9e3070754\n\nChange-Id: Ic40a8c6a22df57d0e97f268f6e1bc8a14a5024a4\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/602201\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nTested-by: Rahul Yadav \u003cyadavrah@google.com\u003e\nCommit-Queue: Rahul Yadav \u003cyadavrah@google.com\u003e\n"
    },
    {
      "commit": "547dc9985ca6d401284b7ee0018721e8aa3324d3",
      "tree": "fd82c27f2cb49ffc27c40bb882970e4e539471e0",
      "parents": [
        "88a7e88e54d27f8d6068ba3d86fe61c291ab76a5"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Wed Jun 24 14:24:52 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Jun 29 11:06:23 2026 -0700"
      },
      "message": "repo: Normalize GNUPGHOME path for MSYS GPG on Windows\n\nConvert GNUPGHOME to a POSIX path using cygpath on Windows\nso MSYS GPG can read it correctly.\n\nBug: 510840000\nChange-Id: I7d25564dd6521f6e887ff45548f42984e709ef5e\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/601121\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "88a7e88e54d27f8d6068ba3d86fe61c291ab76a5",
      "tree": "abe7a9ca75e6c42747618301ec4bb371a69393b3",
      "parents": [
        "c21a41c7ccc0350841cb57733f845dd2054bd285"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Mon Jun 22 22:36:20 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Jun 29 10:50:02 2026 -0700"
      },
      "message": "info: Report actual checked-out HEAD revision\n\nWhen `repo info` runs, the reported \"Current revision\" is resolved using\nthe manifest\u0027s target branch tracking ref (e.g. refs/remotes/goog/main).\n\nIntroduce Project.GetHeadRevisionId(), which gets the checked-out HEAD\ncommit in the worktree, and use it in `repo info` with a fallback to the\nold behavior if the project is not checked out.\n\nBug: 526685287\nChange-Id: I72280ce27daa210cada27d722a94e365644f06e0\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/599481\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "c21a41c7ccc0350841cb57733f845dd2054bd285",
      "tree": "588fdb46f7d4015925e513a6b141afacf3a7e953",
      "parents": [
        "6586efe79ab12e59466b67eaf59d19002abdf268"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue Jun 23 22:47:32 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Fri Jun 26 15:40:55 2026 -0700"
      },
      "message": "git_config: Support SHA-256 object IDs\n\nUpdate ID_RE to match both 40-char (SHA-1) and 64-char (SHA-256) IDs as\npart of Git 3.0 support.\n\nBug: 483758905\nChange-Id: Ie5d9a2a5df4c6e7adda7f1d89f1bfb7724846057\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/600341\nReviewed-by: Brian Gan \u003cbrgan@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "6586efe79ab12e59466b67eaf59d19002abdf268",
      "tree": "4fb5ad140585ee2f1e3eac86e8be8387d23d6b8c",
      "parents": [
        "3af9e2f1462a13a3e344b4fd2e6ed6c4f5403f72"
      ],
      "author": {
        "name": "Brian Gan",
        "email": "brgan@google.com",
        "time": "Thu Jun 25 20:48:34 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu Jun 25 16:07:53 2026 -0700"
      },
      "message": "man: disable line wrapping\n\nWhen help2man runs the repo script to generate man pages, the argparse\nmodule relies on the COLUMNS environment variable to wrap help text.\nThis wrapping can cause URLs and descriptions to be awkwardly broken\nacross lines. Setting COLUMNS\u003d\"10000\" prevents argparse from wrapping\nthe output, keeping URLs intact in the generated man pages.\n\nAdditionally, this fixes a broken git documentation URL fragment for\n--partial-clone in the repo script.\n\nBug: 295374161\nChange-Id: I0c79f37fbfe2bebe71ff90585f2e5e1f88ea33cb\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/601482\nTested-by: Brian Gan \u003cbrgan@google.com\u003e\nCommit-Queue: Brian Gan \u003cbrgan@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "3af9e2f1462a13a3e344b4fd2e6ed6c4f5403f72",
      "tree": "86dae645176976811c024fcb2e2a4e5422b3fdf0",
      "parents": [
        "d32b70275c3d1541026aa87d8b1bea55cac215c5"
      ],
      "author": {
        "name": "Sainath Varanasi",
        "email": "varanasisai@google.com",
        "time": "Thu Jun 25 22:09:03 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu Jun 25 15:28:46 2026 -0700"
      },
      "message": "project: fix sync of shallow projects sharing objdir\n\nRepo sync fails when the following conditions are met:\n\n* There are several checkouts of the same project\n  in different paths.\n* The checkouts are using git hashes as revisions\n  (not branches).\n* There is a clone-depth set on these projects.\n* sync-c\u003d\"true\" is set in the manifest.\n* The revision specified in the manifest\n  has moved forward since the first repo init.\n\nThe sync fails because only the first gitdir gets the \"shallow\" file,\nand subsequent dirs can\u0027t be synced.\n\nDo not optimize away the fetch when the conditions above happen.\n\nSimplified the boolean check in Sync_NetworkHalf and _RemoteFetch\nusing has_shallow, renamed loop variable to avoid shadowing.\n\nTest: create a manifest matching conditions above, repo init,\nforward the hash, and repo sync.\nTest: added tests in test_project.py\nBug: 505072873\nOriginally-by: Elvira Khabirova \u003celvira.khabirova@volvocars.com\u003e\n\nChange-Id: I37c533c382e34fc5ddab489c5593b9e5d3875be2\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/601441\nTested-by: Sainath Varanasi \u003cvaranasisai@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Sainath Varanasi \u003cvaranasisai@google.com\u003e\n"
    },
    {
      "commit": "d32b70275c3d1541026aa87d8b1bea55cac215c5",
      "tree": "12216ea44d8921e18d5ce1fabe0da9e059deefc2",
      "parents": [
        "7f585437036e056389fbaa5904ceb926ae73033b"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Mon Jun 22 14:23:06 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed Jun 24 13:31:45 2026 -0700"
      },
      "message": "agents: Add CRAG-generated review agents and skills\n\nWith cl/930783235, this change sets up two AI review agents that run\nautomatically on new changes.\n\nBug: 522929179\nChange-Id: I315a7ec327dd30af842ec890818cf697756fd55c\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/596721\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "7f585437036e056389fbaa5904ceb926ae73033b",
      "tree": "26414d513b1eef503b6a8b7125158e42aee98330",
      "parents": [
        "39c0b6090071c1039faf9dea2be9ca285054e4f6"
      ],
      "author": {
        "name": "Nasser Grainawi",
        "email": "nasser.grainawi@oss.qualcomm.com",
        "time": "Wed Apr 15 10:53:21 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Mon Jun 22 16:19:30 2026 -0700"
      },
      "message": "gitignore: Add AI agent files\n\nAllow contributors to use local AI agent files without polluting the\nrepository with brand-specific files.\n\nFurther AI agent improvements will be done roughly following the same\nframework being used for Chromium [1].\n\n[1] https://chromium.googlesource.com/chromium/src/+/HEAD/agents\n\nChange-Id: I791f318b4f9cad1705f94e05522089809097cc96\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/573601\nTested-by: Nasser Grainawi \u003cnasser.grainawi@oss.qualcomm.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Mike Frysinger \u003cvapier@google.com\u003e\n"
    },
    {
      "commit": "39c0b6090071c1039faf9dea2be9ca285054e4f6",
      "tree": "dc670de4b75cd7517abd1fec65ac91752d568caa",
      "parents": [
        "cd307a6089f136e8f4f0fe85ce0393782cf99af1"
      ],
      "author": {
        "name": "Rahul Yadav",
        "email": "yadavrah@google.com",
        "time": "Mon Jun 08 15:28:23 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu Jun 18 09:48:49 2026 -0700"
      },
      "message": "sync: Support pluggable remote helpers for smart sync manifest server.\n\nIntroduce support for pluggable remote helpers (declared via the\noptional \u0027helper\u0027 attribute in \u003cmanifest-server\u003e) to dynamically resolve\nproxy addresses. Route the XML-RPC manifest server connection through\nthe resolved proxy.\n\nBug: b/517477903\nChange-Id: I3b6b8ea2640bb077521df4b4a9e8a34a8c6ecdad\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/591642\nTested-by: Rahul Yadav \u003cyadavrah@google.com\u003e\nCommit-Queue: Rahul Yadav \u003cyadavrah@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "cd307a6089f136e8f4f0fe85ce0393782cf99af1",
      "tree": "1d81589db855c92f7771a9ed1fc38ac0c1d09d82",
      "parents": [
        "4b462634e0841f47a035167cf7c08ac21abf53a2"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Mon Jun 15 23:22:53 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Tue Jun 16 10:30:47 2026 -0700"
      },
      "message": "project: Add REPO_PROJECT_FETCH_URL environment variable\n\nAdd REPO_PROJECT_FETCH_URL to Project.GetEnvVars(), which resolves to\nthe remote fetch URL of the project. This is useful for exposing the\nURL to custom fetch commands or other external scripts.\n\nBug: 513329573\nChange-Id: Ic2b0a83493934d16bb1152366ee4e1a2c35ea2dc\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/596121\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "4b462634e0841f47a035167cf7c08ac21abf53a2",
      "tree": "2ebf9c378b124d857a0e06fa6916dd726b9982b0",
      "parents": [
        "d9d86fb59533853adfce354860a2c01dfa72f69f"
      ],
      "author": {
        "name": "Josef Malmström",
        "email": "josef.malmstrom@arm.com",
        "time": "Fri Jun 05 10:05:42 2026 +0200"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Tue Jun 16 00:21:27 2026 -0700"
      },
      "message": "sync: do not init sibling submodules in parallel\n\nInitializing a submodule requires locking \u003cparent\u003e/.git/config.\nAs the implementation was currently doing this in parallel for\nsibling submodules, it lead to a race condition causing\nintermittent errors like:\n\nerror: could not lock config file .git/config: File exists\n\nThis commit enforces that sibling submodules are initialized\nsequentially, eliminating the race condition.\n\nChange-Id: I5ffb3de90276ba43e262d0e279a3d34324220b63\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/591241\nTested-by: Josef Malmstrom \u003cJosef.Malmstrom@arm.com\u003e\nCommit-Queue: Josef Malmstrom \u003cJosef.Malmstrom@arm.com\u003e\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "d9d86fb59533853adfce354860a2c01dfa72f69f",
      "tree": "5f9ba70fc0c87f89567cdbba478514e22f3ff60a",
      "parents": [
        "f7a24df00cdde9b1c2d51e5d0b03e8a36d655f76"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue May 26 10:35:57 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu Jun 11 10:39:45 2026 -0700"
      },
      "message": "repo: Bump launcher version to 2.65\n\nhttps://gerrit-review.git.corp.google.com/c/git-repo/+/569001 didn\u0027t\nupdate the repo launcher script version for the newly added\n`--use-local-gitdirs` flag.\n\nBug: 513329573\nBug: 508146070\nChange-Id: I07ad939a40466ed50e439c815608797689fd505f\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/587381\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\n"
    },
    {
      "commit": "f7a24df00cdde9b1c2d51e5d0b03e8a36d655f76",
      "tree": "e98a0ec351d8fc9abacdc9a0156c83cdf524e1e5",
      "parents": [
        "e0bd39c691e365ce1988e1f727ddf8b37637599c"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Thu Jun 04 21:54:33 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Fri Jun 05 09:16:22 2026 -0700"
      },
      "message": "project: handle corrupted projects in DeleteWorktree\n\nCatch GitError from IsDirty() during DeleteWorktree so corrupted\nprojects can be cleanly wiped instead of crashing.\n\nBug: 515415221\nChange-Id: Ic03ae77c30a722f9aa06f2220747251e0aea4ab7\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/591001\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "e0bd39c691e365ce1988e1f727ddf8b37637599c",
      "tree": "7b4deb6ecd6414648a3d83ea6231173a4f042ea7",
      "parents": [
        "c883613e317561579e164a7d92ea4347d502b86d"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue May 26 11:10:44 2026 -0700"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed May 27 12:58:02 2026 -0700"
      },
      "message": "project: Extract project envvar generation to GetEnvVars\n\nMove project environment variable setup from subcmds/forall.py to a\nreusable Project.GetEnvVars() helper method.\n\nBug: 513329573\nChange-Id: I3b4b113aa5a086e5fa5eaf4461c7ce517d928610\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/583881\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\n"
    },
    {
      "commit": "c883613e317561579e164a7d92ea4347d502b86d",
      "tree": "5c6c4a8bc0895791777b1eea4f5eed772ebfee8d",
      "parents": [
        "384c059f9e7c7497a1f003cbe9b50a49260f3f6d"
      ],
      "author": {
        "name": "Xin Li",
        "email": "delphij@google.com",
        "time": "Tue May 26 15:52:48 2026 -0700"
      },
      "committer": {
        "name": "Xin Li",
        "email": "delphij@google.com",
        "time": "Wed May 27 10:36:32 2026 -0700"
      },
      "message": "sync: Skip copyfile/linkfile for unavailable projects\n\nCommit 5534f16 made UpdateCopyLinkfileList to retry _CopyAndLinkFiles\nfor all projects in the manifest to handle directory-to-symlink\ntransistions. However, for partial sync\u0027s (e.g. repo sync \u003cproject\u003e),\nprojects not included in the sync may not have their local directories\npopulated, attempts to perform the operation on unavailable projects\nwould result in dangling symlinks, or errors like:\n\nerror: Cannot copy file \u003csource\u003e to \u003cdestination\u003e\n\nFix this by adding a check inside _CopyAndLinkFiles in project.py to\nso these operations happen only when the project\u0027s worktree exists\nand is a directory.\n\nTAG\u003dagy\nCONV\u003d90f5fca7-2199-4017-8f62-a010b0ab1dbf\n\nChange-Id: I9ae1e8d62d8fd129cb4535e574c38339c87af441\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/587501\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nTested-by: Xin Li \u003cdelphij@google.com\u003e\n"
    },
    {
      "commit": "384c059f9e7c7497a1f003cbe9b50a49260f3f6d",
      "tree": "12f1c2a3a3a1b6b0ebeeb530948d28b5b1c6c42a",
      "parents": [
        "b8531133deb053b333a3e90ce3b91a6f448b034e"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Thu May 14 22:44:02 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Tue May 26 10:29:06 2026 -0700"
      },
      "message": "tests: Deduplicate test setup in test_project.py\n\nBug: 513329573\nChange-Id: Id729c590a69d2e81d4bce2942c65bd0b3ce3a11a\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/583882\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Dan Willemsen \u003cdwillemsen@google.com\u003e\n"
    },
    {
      "commit": "b8531133deb053b333a3e90ce3b91a6f448b034e",
      "tree": "e4ac7ddaaedc1e037018626568b5cad91070ae31",
      "parents": [
        "2d54384a5e59fddd0626ec091cc0ad11511d834e"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Fri Apr 03 01:11:35 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Tue May 26 10:26:25 2026 -0700"
      },
      "message": "init: Add --use-local-gitdirs for standard Git layouts\n\nIntroduce --use-local-gitdirs to bypass repo\u0027s symlink-based layouts in\nfavor of standard local .git directories.\n\nBug: 513329573\nBug: 508146070\nChange-Id: I53d1602e61be0b86964529bcbea3dc801471f9c9\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/569001\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Dan Willemsen \u003cdwillemsen@google.com\u003e\n"
    },
    {
      "commit": "2d54384a5e59fddd0626ec091cc0ad11511d834e",
      "tree": "c0a9d642bb4064a23df2044777b6f81f2c047473",
      "parents": [
        "1b4e7a04be7b49d8c0c5e161d36f209bca4b6498"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Wed Apr 22 00:39:42 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed May 20 12:28:55 2026 -0700"
      },
      "message": "sync: Add --superproject-rev flag to sync to specific revision\n\nAllow syncing the outer manifest to a state defined by a specific\nsuperproject revision. It updates the superproject, reads the manifest\ncommit from .supermanifest, and checks out the outer manifest project\nto that commit.\n\nSubmanifests are then processed normally, allowing them to be updated\nto the revisions specified in the new outer manifest state.\n\nBug: 416589884\nChange-Id: I304c37a2b8794f9b74cb7e5e209a8a93762bdb52\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/576321\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\n"
    },
    {
      "commit": "1b4e7a04be7b49d8c0c5e161d36f209bca4b6498",
      "tree": "e806e49daa47688240c75f6d5fdb20cc97cec509",
      "parents": [
        "a94c9e2b521096ff961da1bc6daf97d74add121c"
      ],
      "author": {
        "name": "Josef Malmström",
        "email": "josef.malmstrom@arm.com",
        "time": "Wed May 06 16:19:52 2026 +0200"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed May 20 06:05:57 2026 -0700"
      },
      "message": "Fix submodules not synced for repeated repo\n\nIf I check out e.g. multiple branches of the same repo in one\nmanifest, only the submodules of one checkout are synced.\n\nFix this by adding the relative path  of the checkout as a key\nto the mapping of derived projects, preventing overwrite.\n\nThe fix was originally proposed here:\nhttps://issues.gerritcodereview.com/issues/40013218\n\nBug: 40013218\nChange-Id: Ia86518ccf2c0af7bd7e4daf8d703a55b7e10ba52\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/581062\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Josef Malmstrom \u003cJosef.Malmstrom@arm.com\u003e\nTested-by: Josef Malmstrom \u003cJosef.Malmstrom@arm.com\u003e\n"
    },
    {
      "commit": "a94c9e2b521096ff961da1bc6daf97d74add121c",
      "tree": "bc17a531062493aee0c12d8bc549a137282f870d",
      "parents": [
        "51021fb209b118e6ff4350016657ce5f020b1bc2"
      ],
      "author": {
        "name": "gurusai-voleti",
        "email": "gvoleti@google.com",
        "time": "Mon Apr 27 08:15:09 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu May 14 21:31:49 2026 -0700"
      },
      "message": "Automated: Migrate gerrit/git-repo from gsutil to gcloud storage\n\nBug: 486536908\nChange-Id: I248b093e189a3784b8959e837a5d66857f1ce0fc\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/577201\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nTested-by: Guru sai rama subbarao Voleti (xWF) \u003cgvoleti@google.com\u003e\nCommit-Queue: Guru sai rama subbarao Voleti (xWF) \u003cgvoleti@google.com\u003e\n"
    },
    {
      "commit": "51021fb209b118e6ff4350016657ce5f020b1bc2",
      "tree": "f33f17dd35fab90bb1f83483efc5e0ab14faede1",
      "parents": [
        "d453273f0638f7090846a9f95e3cae578569a6c7"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue May 12 20:21:14 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu May 14 13:19:55 2026 -0700"
      },
      "message": "abandon/start/info: Make them respect smart sync override\n\nCall TryOverrideManifestWithSmartSync in start, abandon, and info\ncommands.\n\nThis ensures they pick up the pinned revisions from the smart sync\noverride manifest if it exists, rather than falling back to ToT from\nthe default manifest.\n\nBug: 279204331\nChange-Id: I637f054a77773805daf0bf9cf5a712d82a5959b4\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/582503\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "d453273f0638f7090846a9f95e3cae578569a6c7",
      "tree": "80d0d994901c7023b60efaa42dcd1c978917d309",
      "parents": [
        "0129ac1c460381ea42e907901c256561d1d8f353"
      ],
      "author": {
        "name": "Gavin Mak",
        "email": "gavinmak@google.com",
        "time": "Tue May 12 20:21:10 2026 +0000"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu May 14 13:19:26 2026 -0700"
      },
      "message": "command: Move smart sync override logic to Command base class\n\nDeduplicate the logic for loading `smart_sync_override.xml` by\nmoving it from `forall.py` to the `Command` base class. This allows\nother commands to reuse it to respect smart tags.\n\nBug: 279204331\nChange-Id: I6f2f03995266c2a68c3225cacb92b2f580a89178\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/582502\nTested-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Gavin Mak \u003cgavinmak@google.com\u003e\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\n"
    },
    {
      "commit": "0129ac1c460381ea42e907901c256561d1d8f353",
      "tree": "2159ba773b3f22ef4132978cb4172b08c24eb77d",
      "parents": [
        "bf8c59f4a05677e978eb0466a35b8896dce1613d"
      ],
      "author": {
        "name": "Mike Frysinger",
        "email": "vapier@google.com",
        "time": "Thu May 14 09:49:06 2026 -0400"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu May 14 09:03:56 2026 -0700"
      },
      "message": "docs: drop period in headers\n\nWe don\u0027t do this in most places, so standardize the outliers.\n\nChange-Id: I80c1ef16c5fa7355dcb7797bc8e56852b22c24d5\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/583641\nTested-by: Mike Frysinger \u003cvapier@google.com\u003e\nCommit-Queue: Mike Frysinger \u003cvapier@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\n"
    },
    {
      "commit": "bf8c59f4a05677e978eb0466a35b8896dce1613d",
      "tree": "2eb6004a8c8e025f2079f236631b4b48d2a1fa15",
      "parents": [
        "003f0407fc5a301105a457f5ddc9773f1224cc97"
      ],
      "author": {
        "name": "Mike Frysinger",
        "email": "vapier@google.com",
        "time": "Wed May 13 00:33:49 2026 -0400"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Thu May 14 09:03:52 2026 -0700"
      },
      "message": "run_tests: help2man: update to latest release\n\nChange-Id: I30e4a6452ac5504b782fe545a59ca1f58ac70385\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/583621\nTested-by: Mike Frysinger \u003cvapier@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Mike Frysinger \u003cvapier@google.com\u003e\n"
    },
    {
      "commit": "003f0407fc5a301105a457f5ddc9773f1224cc97",
      "tree": "34b3f9612ab576b02293a67f6b1893587723324e",
      "parents": [
        "1db50e49fb7f99a61f7a3ceee3e1f6289208e249"
      ],
      "author": {
        "name": "Josef Malmström",
        "email": "josef.malmstrom@arm.com",
        "time": "Mon May 04 14:11:46 2026 +0200"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed May 13 00:00:27 2026 -0700"
      },
      "message": "Fix missing `None` check in Remote.Save\n\nThis code was causing an exception in cases where `pushUrl` was set\nbut `projectname` was not.\n\nThis can happen when `pushUrl` is set for the manifest repo which does\nnot have a `projectname`. For example:\n\nrepo init --manifest-url ssh://url.to/my/manifest\n\ncd .repo/manifests\ngit config remote.origin.pushurl ssh://url.to/my/manifest\n\nrepo init --manifest-url ssh://url.to/my/manifest --repo-rev main\n\nThe last `repo init` invocation causes an error.\n\nChange-Id: Ibb68c8446880cfbac22feee595d1fd1b678c7ade\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/579162\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Josef Malmstrom \u003cJosef.Malmstrom@arm.com\u003e\nTested-by: Josef Malmstrom \u003cJosef.Malmstrom@arm.com\u003e\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\n"
    },
    {
      "commit": "1db50e49fb7f99a61f7a3ceee3e1f6289208e249",
      "tree": "5477fb7c061034df31db59a15c2741f5b575817c",
      "parents": [
        "c97a306fe7e9493fc3bed034da5e84bcd5f67a41"
      ],
      "author": {
        "name": "Josef Malmström",
        "email": "josef.malmstrom@arm.com",
        "time": "Mon May 04 14:16:40 2026 +0200"
      },
      "committer": {
        "name": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "email": "gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com",
        "time": "Wed May 13 00:00:11 2026 -0700"
      },
      "message": "Add support for self referencing submodules\n\nWhen working with relative submodule paths, The \"./\" needs special\nhandling similar to \"../\".\n\nSee information on:\nhttps://git-scm.com/docs/git-submodule\nWhich currently states:\n\"\u003crepository\u003e is the URL of the new submodule’s origin repository.\nThis may be either an absolute URL, or (if it begins with ./ or ../),\nthe location relative to the superproject’s default remote\nrepository (Please note that to specify a repository foo.git which is\nlocated right next to a superproject bar.git, you’ll have to use\n../foo.git instead of ./foo.git - as one might expect when following\nthe rules for relative URLs - because the evaluation of relative URLs\nin Git is identical to that of relative directories).\"\n\nThe implementation also was not handling file/directory names\nstarting with \".\" or \"..\". Explicitly look for \"./\" and \"../\"\ninstead.\n\nChange-Id: I8ae68d61fb0cbb1624183b175236e98a36e4afdb\nReviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/579182\nReviewed-by: Mike Frysinger \u003cvapier@google.com\u003e\nReviewed-by: Gavin Mak \u003cgavinmak@google.com\u003e\nCommit-Queue: Josef Malmstrom \u003cJosef.Malmstrom@arm.com\u003e\nTested-by: Josef Malmstrom \u003cJosef.Malmstrom@arm.com\u003e\n"
    }
  ],
  "next": "c97a306fe7e9493fc3bed034da5e84bcd5f67a41"
}
