vde-worktree 0.0.14 → 0.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ja.md CHANGED
@@ -427,9 +427,14 @@ vw completion zsh --install
427
427
 
428
428
  `overall` ポリシー:
429
429
 
430
- - `byPR === true` -> `overall = true`
431
- - `byPR === false` -> `overall = false`
432
- - `byPR === null` -> `byAncestry` にフォールバック
430
+ - `byPR === true` -> `overall = true`(squash/rebase merge を含む)
431
+ - `byAncestry === false` -> `overall = false`
432
+ - `byAncestry === true` の場合は、分岐の証跡があるときだけ merged 扱い
433
+ - `.vde/worktree/state/branches/*.json` の lifecycle 記録
434
+ - lifecycle がない場合の `git reflog` フォールバック
435
+ - 分岐証跡が `baseBranch` に取り込まれていれば `overall = true`
436
+ - `byPR === false` または lifecycle が明示的に未取り込みなら `overall = false`
437
+ - それ以外は `overall = null`
433
438
 
434
439
  `byPR` が `null` になる例:
435
440
 
package/README.md CHANGED
@@ -427,9 +427,14 @@ Each worktree reports:
427
427
 
428
428
  Overall policy:
429
429
 
430
- - `byPR === true` => `overall = true`
431
- - `byPR === false` => `overall = false`
432
- - `byPR === null` => fallback to `byAncestry`
430
+ - `byPR === true` => `overall = true` (includes squash/rebase merges)
431
+ - `byAncestry === false` => `overall = false`
432
+ - when `byAncestry === true`, require divergence evidence before treating as merged
433
+ - lifecycle evidence from `.vde/worktree/state/branches/*.json`
434
+ - reflog fallback (`git reflog`) when lifecycle evidence is missing
435
+ - if divergence evidence is contained in `baseBranch`, `overall = true`
436
+ - `byPR === false` or explicit lifecycle "not merged" evidence => `overall = false`
437
+ - otherwise `overall = null`
433
438
 
434
439
  `byPR` becomes `null` when PR lookup is unavailable (for example: `gh` missing, auth missing, API error, `vde-worktree.enableGh=false`, or `--no-gh`).
435
440
 
package/dist/index.mjs CHANGED
@@ -617,7 +617,8 @@ const hasStateDirectory = async (repoRoot) => {
617
617
  const parseLifecycle = (content) => {
618
618
  try {
619
619
  const parsed = JSON.parse(content);
620
- if (parsed.schemaVersion !== 1 || typeof parsed.branch !== "string" || typeof parsed.worktreeId !== "string" || typeof parsed.baseBranch !== "string" || typeof parsed.createdHead !== "string" || parsed.createdHead.length === 0 || typeof parsed.createdAt !== "string" || typeof parsed.updatedAt !== "string") return {
620
+ const isLastDivergedHeadValid = parsed.lastDivergedHead === null || typeof parsed.lastDivergedHead === "string" && parsed.lastDivergedHead.length > 0;
621
+ if (parsed.schemaVersion !== 2 || typeof parsed.branch !== "string" || typeof parsed.worktreeId !== "string" || typeof parsed.baseBranch !== "string" || typeof parsed.everDiverged !== "boolean" || isLastDivergedHeadValid !== true || typeof parsed.createdAt !== "string" || typeof parsed.updatedAt !== "string") return {
621
622
  valid: false,
622
623
  record: null
623
624
  };
@@ -665,15 +666,17 @@ const readWorktreeMergeLifecycle = async ({ repoRoot, branch }) => {
665
666
  };
666
667
  }
667
668
  };
668
- const upsertWorktreeMergeLifecycle = async ({ repoRoot, branch, baseBranch, createdHead }) => {
669
+ const upsertWorktreeMergeLifecycle = async ({ repoRoot, branch, baseBranch, observedDivergedHead }) => {
670
+ const normalizedObservedHead = typeof observedDivergedHead === "string" && observedDivergedHead.length > 0 ? observedDivergedHead : null;
669
671
  if (await hasStateDirectory(repoRoot) !== true) {
670
672
  const now = (/* @__PURE__ */ new Date()).toISOString();
671
673
  return {
672
- schemaVersion: 1,
674
+ schemaVersion: 2,
673
675
  branch,
674
676
  worktreeId: branchToWorktreeId(branch),
675
677
  baseBranch,
676
- createdHead,
678
+ everDiverged: normalizedObservedHead !== null,
679
+ lastDivergedHead: normalizedObservedHead,
677
680
  createdAt: now,
678
681
  updatedAt: now
679
682
  };
@@ -682,14 +685,17 @@ const upsertWorktreeMergeLifecycle = async ({ repoRoot, branch, baseBranch, crea
682
685
  repoRoot,
683
686
  branch
684
687
  });
685
- if (current.valid && current.record !== null && current.record.baseBranch === baseBranch) return current.record;
688
+ if (current.valid && current.record !== null && current.record.baseBranch === baseBranch && normalizedObservedHead === null) return current.record;
686
689
  const now = (/* @__PURE__ */ new Date()).toISOString();
690
+ const everDiverged = current.record?.everDiverged === true || normalizedObservedHead !== null;
691
+ const lastDivergedHead = normalizedObservedHead ?? current.record?.lastDivergedHead ?? null;
687
692
  const next = {
688
- schemaVersion: 1,
693
+ schemaVersion: 2,
689
694
  branch,
690
695
  worktreeId: branchToWorktreeId(branch),
691
696
  baseBranch,
692
- createdHead: current.record?.createdHead ?? createdHead,
697
+ everDiverged,
698
+ lastDivergedHead,
693
699
  createdAt: current.record?.createdAt ?? now,
694
700
  updatedAt: now
695
701
  };
@@ -699,15 +705,17 @@ const upsertWorktreeMergeLifecycle = async ({ repoRoot, branch, baseBranch, crea
699
705
  });
700
706
  return next;
701
707
  };
702
- const moveWorktreeMergeLifecycle = async ({ repoRoot, fromBranch, toBranch, baseBranch, createdHead }) => {
708
+ const moveWorktreeMergeLifecycle = async ({ repoRoot, fromBranch, toBranch, baseBranch, observedDivergedHead }) => {
709
+ const normalizedObservedHead = typeof observedDivergedHead === "string" && observedDivergedHead.length > 0 ? observedDivergedHead : null;
703
710
  if (await hasStateDirectory(repoRoot) !== true) {
704
711
  const now = (/* @__PURE__ */ new Date()).toISOString();
705
712
  return {
706
- schemaVersion: 1,
713
+ schemaVersion: 2,
707
714
  branch: toBranch,
708
715
  worktreeId: branchToWorktreeId(toBranch),
709
716
  baseBranch,
710
- createdHead,
717
+ everDiverged: normalizedObservedHead !== null,
718
+ lastDivergedHead: normalizedObservedHead,
711
719
  createdAt: now,
712
720
  updatedAt: now
713
721
  };
@@ -718,12 +726,15 @@ const moveWorktreeMergeLifecycle = async ({ repoRoot, fromBranch, toBranch, base
718
726
  });
719
727
  const targetPath = lifecycleFilePath(repoRoot, toBranch);
720
728
  const now = (/* @__PURE__ */ new Date()).toISOString();
729
+ const everDiverged = source.record?.everDiverged === true || normalizedObservedHead !== null;
730
+ const lastDivergedHead = normalizedObservedHead ?? source.record?.lastDivergedHead ?? null;
721
731
  const next = {
722
- schemaVersion: 1,
732
+ schemaVersion: 2,
723
733
  branch: toBranch,
724
734
  worktreeId: branchToWorktreeId(toBranch),
725
735
  baseBranch,
726
- createdHead: source.record?.createdHead ?? createdHead,
736
+ everDiverged,
737
+ lastDivergedHead,
727
738
  createdAt: source.record?.createdAt ?? now,
728
739
  updatedAt: now
729
740
  };
@@ -1049,6 +1060,56 @@ const resolveLockState = async ({ repoRoot, branch }) => {
1049
1060
  };
1050
1061
  }
1051
1062
  };
1063
+ const WORK_REFLOG_MESSAGE_PATTERN = /^(commit(?: \([^)]*\))?|cherry-pick|revert|rebase \(pick\)|merge):/;
1064
+ const resolveLifecycleFromReflog = async ({ repoRoot, branch, baseBranch }) => {
1065
+ const reflog = await runGitCommand({
1066
+ cwd: repoRoot,
1067
+ args: [
1068
+ "reflog",
1069
+ "show",
1070
+ "--format=%H%x09%gs",
1071
+ branch
1072
+ ],
1073
+ reject: false
1074
+ });
1075
+ if (reflog.exitCode !== 0) return {
1076
+ merged: null,
1077
+ divergedHead: null
1078
+ };
1079
+ let latestWorkHead = null;
1080
+ for (const line of reflog.stdout.split("\n")) {
1081
+ const trimmed = line.trim();
1082
+ if (trimmed.length === 0) continue;
1083
+ const separatorIndex = trimmed.indexOf(" ");
1084
+ if (separatorIndex <= 0) continue;
1085
+ const head = trimmed.slice(0, separatorIndex).trim();
1086
+ const message = trimmed.slice(separatorIndex + 1).trim();
1087
+ if (head.length === 0 || WORK_REFLOG_MESSAGE_PATTERN.test(message) !== true) continue;
1088
+ if (latestWorkHead === null) latestWorkHead = head;
1089
+ const result = await runGitCommand({
1090
+ cwd: repoRoot,
1091
+ args: [
1092
+ "merge-base",
1093
+ "--is-ancestor",
1094
+ head,
1095
+ baseBranch
1096
+ ],
1097
+ reject: false
1098
+ });
1099
+ if (result.exitCode === 0) return {
1100
+ merged: true,
1101
+ divergedHead: head
1102
+ };
1103
+ if (result.exitCode !== 1) return {
1104
+ merged: null,
1105
+ divergedHead: latestWorkHead
1106
+ };
1107
+ }
1108
+ return {
1109
+ merged: false,
1110
+ divergedHead: latestWorkHead
1111
+ };
1112
+ };
1052
1113
  const resolveMergedState = async ({ repoRoot, branch, head, baseBranch, mergedByPrByBranch }) => {
1053
1114
  if (branch === null) return {
1054
1115
  byAncestry: null,
@@ -1077,10 +1138,39 @@ const resolveMergedState = async ({ repoRoot, branch, head, baseBranch, mergedBy
1077
1138
  repoRoot,
1078
1139
  branch,
1079
1140
  baseBranch,
1080
- createdHead: head
1141
+ observedDivergedHead: byAncestry === false ? head : null
1081
1142
  });
1082
- if (byAncestry === true) byLifecycle = lifecycle.createdHead !== head;
1083
- else if (byAncestry === false) byLifecycle = false;
1143
+ if (byAncestry === false) byLifecycle = false;
1144
+ else if (byAncestry === true) if (lifecycle.everDiverged !== true || lifecycle.lastDivergedHead === null) if (byPR === true) byLifecycle = null;
1145
+ else {
1146
+ const probe = await resolveLifecycleFromReflog({
1147
+ repoRoot,
1148
+ branch,
1149
+ baseBranch
1150
+ });
1151
+ byLifecycle = probe.merged;
1152
+ if (probe.divergedHead !== null) await upsertWorktreeMergeLifecycle({
1153
+ repoRoot,
1154
+ branch,
1155
+ baseBranch,
1156
+ observedDivergedHead: probe.divergedHead
1157
+ });
1158
+ }
1159
+ else {
1160
+ const lifecycleResult = await runGitCommand({
1161
+ cwd: repoRoot,
1162
+ args: [
1163
+ "merge-base",
1164
+ "--is-ancestor",
1165
+ lifecycle.lastDivergedHead,
1166
+ baseBranch
1167
+ ],
1168
+ reject: false
1169
+ });
1170
+ if (lifecycleResult.exitCode === 0) byLifecycle = true;
1171
+ else if (lifecycleResult.exitCode === 1) byLifecycle = false;
1172
+ else byLifecycle = null;
1173
+ }
1084
1174
  }
1085
1175
  return {
1086
1176
  byAncestry,
@@ -1440,9 +1530,9 @@ const colorizeListTableLine = ({ line, theme }) => {
1440
1530
  const segments = line.split("│");
1441
1531
  if (segments.length < 3) return line;
1442
1532
  const cells = segments.slice(1, -1);
1443
- if (cells.length !== 5) return line;
1533
+ if (cells.length !== 7) return line;
1444
1534
  const headers = cells.map((cell) => cell.trim());
1445
- if (headers[0] === "branch" && headers[1] === "dirty" && headers[2] === "merged" && headers[3] === "locked" && headers[4] === "path") {
1535
+ if (headers[0] === "branch" && headers[1] === "dirty" && headers[2] === "merged" && headers[3] === "locked" && headers[4] === "ahead" && headers[5] === "behind" && headers[6] === "path") {
1446
1536
  const nextCells = cells.map((cell) => colorizeCellContent({
1447
1537
  cell,
1448
1538
  color: theme.header
@@ -1457,13 +1547,21 @@ const colorizeListTableLine = ({ line, theme }) => {
1457
1547
  const dirtyCell = cells[1];
1458
1548
  const mergedCell = cells[2];
1459
1549
  const lockedCell = cells[3];
1460
- const pathCell = cells[4];
1550
+ const aheadCell = cells[4];
1551
+ const behindCell = cells[5];
1552
+ const pathCell = cells[6];
1461
1553
  const branchColor = branchCell.includes("(detached)") === true ? theme.branchDetached : branchCell.trimStart().startsWith("*") ? theme.branchCurrent : theme.branch;
1462
1554
  const dirtyTrimmed = dirtyCell.trim();
1463
1555
  const dirtyColor = dirtyTrimmed === "dirty" ? theme.dirty : dirtyTrimmed === "clean" ? theme.clean : theme.value;
1464
1556
  const mergedTrimmed = mergedCell.trim();
1465
1557
  const mergedColor = mergedTrimmed === "merged" ? theme.merged : mergedTrimmed === "unmerged" ? theme.unmerged : mergedTrimmed === "-" ? theme.base : theme.unknown;
1466
1558
  const lockedColor = lockedCell.trim() === "locked" ? theme.locked : theme.muted;
1559
+ const aheadTrimmed = aheadCell.trim();
1560
+ const aheadValue = Number.parseInt(aheadTrimmed, 10);
1561
+ const aheadColor = aheadTrimmed === "-" ? theme.muted : Number.isNaN(aheadValue) ? theme.value : aheadValue > 0 ? theme.unmerged : aheadValue === 0 ? theme.merged : theme.unknown;
1562
+ const behindTrimmed = behindCell.trim();
1563
+ const behindValue = Number.parseInt(behindTrimmed, 10);
1564
+ const behindColor = behindTrimmed === "-" ? theme.muted : Number.isNaN(behindValue) ? theme.value : behindValue > 0 ? theme.unknown : behindValue === 0 ? theme.merged : theme.unknown;
1467
1565
  const nextCells = [
1468
1566
  colorizeCellContent({
1469
1567
  cell: branchCell,
@@ -1481,6 +1579,14 @@ const colorizeListTableLine = ({ line, theme }) => {
1481
1579
  cell: lockedCell,
1482
1580
  color: lockedColor
1483
1581
  }),
1582
+ colorizeCellContent({
1583
+ cell: aheadCell,
1584
+ color: aheadColor
1585
+ }),
1586
+ colorizeCellContent({
1587
+ cell: behindCell,
1588
+ color: behindColor
1589
+ }),
1484
1590
  colorizeCellContent({
1485
1591
  cell: pathCell,
1486
1592
  color: theme.path
@@ -1509,7 +1615,7 @@ const commandHelpEntries = [
1509
1615
  name: "list",
1510
1616
  usage: "vw list [--json]",
1511
1617
  summary: "List worktrees with status metadata.",
1512
- details: ["Includes branch, path, dirty, lock, merged, and upstream fields."]
1618
+ details: ["Table output includes branch, path, dirty, lock, merged, and ahead/behind vs base branch.", "JSON output includes upstream metadata fields."]
1513
1619
  },
1514
1620
  {
1515
1621
  name: "status",
@@ -1881,22 +1987,6 @@ const resolveBaseBranch = async (repoRoot) => {
1881
1987
  for (const candidate of ["main", "master"]) if (await doesGitRefExist(repoRoot, `refs/heads/${candidate}`)) return candidate;
1882
1988
  throw createCliError("INVALID_ARGUMENT", { message: "Unable to resolve base branch. Configure vde-worktree.baseBranch." });
1883
1989
  };
1884
- const resolveBranchHead = async ({ repoRoot, branch }) => {
1885
- const resolved = await runGitCommand({
1886
- cwd: repoRoot,
1887
- args: [
1888
- "rev-parse",
1889
- "--verify",
1890
- branch
1891
- ],
1892
- reject: false
1893
- });
1894
- if (resolved.exitCode !== 0 || resolved.stdout.trim().length === 0) throw createCliError("INVALID_ARGUMENT", {
1895
- message: `Failed to resolve branch head: ${branch}`,
1896
- details: { branch }
1897
- });
1898
- return resolved.stdout.trim();
1899
- };
1900
1990
  const ensureTargetPathWritable = async (targetPath) => {
1901
1991
  try {
1902
1992
  await access(targetPath, constants.F_OK);
@@ -2342,6 +2432,37 @@ const formatMergedColor = ({ mergedState, theme }) => {
2342
2432
  if (normalized === "base") return theme.base(mergedState);
2343
2433
  return theme.unknown(mergedState);
2344
2434
  };
2435
+ const formatListUpstreamCount = (value) => {
2436
+ if (value === null) return "-";
2437
+ return String(value);
2438
+ };
2439
+ const resolveAheadBehindAgainstBaseBranch = async ({ repoRoot, baseBranch, worktree }) => {
2440
+ if (baseBranch === null) return {
2441
+ ahead: null,
2442
+ behind: null
2443
+ };
2444
+ const distance = await runGitCommand({
2445
+ cwd: repoRoot,
2446
+ args: [
2447
+ "rev-list",
2448
+ "--left-right",
2449
+ "--count",
2450
+ `${baseBranch}...${worktree.branch ?? worktree.head}`
2451
+ ],
2452
+ reject: false
2453
+ });
2454
+ if (distance.exitCode !== 0) return {
2455
+ ahead: null,
2456
+ behind: null
2457
+ };
2458
+ const [behindRaw, aheadRaw] = distance.stdout.trim().split(/\s+/);
2459
+ const behind = Number.parseInt(behindRaw ?? "", 10);
2460
+ const ahead = Number.parseInt(aheadRaw ?? "", 10);
2461
+ return {
2462
+ ahead: Number.isNaN(ahead) ? null : ahead,
2463
+ behind: Number.isNaN(behind) ? null : behind
2464
+ };
2465
+ };
2345
2466
  const padToDisplayWidth = ({ value, width }) => {
2346
2467
  const visibleLength = stringWidth(value);
2347
2468
  if (visibleLength >= width) return value;
@@ -2910,17 +3031,26 @@ const createCli = (options = {}) => {
2910
3031
  "dirty",
2911
3032
  "merged",
2912
3033
  "locked",
3034
+ "ahead",
3035
+ "behind",
2913
3036
  "path"
2914
- ], ...snapshot.worktrees.map((worktree) => {
3037
+ ], ...await Promise.all(snapshot.worktrees.map(async (worktree) => {
3038
+ const distanceFromBase = await resolveAheadBehindAgainstBaseBranch({
3039
+ repoRoot,
3040
+ baseBranch: snapshot.baseBranch,
3041
+ worktree
3042
+ });
2915
3043
  const mergedState = (worktree.branch !== null && snapshot.baseBranch !== null && worktree.branch === snapshot.baseBranch) === true ? "-" : worktree.merged.overall === true ? "merged" : worktree.merged.overall === false ? "unmerged" : "unknown";
2916
3044
  return [
2917
3045
  `${worktree.path === repoContext.currentWorktreeRoot ? "*" : " "} ${worktree.branch ?? "(detached)"}`,
2918
3046
  worktree.dirty ? "dirty" : "clean",
2919
3047
  mergedState,
2920
3048
  worktree.locked.value ? "locked" : "-",
3049
+ formatListUpstreamCount(distanceFromBase.ahead),
3050
+ formatListUpstreamCount(distanceFromBase.behind),
2921
3051
  formatDisplayPath(worktree.path)
2922
3052
  ];
2923
- })], {
3053
+ }))], {
2924
3054
  border: getBorderCharacters("norc"),
2925
3055
  drawHorizontalLine: (lineIndex, rowCount) => {
2926
3056
  return lineIndex === 0 || lineIndex === 1 || lineIndex === rowCount;
@@ -3039,10 +3169,7 @@ const createCli = (options = {}) => {
3039
3169
  repoRoot,
3040
3170
  branch,
3041
3171
  baseBranch,
3042
- createdHead: await resolveBranchHead({
3043
- repoRoot,
3044
- branch
3045
- })
3172
+ observedDivergedHead: null
3046
3173
  });
3047
3174
  await runPostHook({
3048
3175
  name: "new",
@@ -3077,18 +3204,12 @@ const createCli = (options = {}) => {
3077
3204
  const snapshot = await collectWorktreeSnapshot$1(repoRoot);
3078
3205
  const existing = snapshot.worktrees.find((worktree) => worktree.branch === branch);
3079
3206
  if (existing !== void 0) {
3080
- if (snapshot.baseBranch !== null) {
3081
- const branchHead = await resolveBranchHead({
3082
- repoRoot,
3083
- branch
3084
- });
3085
- await upsertWorktreeMergeLifecycle({
3086
- repoRoot,
3087
- branch,
3088
- baseBranch: snapshot.baseBranch,
3089
- createdHead: branchHead
3090
- });
3091
- }
3207
+ if (snapshot.baseBranch !== null) await upsertWorktreeMergeLifecycle({
3208
+ repoRoot,
3209
+ branch,
3210
+ baseBranch: snapshot.baseBranch,
3211
+ observedDivergedHead: null
3212
+ });
3092
3213
  return {
3093
3214
  status: "existing",
3094
3215
  branch,
@@ -3134,18 +3255,12 @@ const createCli = (options = {}) => {
3134
3255
  ]
3135
3256
  });
3136
3257
  }
3137
- if (lifecycleBaseBranch !== null) {
3138
- const branchHead = await resolveBranchHead({
3139
- repoRoot,
3140
- branch
3141
- });
3142
- await upsertWorktreeMergeLifecycle({
3143
- repoRoot,
3144
- branch,
3145
- baseBranch: lifecycleBaseBranch,
3146
- createdHead: branchHead
3147
- });
3148
- }
3258
+ if (lifecycleBaseBranch !== null) await upsertWorktreeMergeLifecycle({
3259
+ repoRoot,
3260
+ branch,
3261
+ baseBranch: lifecycleBaseBranch,
3262
+ observedDivergedHead: null
3263
+ });
3149
3264
  await runPostHook({
3150
3265
  name: "switch",
3151
3266
  context: hookContext
@@ -3245,19 +3360,13 @@ const createCli = (options = {}) => {
3245
3360
  newPath
3246
3361
  ]
3247
3362
  });
3248
- if (snapshot.baseBranch !== null) {
3249
- const branchHead = await resolveBranchHead({
3250
- repoRoot,
3251
- branch: newBranch
3252
- });
3253
- await moveWorktreeMergeLifecycle({
3254
- repoRoot,
3255
- fromBranch: oldBranch,
3256
- toBranch: newBranch,
3257
- baseBranch: snapshot.baseBranch,
3258
- createdHead: branchHead
3259
- });
3260
- }
3363
+ if (snapshot.baseBranch !== null) await moveWorktreeMergeLifecycle({
3364
+ repoRoot,
3365
+ fromBranch: oldBranch,
3366
+ toBranch: newBranch,
3367
+ baseBranch: snapshot.baseBranch,
3368
+ observedDivergedHead: null
3369
+ });
3261
3370
  await runPostHook({
3262
3371
  name: "mv",
3263
3372
  context: hookContext
@@ -3526,10 +3635,7 @@ const createCli = (options = {}) => {
3526
3635
  repoRoot,
3527
3636
  branch,
3528
3637
  baseBranch: lifecycleBaseBranch,
3529
- createdHead: await resolveBranchHead({
3530
- repoRoot,
3531
- branch
3532
- })
3638
+ observedDivergedHead: null
3533
3639
  });
3534
3640
  await runPostHook({
3535
3641
  name: "get",
@@ -3556,10 +3662,7 @@ const createCli = (options = {}) => {
3556
3662
  repoRoot,
3557
3663
  branch,
3558
3664
  baseBranch: lifecycleBaseBranch,
3559
- createdHead: await resolveBranchHead({
3560
- repoRoot,
3561
- branch
3562
- })
3665
+ observedDivergedHead: null
3563
3666
  });
3564
3667
  await runPostHook({
3565
3668
  name: "get",
@@ -3671,10 +3774,7 @@ const createCli = (options = {}) => {
3671
3774
  repoRoot,
3672
3775
  branch,
3673
3776
  baseBranch,
3674
- createdHead: await resolveBranchHead({
3675
- repoRoot,
3676
- branch
3677
- })
3777
+ observedDivergedHead: null
3678
3778
  });
3679
3779
  if (stashOid !== null) {
3680
3780
  if ((await runGitCommand({