<feed xmlns='http://www.w3.org/2005/Atom'>
<title>tools/git-repo.git/project.py, branch v2.68</title>
<subtitle>Mirror of gerrit.googlesource.com/git-repo</subtitle>
<id>https://git.enea.com/cgit/tools/git-repo.git/atom?h=v2.68</id>
<link rel='self' href='https://git.enea.com/cgit/tools/git-repo.git/atom?h=v2.68'/>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/tools/git-repo.git/'/>
<updated>2026-09-21T20:40:01+00:00</updated>
<entry>
<title>project: avoid unnecessary sync revision enumeration</title>
<updated>2026-09-21T20:40:01+00:00</updated>
<author>
<name>Gavin Mak</name>
<email>gavinmak@google.com</email>
</author>
<published>2026-08-25T15:57:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/tools/git-repo.git/commit/?id=f6f5946422097f2559cf3bc39a69d5fddc838ab8'/>
<id>urn:sha1:f6f5946422097f2559cf3bc39a69d5fddc838ab8</id>
<content type='text'>
Skip the detached-history walk when its count will not be printed, ask
rev-list --count for upstream gain, and cap the published-but-unmerged
existence probe at one commit. These preserve the decisions while
reducing traversal and output work.

Bug: 553599402
Change-Id: I30f769c9aa5269428ece15ffcb45c50993d7c4b8
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/634004
Commit-Queue: Gavin Mak &lt;gavinmak@google.com&gt;
Tested-by: Gavin Mak &lt;gavinmak@google.com&gt;
Reviewed-by: Brian Gan &lt;brgan@google.com&gt;
</content>
</entry>
<entry>
<title>project: make fast-forward merges explicit</title>
<updated>2026-09-21T20:39:56+00:00</updated>
<author>
<name>Gavin Mak</name>
<email>gavinmak@google.com</email>
</author>
<published>2026-08-25T15:58:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/tools/git-repo.git/commit/?id=6321b26685ff9bdf5858e574dc4967761990ce5b'/>
<id>urn:sha1:6321b26685ff9bdf5858e574dc4967761990ce5b</id>
<content type='text'>
Every caller expects _FastForward to reject a merge commit. Always pass
--ff-only and remove the optional parameter so a violated ancestry
assumption fails instead of silently creating a merge.

Bug: 553599402
Change-Id: I04690b5ca675cb7d3062df08d5e20cd82f5b9e82
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/634003
Tested-by: Gavin Mak &lt;gavinmak@google.com&gt;
Reviewed-by: Brian Gan &lt;brgan@google.com&gt;
Commit-Queue: Gavin Mak &lt;gavinmak@google.com&gt;
</content>
</entry>
<entry>
<title>project: fold normal stash detection into status</title>
<updated>2026-09-21T20:39:51+00:00</updated>
<author>
<name>Gavin Mak</name>
<email>gavinmak@google.com</email>
</author>
<published>2026-08-25T16:01:50+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/tools/git-repo.git/commit/?id=7bffc72b5bf6bc8b6065ef6712e589457a3f7f20'/>
<id>urn:sha1:7bffc72b5bf6bc8b6065ef6712e589457a3f7f20</id>
<content type='text'>
When Git 2.35 or newer supplies a stash header, use the same status
snapshot for stateless dirty and stash checks. Retain rev-parse for
earlier clients or when the status snapshot is unavailable.

Bug: 543851900
Bug: 553599402
Change-Id: I6e310459d9c1a3ba7978f7907ae6b7a9bc611749
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/632146
Tested-by: Gavin Mak &lt;gavinmak@google.com&gt;
Commit-Queue: Gavin Mak &lt;gavinmak@google.com&gt;
Reviewed-by: Brian Gan &lt;brgan@google.com&gt;
</content>
</entry>
<entry>
<title>project: render worktree status from one snapshot</title>
<updated>2026-09-21T20:39:16+00:00</updated>
<author>
<name>Gavin Mak</name>
<email>gavinmak@google.com</email>
</author>
<published>2026-08-25T15:47:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/tools/git-repo.git/commit/?id=c9448f986ef952487006e9c2d22989e98655c591'/>
<id>urn:sha1:c9448f986ef952487006e9c2d22989e98655c591</id>
<content type='text'>
Use porcelain-v2 branch and path records to replace the status display
fan-out with one Git process on Git 2.11 and newer. Preserve the legacy
renderer for older clients, force rename and ahead/behind behavior where
supported, and fall back to the old divergence query only when status
cannot supply branch.ab.

Bug: 543851900
Bug: 553599402
Change-Id: Ic760360f4f48ab9320abf69dbbb7310dab4ac649
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/632144
Commit-Queue: Gavin Mak &lt;gavinmak@google.com&gt;
Reviewed-by: Brian Gan &lt;brgan@google.com&gt;
Tested-by: Gavin Mak &lt;gavinmak@google.com&gt;
</content>
</entry>
<entry>
<title>project: use one status snapshot for dirty checks</title>
<updated>2026-09-21T20:37:38+00:00</updated>
<author>
<name>Gavin Mak</name>
<email>gavinmak@google.com</email>
</author>
<published>2026-09-17T22:07:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/tools/git-repo.git/commit/?id=530258d08ebcd61d8b8e96abc3a973f83bbfa81f'/>
<id>urn:sha1:530258d08ebcd61d8b8e96abc3a973f83bbfa81f</id>
<content type='text'>
On Git 2.11 and newer, replace update-index, diff-index, diff-files, and
ls-files fan-out with one porcelain-v2 snapshot for IsDirty,
UncommittedFiles, and HasChanges. Preserve category ordering and
duplicate staged-plus-unstaged paths, and keep the exact legacy path for
older Git or a failed snapshot.

Bug: 543851900
Bug: 553599402
Change-Id: I309e39977e1f1d4ee6115f488d6aabb83ec3d83c
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/632143
Tested-by: Gavin Mak &lt;gavinmak@google.com&gt;
Reviewed-by: Brian Gan &lt;brgan@google.com&gt;
Commit-Queue: Gavin Mak &lt;gavinmak@google.com&gt;
</content>
</entry>
<entry>
<title>project: pass --no-filter and --no-tags in DownloadPatchSet</title>
<updated>2026-09-21T16:19:39+00:00</updated>
<author>
<name>Sam Saccone</name>
<email>samccone@google.com</email>
</author>
<published>2026-09-03T18:31:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/tools/git-repo.git/commit/?id=4c37f588069d3a62b416ffcc25184119cd21e59e'/>
<id>urn:sha1:4c37f588069d3a62b416ffcc25184119cd21e59e</id>
<content type='text'>
In partial clone checkouts (e.g. --filter=blob:none or blob:limit=10k),
DownloadPatchSet previously invoked `git fetch &lt;remote&gt; &lt;ref&gt;` without
explicit filter overrides. Consequently, git fetch applied the
configured partial clone filter from the remote and omitted the blobs
for the incoming change.

When repo download subsequently checks out, cherry-picks, or merges the
downloaded commit, Git discovers that the required blobs are missing
locally and triggers on-demand unadvertised object fetches to the
promisor remote (POST /git-upload-pack with `want &lt;blob_sha&gt;`). On large
repositories, server-side reachability validation for unadvertised
objects can result in expensive graph traversals, proxy/gateway timeouts
(such as HTTP 502 or connection drops), and client fetch failures:
  fatal: expected 'packfile'
  fatal: could not fetch &lt;sha&gt; from promisor remote

Pass --no-filter (when Git &gt;= 2.17.0) and --no-tags when fetching patch
sets in DownloadPatchSet. Because the change ref is an advertised ref
tip, fetching with --no-filter allows the server to generate a complete
packfile containing all required blobs upfront without requiring
unadvertised object reachability checks. All blobs are present in the
local object database prior to checkout or cherry-pick, completely
preventing on-demand promisor queries.

TAG=agy
CONV=bdc489e3-b20b-4ef3-b32e-549dbe21fc6c

Google-Bug-Id: b/532920848
Test: pytest tests/test_project.py
Change-Id: Ic6118e4edeb754f0467e0580fd1d0965a6553153
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/625621
Reviewed-by: Gavin Mak &lt;gavinmak@google.com&gt;
Tested-by: Sam Saccone &lt;samccone@google.com&gt;
Commit-Queue: Sam Saccone &lt;samccone@google.com&gt;
</content>
</entry>
<entry>
<title>project: rename UncommitedFiles to UncommittedFiles</title>
<updated>2026-09-18T00:21:32+00:00</updated>
<author>
<name>Gavin Mak</name>
<email>gavinmak@google.com</email>
</author>
<published>2026-09-17T22:07:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/tools/git-repo.git/commit/?id=c86ddc1628981a96391700c041f8493e145aa4c8'/>
<id>urn:sha1:c86ddc1628981a96391700c041f8493e145aa4c8</id>
<content type='text'>
Fix typo in UncommitedFiles across project.py and HasChanges.

Bug: 553599402
Change-Id: I2b9b606b4c9a47fd998e50cca976545fcd783771
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/632881
Tested-by: Gavin Mak &lt;gavinmak@google.com&gt;
Reviewed-by: Brian Gan &lt;brgan@google.com&gt;
Commit-Queue: Gavin Mak &lt;gavinmak@google.com&gt;
</content>
</entry>
<entry>
<title>sync: implement reprojectcmd for the local half</title>
<updated>2026-09-15T19:53:01+00:00</updated>
<author>
<name>Gavin Mak</name>
<email>gavinmak@google.com</email>
</author>
<published>2026-09-03T22:55:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/tools/git-repo.git/commit/?id=a468ea7752cddd67fa2242ef038ac96f53c35a6a'/>
<id>urn:sha1:a468ea7752cddd67fa2242ef038ac96f53c35a6a</id>
<content type='text'>
Add `repo.reprojectcmd`, the checkout counterpart to `repo.fetchcmd`.
When set, `repo sync` runs this command instead of Git to materialize a
project's index and worktree at the target tree, while `repo` handles
ref updates directly via `git update-ref`.

This replaces Git's tree materialization steps: detaching HEAD,
fast-forwarding, and hard-resetting. Rebasing is not delegated, and the
command is skipped if HEAD is already at the target, if HEAD is ahead of
the target during fast-forward, or for MetaProjects.

The command runs in a subshell with project environment variables (such
as `REPO_TREV`). Before running, `repo` ensures no operation is in
progress and no staged changes exist. Worktree collision detection is
delegated to the command (preserving benign unstaged/untracked edits).
Afterward, `repo` verifies that HEAD was untouched and that the index
matches the target tree.

Like `repo.fetchcmd`, this requires `repo.uselocalgitdirs`. Nested
projects and submodules are unsupported; `repo sync` fails if the
manifest contains any while `repo.reprojectcmd` is enabled.

Verified end-to-end with repo init using local-gitdirs, repo.fetchcmd,
and repo.reprojectcmd ('git -C $REPO_PATH read-tree -m -u $REPO_TREV'):
  * Verified detached HEAD checkout and correct reflog generation across
    projects.
  * Verified benign unstaged edits and untracked files survive checkout.
  * Verified conflicting untracked files fail with exit 128 without
    clobbering worktree.
  * Verified staged changes fail upfront before reprojectcmd is executed.

Bug: 513329573
Change-Id: I964d24d22dccffc05a9b991ad69f3a7e93268c01
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/626281
Tested-by: Gavin Mak &lt;gavinmak@google.com&gt;
Reviewed-by: Brian Gan &lt;brgan@google.com&gt;
Commit-Queue: Gavin Mak &lt;gavinmak@google.com&gt;
</content>
</entry>
<entry>
<title>project: report why refreshing the index failed</title>
<updated>2026-09-14T20:27:19+00:00</updated>
<author>
<name>Brian Gan</name>
<email>brgan@google.com</email>
</author>
<published>2026-09-14T14:14:24+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/tools/git-repo.git/commit/?id=c2c330ba4a92c915f0180457f0d7ee29031bb253'/>
<id>urn:sha1:c2c330ba4a92c915f0180457f0d7ee29031bb253</id>
<content type='text'>
"repo status" aborts the whole tree when one project fails, without
saying why. The three callers that refresh the index stat cache pass -q,
which suppresses git's diagnosis when it cannot create the index lock;
git then exits 128 with both streams empty. A stale lock, a permissions
problem on the gitdir and a full disk all reach that same silent exit,
yet each needs a different remedy.

Route the three identical call sites through one helper that keeps -q
for the refresh itself. When that fails, it repeats the command without
-q to obtain git's diagnosis. The command still fails, which is correct,
but the user is now told why.

Keeping -q on the common path matters: without it git exits 1 whenever
paths hold uncommitted changes, which would report a failure to
telemetry for every modified project, even if we treat it as benign in
the code. The retry accepts that 1, since --unmerged makes git skip
conflicted paths rather than count them, so nothing else yields it.

The similar call in subcmds/sync.py is unchanged: it passes different
flags, without --unmerged, so exit 1 cannot be assumed benign there.

Bug: 560289756
Change-Id: I2e1024c84454f86076081f2d7f155728b1aa35c6
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/630641
Tested-by: Brian Gan &lt;brgan@google.com&gt;
Reviewed-by: Gavin Mak &lt;gavinmak@google.com&gt;
Commit-Queue: Brian Gan &lt;brgan@google.com&gt;
</content>
</entry>
<entry>
<title>project: check upstream ref ancestry for non-shallow clones</title>
<updated>2026-09-03T09:15:23+00:00</updated>
<author>
<name>Rahul Yadav</name>
<email>yadavrah@google.com</email>
</author>
<published>2026-09-01T15:45:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.enea.com/cgit/tools/git-repo.git/commit/?id=d27d6829a84f488b7253ea693dcc429076c33914'/>
<id>urn:sha1:d27d6829a84f488b7253ea693dcc429076c33914</id>
<content type='text'>
In _CheckForImmutableRevision, commit d9cc0a15 restricted upstream ref
validation strictly to superprojects (if use_superproject) to prevent
shallow clones with an upstream attribute from failing ancestry checks
and falling back to full clones.

However, restricting this check exclusively to superprojects broke
non-shallow projects with pinned immutable revisions (such as in Smart
Sync, `repo sync -t &lt;BUILD_ID&gt;`, or pinned manifests): When the target
commit already exists in the local Git object store (for instance,
prefetched into refs/prefetch/ by a background daemon or via shared
object dirs), _CheckForImmutableRevision returned True without verifying
that the local tracking ref (refs/remotes/&lt;remote&gt;/&lt;upstream&gt;) is
present and reaches the revision. As a result, _RemoteFetch skipped
fetching the upstream branch, leaving the local tracking ref stale or
missing. Subsequent `repo start` branches tracking that remote branch
diverged, causing `repo upload` to attempt uploading all intermediate
commits between the stale tracking ref and HEAD.

Restore upstream ancestry validation in _CheckForImmutableRevision for
non-shallow projects when upstream is specified. Also pass the sync
depth into _CheckForImmutableRevision call sites so shallow checkouts
continue to skip upstream verification and avoid triggering un-shallow
fallbacks.

Test: PYTHONPATH=. pytest tests/test_project.py
Change-Id: Ib5bdf41810bb06c8ed053447209ddc2e488f3913
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/624361
Tested-by: Rahul Yadav &lt;yadavrah@google.com&gt;
Commit-Queue: Rahul Yadav &lt;yadavrah@google.com&gt;
Reviewed-by: Gavin Mak &lt;gavinmak@google.com&gt;
</content>
</entry>
</feed>
