Skip to content

Log().IncludingAllRefs().ExcludingRemoteTrackingRefs() reports commits the remote already has as "exist only here" when git maintenance prefetch is on (refs/prefetch is swept in by --all) #254

Open

Description

@matt-edmondson

Symptom

The README's "Checking for Work That Exists Nowhere Else" query lists commits that came from the remote whenever the repository has refs/prefetch/*. That means every repository registered with git maintenance start or Scalar. Their hourly prefetch task fetches into refs/prefetch/remotes/<remote>/*, a namespace that is deliberately outside refs/remotes. --all includes those refs, and --not --remotes does not exclude them.

Reproduction (git 2.43)

  1. Clone a repository and leave main in sync with origin/main.
  2. From another clone, push a new commit ("remote-new").
  3. In the first clone, run git maintenance run --task=prefetch. This creates refs/prefetch/remotes/origin/main and does not move origin/main.
  4. Run the query:
var atRisk = await repo.Log().IncludingAllRefs().ExcludingRemoteTrackingRefs().ExecuteAsync();
// unpushed: 0ae62ea remote-new   <- authored elsewhere, already on the remote

git status -sb shows ## main...origin/main, so nothing is ahead. The query still flags the commit, and a caller deciding whether a working copy is safe to delete gets a false "has unpushed work". The same mechanism also lets any other non-refs/remotes mirror of remote state through.

Where

  • GitIntegration/Builders/GitLogBuilder.cs L193-218 (permalink) emits --all and then --not --remotes --not.
  • The IncludingAllRefs remarks (L47-62) and the README (L370-396) present this as the check to run before discarding a working copy.

Fix / acceptance criteria

  • Treat refs/prefetch/* as remote evidence. Both of these drop the false positive and keep genuine local-only commits (checked against git 2.43):
    • --not --remotes --glob=refs/prefetch/* --not
    • --exclude=refs/prefetch/* --all (--exclude must come before --all).
  • Add an integration test:
    • a commit reachable only from refs/prefetch/remotes/origin/main is not reported
    • a commit on a local branch or a detached HEAD still is.
  • Update the remarks and the README to say which non-remote namespaces count as remote copies.

Activity

  1. matt-edmondson commented on Oct 18, 2026

    @matt-edmondson
    ContributorAuthor

    Triage

    • Category: Bug
    • Priority: Medium. It is a false positive, so a caller is wrongly told a working copy has unpushed work. That errs on the safe side, but it defeats the README's documented "safe to delete?" check for every repository with git maintenance or Scalar enabled.
    • Area / suggested assignee: GitIntegration/Builders/GitLogBuilder.cs (IncludingAllRefs / ExcludingRemoteTrackingRefs), plus the README section. Owner: @matt-edmondson
    • Duplicates / in progress: not a duplicate. Open PR Close revision operands with -- in Log, RevList, Diff and Patch [patch] #223 (closing revision operands with -- in Log) touches the same builder, so expect a small merge overlap. It does not fix this.
    • Next step: add --glob=refs/prefetch/* to the excluded set (or --exclude=refs/prefetch/* before --all), add the integration test, and document which namespaces count as remote copies.

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions