Default new worktrees to the upstream branch (#2848)
* fix(workspaces): default new worktrees to upstream refs Use the daemon-resolved upstream as the untouched starting ref so unpushed local commits do not leak into new workspaces. Preserve exact base identity for fork remotes while keeping local-first behavior across version drift. * fix(workspaces): preserve exact base refs in git actions Resolve accepted display aliases back to the stored ref before comparisons and updates. Fail closed when a non-origin remote base has no explicit mutable merge target. * fix(workspaces): reject conflicting qualified base refs Display aliases remain accepted for compatibility, but a qualified ref carries remote identity and must not be canonicalized to a different stored upstream. * test(server): make upstream fixtures portable Keep the checkout-status fixture aligned with the optional upstream field, and select main explicitly when cloning a bare test remote whose default HEAD varies by platform. * fix(workspaces): preserve exact upstream refs Qualified remote refs now fail closed when pruned instead of switching lineage. Metadata accepts Git-valid upstream names rather than applying a narrower character whitelist. * fix(workspaces): preserve qualified local base refs Local tracking branches are exact upstream identities too. Keep heuristics only for legacy unqualified metadata so origin cannot replace a stored refs/heads base.
This commit is contained in:
@@ -348,6 +348,23 @@ export async function searchAndSelectBranchInPicker(page: Page, name: string): P
|
||||
await selectBranchInPicker(page, name);
|
||||
}
|
||||
|
||||
// Ref picker rows are named for a user: "main, origin branch" is the upstream copy and
|
||||
// "main, local branch, 2 commits ahead of origin main" is the local one.
|
||||
export function startingRefRow(page: Page, accessibleName: string) {
|
||||
return page.getByRole("button", { name: accessibleName, exact: true });
|
||||
}
|
||||
|
||||
export async function expectStartingRefRows(page: Page, accessibleNames: string[]): Promise<void> {
|
||||
for (const name of accessibleNames) {
|
||||
await expect(startingRefRow(page, name)).toBeVisible({ timeout: 30_000 });
|
||||
}
|
||||
}
|
||||
|
||||
export async function captureStartingRefPicker(page: Page, screenshotPath: string): Promise<void> {
|
||||
await expect(page.getByTestId("combobox-desktop-container")).toBeVisible({ timeout: 30_000 });
|
||||
await page.getByTestId("combobox-desktop-container").screenshot({ path: screenshotPath });
|
||||
}
|
||||
|
||||
export async function selectGitHubPrInPicker(page: Page, number: number): Promise<void> {
|
||||
const prRow = page.getByTestId(`new-workspace-ref-picker-pr-${number}`);
|
||||
await expect(prRow).toBeVisible({ timeout: 30_000 });
|
||||
|
||||
Reference in New Issue
Block a user