Skip to content

Commit 4396e92

Browse files
critesjoshclaude
andcommitted
fix: check remote for newer incremental tags before skipping re-clone
needsReclone now queries ls-remote to compare the local incremental tag against the latest upstream variant, so a checkout at -0 will re-clone when -2 is published. Falls back gracefully if the remote is unreachable. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 7783c45 commit 4396e92

2 files changed

Lines changed: 52 additions & 4 deletions

File tree

src/utils/git.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -373,11 +373,16 @@ export async function needsReclone(config: RepoConfig): Promise<boolean> {
373373
if (currentTag === null) return true;
374374
if (currentTag === config.tag || currentTag === alternateTagName(config.tag)) return false;
375375
// For incremental tags (e.g., "4.2.0-rc.1-2"), check if the current tag
376-
// is a versioned variant of the requested tag
376+
// is a versioned variant and whether a newer one exists upstream
377377
if (config.matchLatestIncrementalTag) {
378378
const bare = config.tag.startsWith("v") ? config.tag.slice(1) : config.tag;
379379
const currentBare = currentTag.startsWith("v") ? currentTag.slice(1) : currentTag;
380-
if (currentBare.startsWith(bare + "-")) return false;
380+
if (currentBare.startsWith(bare + "-")) {
381+
const latest = await findLatestIncrementalTag(config.url, config.tag);
382+
if (!latest) return false; // can't reach remote, assume current is fine
383+
const latestBare = latest.startsWith("v") ? latest.slice(1) : latest;
384+
return currentBare !== latestBare;
385+
}
381386
}
382387
return true;
383388
}

tests/utils/git.test.ts

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -606,18 +606,61 @@ describe("needsReclone", () => {
606606
expect(result).toBe(false);
607607
});
608608

609-
it("returns false when current tag is an incremental variant and matchLatestIncrementalTag is set", async () => {
609+
it("returns false when at latest incremental tag and matchLatestIncrementalTag is set", async () => {
610610
mockExistsSync.mockReturnValue(true);
611611
// Repo is checked out at "4.2.0-aztecnr-rc.2-2" but config requests "v4.2.0-aztecnr-rc.2"
612612
mockGitInstance.raw.mockResolvedValue("4.2.0-aztecnr-rc.2-2\n");
613+
// ls-remote confirms -2 is the latest
614+
mockGitInstance.listRemote.mockResolvedValueOnce(
615+
"abc123\trefs/tags/4.2.0-aztecnr-rc.2-0\n" +
616+
"def456\trefs/tags/4.2.0-aztecnr-rc.2-1\n" +
617+
"ghi789\trefs/tags/4.2.0-aztecnr-rc.2-2\n"
618+
);
613619

614620
const result = await needsReclone({
615621
name: "test",
616-
url: "test",
622+
url: "https://github.com/test/test",
623+
tag: "v4.2.0-aztecnr-rc.2",
624+
matchLatestIncrementalTag: true,
625+
description: "test",
626+
});
627+
expect(result).toBe(false);
628+
});
629+
630+
it("returns true when a newer incremental tag exists upstream", async () => {
631+
mockExistsSync.mockReturnValue(true);
632+
// Repo is checked out at "-0" but "-2" exists upstream
633+
mockGitInstance.raw.mockResolvedValue("4.2.0-aztecnr-rc.2-0\n");
634+
mockGitInstance.listRemote.mockResolvedValueOnce(
635+
"abc123\trefs/tags/4.2.0-aztecnr-rc.2-0\n" +
636+
"def456\trefs/tags/4.2.0-aztecnr-rc.2-1\n" +
637+
"ghi789\trefs/tags/4.2.0-aztecnr-rc.2-2\n"
638+
);
639+
640+
const result = await needsReclone({
641+
name: "test",
642+
url: "https://github.com/test/test",
643+
tag: "v4.2.0-aztecnr-rc.2",
644+
matchLatestIncrementalTag: true,
645+
description: "test",
646+
});
647+
expect(result).toBe(true);
648+
});
649+
650+
it("returns false when remote check fails for incremental tag", async () => {
651+
mockExistsSync.mockReturnValue(true);
652+
mockGitInstance.raw.mockResolvedValue("4.2.0-aztecnr-rc.2-0\n");
653+
// ls-remote fails (network error)
654+
mockGitInstance.listRemote.mockRejectedValue(new Error("network error"));
655+
656+
const result = await needsReclone({
657+
name: "test",
658+
url: "https://github.com/test/test",
617659
tag: "v4.2.0-aztecnr-rc.2",
618660
matchLatestIncrementalTag: true,
619661
description: "test",
620662
});
663+
// Can't reach remote, assume current is fine
621664
expect(result).toBe(false);
622665
});
623666

0 commit comments

Comments
 (0)