OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-sync commits / 06d2b0b

pull: force-update refs on fetch (+refs/*:refs/*)
Without the leading '+' on the refspec, git fetch rejects non- fast-forward ref updates — which is exactly what happens after a history rewrite on the publisher (e.g. `git filter-repo --path node_modules` to strip bloat). The mirror gets the new pack but can't update its refs, so it stays stuck on old SHAs forever. With '+', refs force-update. Old objects become unreachable and are reclaimed by the next gc. No manual rm -rf recovery needed on mirror machines. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
06d2b0b824b22b0144514a32fe95371202f20876
by plankatron <fleeky@gmail.com> · 2026-04-21T20:37:44.000Z

Changed files (1) +7 -1

index.js +7 -1
……@@ -414,8 +414,14 @@ module.exports = class HyperSync extends ReadyResource {
414414
415415 _gitFetch (repoPath, fetchUrl) {
416416 return new Promise((resolve, reject) => {
417 // '+refs/*:refs/*' — leading '+' means force-update. Lets us
418 // recover when the remote rewrote history (e.g. filter-repo
419 // strip of node_modules). Without it, git fetch rejects
420 // non-fast-forward refs and the mirror stays stuck on old
421 // SHAs forever. Old objects become unreachable on the next
422 // fetch and get reclaimed by the next gc.
417423 const proc = spawn('git', [
418 '-C', repoPath, 'fetch', fetchUrl, 'refs/*:refs/*', '--no-tags'
424 '-C', repoPath, 'fetch', fetchUrl, '+refs/*:refs/*', '--no-tags'
419425 ], { stdio: ['ignore', 'pipe', 'pipe'] });
420426
421427 const errChunks = [];