feat(server): invalidate GitHub cache after local git mutations
Pass the GitHub service into pullCurrentBranch, pushCurrentBranch, createPullRequest, branch setup, and worktree archival, and invalidate the cached PR status / repo view whenever a mutation succeeds. Have mergeToBase return the worktree cwd it actually touched so the session can invalidate the base checkout when the merge lands there.
This commit is contained in:
@@ -571,6 +571,36 @@ const x = 1;
|
||||
expect(currentBranch).toBe("feature");
|
||||
});
|
||||
|
||||
it("reports the base worktree cwd when merge-to-base mutates a separate checkout", async () => {
|
||||
execSync("git checkout -b develop", { cwd: repoDir });
|
||||
writeFileSync(join(repoDir, "develop.txt"), "develop\n");
|
||||
execSync("git add develop.txt", { cwd: repoDir });
|
||||
execSync("git -c commit.gpgsign=false commit -m 'develop commit'", { cwd: repoDir });
|
||||
execSync("git checkout main", { cwd: repoDir });
|
||||
|
||||
const baseWorktreePath = join(tempDir, "base-worktree");
|
||||
execSync(`git worktree add ${baseWorktreePath} develop`, { cwd: repoDir });
|
||||
|
||||
const featureWorktree = await createLegacyWorktreeForTest({
|
||||
branchName: "feature",
|
||||
cwd: repoDir,
|
||||
baseBranch: "develop",
|
||||
worktreeSlug: "feature-worktree",
|
||||
paseoHome,
|
||||
});
|
||||
|
||||
writeFileSync(join(featureWorktree.worktreePath, "feature.txt"), "feature\n");
|
||||
execSync("git add feature.txt", { cwd: featureWorktree.worktreePath });
|
||||
execSync("git -c commit.gpgsign=false commit -m 'feature commit'", {
|
||||
cwd: featureWorktree.worktreePath,
|
||||
});
|
||||
|
||||
const mutatedCwd = await mergeToBase(featureWorktree.worktreePath, {}, { paseoHome });
|
||||
|
||||
expect(mutatedCwd).toBe(baseWorktreePath);
|
||||
expect(mutatedCwd).not.toBe(featureWorktree.worktreePath);
|
||||
});
|
||||
|
||||
it("merges from the most-ahead base ref (origin/main when it is ahead)", async () => {
|
||||
const remoteDir = join(tempDir, "remote.git");
|
||||
execSync(`git init --bare -b main ${remoteDir}`);
|
||||
@@ -669,6 +699,23 @@ const x = 1;
|
||||
expect(readFileSync(join(repoDir, "pulled.txt"), "utf8")).toBe("remote\n");
|
||||
});
|
||||
|
||||
it("invalidates GitHub cache after successful local git mutation paths", async () => {
|
||||
const remoteDir = join(tempDir, "remote.git");
|
||||
execSync(`git init --bare -b main ${remoteDir}`);
|
||||
execSync(`git remote add origin ${remoteDir}`, { cwd: repoDir });
|
||||
execSync("git push -u origin main", { cwd: repoDir });
|
||||
|
||||
const invalidatedCwds: string[] = [];
|
||||
const github = createGitHubServiceForStatus(null);
|
||||
github.invalidate = ({ cwd }) => {
|
||||
invalidatedCwds.push(cwd);
|
||||
};
|
||||
|
||||
await pullCurrentBranch(repoDir, github);
|
||||
|
||||
expect(invalidatedCwds).toEqual([repoDir]);
|
||||
});
|
||||
|
||||
it("aborts pull on merge conflicts and leaves no merge in progress", async () => {
|
||||
const remoteDir = join(tempDir, "remote.git");
|
||||
execSync(`git init --bare -b main ${remoteDir}`);
|
||||
|
||||
@@ -1573,7 +1573,7 @@ export async function mergeToBase(
|
||||
cwd: string,
|
||||
options: MergeToBaseOptions = {},
|
||||
context?: CheckoutContext,
|
||||
): Promise<void> {
|
||||
): Promise<string> {
|
||||
await requireGitRepo(cwd);
|
||||
const currentBranch = await getCurrentBranch(cwd);
|
||||
const configured = await getConfiguredBaseRefForCwd(cwd, context);
|
||||
@@ -1589,11 +1589,11 @@ export async function mergeToBase(
|
||||
}
|
||||
let normalizedBaseRef = baseRef;
|
||||
normalizedBaseRef = normalizeLocalBranchRefName(normalizedBaseRef);
|
||||
const currentWorktreeRoot = (await getWorktreeRoot(cwd)) ?? cwd;
|
||||
if (normalizedBaseRef === currentBranch) {
|
||||
return;
|
||||
return currentWorktreeRoot;
|
||||
}
|
||||
|
||||
const currentWorktreeRoot = (await getWorktreeRoot(cwd)) ?? cwd;
|
||||
const baseWorktree = await getWorktreePathForBranch(cwd, normalizedBaseRef);
|
||||
const operationCwd = baseWorktree ?? currentWorktreeRoot;
|
||||
const isSameCheckout = resolve(operationCwd) === resolve(currentWorktreeRoot);
|
||||
@@ -1681,6 +1681,7 @@ export async function mergeToBase(
|
||||
}
|
||||
}
|
||||
}
|
||||
return operationCwd;
|
||||
}
|
||||
|
||||
export async function mergeFromBase(
|
||||
@@ -1776,7 +1777,7 @@ export async function mergeFromBase(
|
||||
}
|
||||
}
|
||||
|
||||
export async function pullCurrentBranch(cwd: string): Promise<void> {
|
||||
export async function pullCurrentBranch(cwd: string, github?: GitHubService): Promise<void> {
|
||||
await requireGitRepo(cwd);
|
||||
const currentBranch = await getCurrentBranch(cwd);
|
||||
if (!currentBranch || currentBranch === "HEAD") {
|
||||
@@ -1788,13 +1789,14 @@ export async function pullCurrentBranch(cwd: string): Promise<void> {
|
||||
}
|
||||
try {
|
||||
await runGitCommand(["pull"], { cwd, timeout: 120_000 });
|
||||
github?.invalidate({ cwd });
|
||||
} catch (error) {
|
||||
await abortGitPullConflictState(cwd);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function pushCurrentBranch(cwd: string): Promise<void> {
|
||||
export async function pushCurrentBranch(cwd: string, github?: GitHubService): Promise<void> {
|
||||
await requireGitRepo(cwd);
|
||||
const currentBranch = await getCurrentBranch(cwd);
|
||||
if (!currentBranch || currentBranch === "HEAD") {
|
||||
@@ -1805,6 +1807,7 @@ export async function pushCurrentBranch(cwd: string): Promise<void> {
|
||||
throw new Error("Remote 'origin' is not configured.");
|
||||
}
|
||||
await runGitCommand(["push", "-u", "origin", currentBranch], { cwd, timeout: 120_000 });
|
||||
github?.invalidate({ cwd });
|
||||
}
|
||||
|
||||
export interface CreatePullRequestOptions {
|
||||
@@ -1869,7 +1872,7 @@ export async function createPullRequest(
|
||||
|
||||
await runGitCommand(["push", "-u", "origin", head], { cwd, timeout: 120_000 });
|
||||
|
||||
return github.createPullRequest({
|
||||
const result = await github.createPullRequest({
|
||||
cwd,
|
||||
repo,
|
||||
title: options.title,
|
||||
@@ -1877,6 +1880,8 @@ export async function createPullRequest(
|
||||
head,
|
||||
base: normalizedBase,
|
||||
});
|
||||
github.invalidate({ cwd });
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function getPullRequestStatus(
|
||||
|
||||
Reference in New Issue
Block a user