Skip to content

fix(repo-walker): overwrite moved tags on pull - #5

Merged
twistedmelonman merged 1 commit into
mainfrom
claude/fix-tag-clobber-pull
Oct 15, 2026
Merged

twistedmelonman merged 1 commit into
mainfrom
claude/fix-tag-clobber-pull

Conversation

@twistedmelonman

Copy link
Copy Markdown
Member

Summary

my-repos failed to pull any repo whose upstream had moved a tag. github-workflows moves its floating v3-style tags on every release, so it hit this each time.

The cause is fetch.pruneTags = true in the global git config. That setting adds a non-forced refs/tags/*:refs/tags/* refspec to every fetch, and git refuses to move an existing tag through a non-forced refspec: ! [rejected] v3 -> v3 (would clobber existing tag). Without pruneTags, tag auto-follow never touches a tag that already exists, which is why the plain case looks fine.

The walker now runs git pull --ff-only --force. The --force reaches the fetch, so the local tag is overwritten (t [tag update] v3 -> v3). --ff-only still decides what happens to the branch, so a diverged or force-pushed branch is still refused.

This is the only pull/fetch site in lib/repo-walker.sh.

Tests

Two new walk tests in tests/repo-walker.bats. Each builds a local bare upstream and sets fetch.pruneTags on the walked clone so the result doesn't depend on whoever runs it:

  • a moved tag: the walk succeeds and the local tag and HEAD match upstream
  • a diverged branch plus a moved tag: the pull still fails, the reason is not the tag, and HEAD stays put

Both fail without the fix. All 85 tests in the file pass with it, and they also pass with GIT_CONFIG_GLOBAL=/dev/null.

Closes smartwatermelon/github-workflows#189

With fetch.pruneTags set, every fetch carries a non-forced
refs/tags/*:refs/tags/* refspec. When upstream re-points a tag, as
github-workflows does with its floating v3-style tags, the fetch
rejects it as "would clobber existing tag" and the whole pull fails,
so my-repos reports the repo as failed and leaves it behind.

Pass --force to the pull so the fetch may overwrite the local tag.
--ff-only still guards the branch: a diverged or rewritten branch is
still refused and left where it was.

Two walk tests cover it: one moves a tag upstream and checks the walk
pulls and updates the tag, the other diverges the branch and checks
the pull still fails for that reason and not the tag. Both fail
without the fix.

Closes smartwatermelon/github-workflows#189
@twistedmelonman
twistedmelonman merged commit b99bd5a into main Oct 15, 2026
3 checks passed
@twistedmelonman
twistedmelonman deleted the claude/fix-tag-clobber-pull branch October 15, 2026 21:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

don't break git-pull on tag-clobber-overwrite

1 participant