Skip to content

Fetch tags with a forced refspec #464

Description

@blooop

Work

Fetch tags with a forced refspec, so the bare's tags are prunable and a moved tag stops wedging the fetch.

One word, measured on #453, and it fixes a live production bug as well as a straggler. In Git::fetch_all (rust/devlaunch-core/src/clients/git.rs:612-626), replace --tags with an explicit +refs/tags/*:refs/tags/*.

--tags is a non-forced refs/tags/*:refs/tags/*, and git fetch --prune prunes per refspec. Two consequences, both measured:

  • Tags are never pruned. refs/tags is monotone in every tag the remote has ever advertised, and those refs pin objects. A 20,971,520 B blob reachable only from an upstream-deleted tag survived git gc --prune=now at 0 B reclaimed; with the forced refspec, the tag went and 20,975,616 B came back, taking the probe repository from 21,094,400 B to 118,784 B.
  • A tag force-moved upstream wedges the fetch permanently. ! [rejected] moving -> moving (would clobber existing tag), exit 1, repeatably, which RepoManager::fetch_repo maps to FetchRepoError::Refused. So freshness fetches stay broken for that repository until a human deletes the local tag by hand. With the forced refspec it is t [tag update], exit 0.

A test per effect: a tag deleted upstream is pruned locally, a tag force-moved upstream updates instead of failing, and the fetch's argv is pinned so the refspec cannot silently regress to --tags.

One principle-1 call to make explicitly rather than by implication, and to state in the resolution: pruning a tag deletes a ref. The reading that licenses it is that a tag in the bare is a copy of an upstream ref holding no unique work, which is the same argument that already licenses pruning heads. If that reading is accepted, say so; if not, this becomes a flagged path rather than automatic.

Also in scope because #453 found it in the same place: --prune removes refs/heads/main when main disappears upstream, leaving the bare's HEAD symref dangling, which Git::symbolic_ref reads for default-branch detection. Either handle it or record it as a known consequence with the symptom named.

Activity

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

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions