gh-stack 0.19.5 → 0.19.6

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.md CHANGED
@@ -92,6 +92,9 @@ add [branch] [--parent <branch>]
92
92
  stack — without pushing or opening a PR. Walks local ancestry: if the
93
93
  branch sits on top of an existing stack it's adopted into it (parent
94
94
  auto-detected); otherwise a new stack is created from the chain.
95
+ A PR that gh-stack already recorded for a branch in git config (in
96
+ another worktree of the repo) is kept, so a stack submitted from a
97
+ worktree can be tracked in the main checkout and merged from there.
95
98
 
96
99
  --parent <branch>: stack it directly on <branch> (which it must
97
100
  already be based on), tracking <branch> first if needed. Use this
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gh-stack",
3
- "version": "0.19.5",
3
+ "version": "0.19.6",
4
4
  "description": "Stacked PR manager for squash-merge workflows",
5
5
  "author": "Kiliman <kiliman@gmail.com>",
6
6
  "license": "MIT",
@@ -38,7 +38,8 @@ OPTIONS
38
38
  its stack and has no PR (e.g. a mistaken ${"`"}init${"`"} at trunk).
39
39
 
40
40
  Network-free — nothing is pushed and no PR is opened. Run ${"`"}gh-stack submit${"`"} when
41
- you're ready to publish.
41
+ you're ready to publish. A PR already recorded for the branch in git config
42
+ (by gh-stack in another worktree of this repo) is kept.
42
43
 
43
44
  EXAMPLES
44
45
  gh-stack add Track the current branch
package/src/lib/chain.ts CHANGED
@@ -4,9 +4,25 @@
4
4
  // auto-create/register a stack from a bare set of local branches so the
5
5
  // end state is always stack registered + branches pushed + PRs created).
6
6
  import * as git from "./git.ts";
7
+ import { allBranchMemberships, type BranchMembership } from "./branch-config.ts";
7
8
  import { findStackForBranch, getOrderedBranches, stackBase } from "./metadata.ts";
8
9
  import type { StackMetadata, Branch } from "../types.ts";
9
10
 
11
+ /**
12
+ * A new stack entry for a branch, keeping the PR number and id already
13
+ * recorded for it in git config. Git config is shared by every worktree of a
14
+ * repo, but stack files are not: a branch submitted in one worktree and then
15
+ * tracked in another (the dependency sweep's handoff) would otherwise lose its
16
+ * PR, and `sync` and `merge --base` would not see it merge.
17
+ */
18
+ function newBranchEntry(parent: string, recorded: BranchMembership | undefined): Branch {
19
+ return {
20
+ parent,
21
+ ...(recorded?.pr != null && { pr: recorded.pr }),
22
+ ...(recorded?.id && { id: recorded.id }),
23
+ };
24
+ }
25
+
10
26
  /**
11
27
  * Detect a chain of branches from trunk to the current branch.
12
28
  *
@@ -107,6 +123,7 @@ export async function resolveOrCreateStack(
107
123
  trunk: string,
108
124
  ): Promise<StackResolution> {
109
125
  const fullChain = await detectBranchChain(branch, trunk); // trunk→current
126
+ const recorded = await allBranchMemberships();
110
127
 
111
128
  // Walk from just below `branch` downward; the first tracked ancestor is the
112
129
  // attachment point. Everything above it (up to `branch`) is the untracked
@@ -143,7 +160,7 @@ export async function resolveOrCreateStack(
143
160
  }
144
161
 
145
162
  if (stack.branches[name]) continue; // already tracked — leave as-is
146
- stack.branches[name] = { parent };
163
+ stack.branches[name] = newBranchEntry(parent, recorded.get(name));
147
164
  stack.last_branch = name;
148
165
  addedBranches.push(name);
149
166
  }
@@ -177,8 +194,7 @@ export async function resolveOrCreateStack(
177
194
  const name = fullChain[i]!;
178
195
  if (stack.branches[name]) continue;
179
196
  const parent = i === 0 ? trunk : fullChain[i - 1]!;
180
- const branchData: Branch = { parent };
181
- stack.branches[name] = branchData;
197
+ stack.branches[name] = newBranchEntry(parent, recorded.get(name));
182
198
  stack.last_branch = name;
183
199
  addedBranches.push(name);
184
200
  }
@@ -129,6 +129,11 @@ This resolves the catch-22 where `sync`/`restack` said "not in any stack" for a
129
129
  tip you hadn't submitted yet. (`submit` still auto-tracks too — `add` is just the
130
130
  no-publish path.)
131
131
 
132
+ **Handing a stack over from another worktree.** Stack files are per worktree,
133
+ but the PR numbers gh-stack records in git config are shared. So after
134
+ submitting from a worktree, `gh-stack add <top-branch>` in the main checkout
135
+ tracks the whole chain _with_ its PRs, and `sync`/`merge --base` work there.
136
+
132
137
  **Splice an existing branch/PR into a stack — `gh-stack join`.** For a branch
133
138
  that should have been stacked but was cut from main on its own (often with its
134
139
  own PR already open):