fix(worktree): refresh changed discovery metadata
This commit is contained in:
@@ -153,6 +153,18 @@ describe('worktreeMapsEqual', () => {
|
|||||||
expect(worktreeMapsEqual(a, b)).toBe(false);
|
expect(worktreeMapsEqual(a, b)).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('returns false when head state changes without a branch change', () => {
|
||||||
|
const a = new Map([['/repo', [wt('/r/main', '', { headState: 'unborn' })]]]);
|
||||||
|
const b = new Map([['/repo', [wt('/r/main', '', { headState: 'detached' })]]]);
|
||||||
|
expect(worktreeMapsEqual(a, b)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('returns false when discovered display metadata changes', () => {
|
||||||
|
const a = new Map([['/repo', [wt('/r/main', '', { name: 'old', label: 'old' })]]]);
|
||||||
|
const b = new Map([['/repo', [wt('/r/main', '', { name: 'new', label: 'new' })]]]);
|
||||||
|
expect(worktreeMapsEqual(a, b)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
test('returns false when paths differ', () => {
|
test('returns false when paths differ', () => {
|
||||||
const a = new Map([['/repo', [wt('/r/main', 'main')]]]);
|
const a = new Map([['/repo', [wt('/r/main', 'main')]]]);
|
||||||
const b = new Map([['/repo', [wt('/r/other', 'main')]]]);
|
const b = new Map([['/repo', [wt('/r/other', 'main')]]]);
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ const toCreatePayload = (args: {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare two worktree-by-project maps for equality.
|
* Compare two worktree-by-project maps for equality.
|
||||||
* Compares per-element `path` and `branch` (not reference equality)
|
* Compares discovery-owned metadata (not reference equality)
|
||||||
* because readStableProjectWorktrees creates new object instances on
|
* because readStableProjectWorktrees creates new object instances on
|
||||||
* each call, making reference checks always report changed.
|
* each call, making reference checks always report changed.
|
||||||
*
|
*
|
||||||
@@ -246,22 +246,27 @@ const toCreatePayload = (args: {
|
|||||||
* flow through `setStoredWorktreeStatus`, which writes a new Map
|
* flow through `setStoredWorktreeStatus`, which writes a new Map
|
||||||
* reference that the persist subscriber picks up directly.
|
* reference that the persist subscriber picks up directly.
|
||||||
*
|
*
|
||||||
* Generic over `T extends { path: string; branch: string }` so the
|
|
||||||
* helper documents its equality contract at the type level and
|
|
||||||
* stays reusable for any future map-of-arrays shape that has both
|
|
||||||
* fields.
|
|
||||||
*/
|
*/
|
||||||
export const worktreeMapsEqual = <T extends { path: string; branch: string }>(
|
export const worktreeMapsEqual = (
|
||||||
a: Map<string, T[]>,
|
a: Map<string, WorktreeMetadata[]>,
|
||||||
b: Map<string, T[]>,
|
b: Map<string, WorktreeMetadata[]>,
|
||||||
): boolean => {
|
): boolean => {
|
||||||
if (a.size !== b.size) return false;
|
if (a.size !== b.size) return false;
|
||||||
for (const [key, value] of a) {
|
for (const [key, value] of a) {
|
||||||
const existing = b.get(key);
|
const existing = b.get(key);
|
||||||
if (!existing || existing.length !== value.length) return false;
|
if (!existing || existing.length !== value.length) return false;
|
||||||
for (let i = 0; i < value.length; i++) {
|
for (let i = 0; i < value.length; i++) {
|
||||||
if (value[i].path !== existing[i].path) return false;
|
const next = value[i];
|
||||||
if (value[i].branch !== existing[i].branch) return false;
|
const current = existing[i];
|
||||||
|
if (next.path !== current.path
|
||||||
|
|| next.branch !== current.branch
|
||||||
|
|| next.name !== current.name
|
||||||
|
|| next.label !== current.label
|
||||||
|
|| next.projectDirectory !== current.projectDirectory
|
||||||
|
|| next.worktreeRoot !== current.worktreeRoot
|
||||||
|
|| next.headState !== current.headState
|
||||||
|
|| next.worktreeSource !== current.worktreeSource
|
||||||
|
|| next.source !== current.source) return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user