sequant 1.10.0 → 1.10.1
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/dist/src/commands/run.js +51 -4
- package/package.json +1 -1
package/dist/src/commands/run.js
CHANGED
|
@@ -107,8 +107,9 @@ export function getWorktreeChangedFiles(worktreePath) {
|
|
|
107
107
|
/**
|
|
108
108
|
* Create or reuse a worktree for an issue
|
|
109
109
|
* @param baseBranch - Optional branch to use as base instead of origin/main (for chain mode)
|
|
110
|
+
* @param chainMode - If true and branch exists, rebase onto baseBranch instead of using as-is
|
|
110
111
|
*/
|
|
111
|
-
async function ensureWorktree(issueNumber, title, verbose, packageManager, baseBranch) {
|
|
112
|
+
async function ensureWorktree(issueNumber, title, verbose, packageManager, baseBranch, chainMode) {
|
|
112
113
|
const gitRoot = getGitRoot();
|
|
113
114
|
if (!gitRoot) {
|
|
114
115
|
console.log(chalk.red(" ❌ Not in a git repository"));
|
|
@@ -129,6 +130,7 @@ async function ensureWorktree(issueNumber, title, verbose, packageManager, baseB
|
|
|
129
130
|
path: existingPath,
|
|
130
131
|
branch,
|
|
131
132
|
existed: true,
|
|
133
|
+
rebased: false,
|
|
132
134
|
};
|
|
133
135
|
}
|
|
134
136
|
// Check if branch exists (but no worktree)
|
|
@@ -172,11 +174,16 @@ async function ensureWorktree(issueNumber, title, verbose, packageManager, baseB
|
|
|
172
174
|
}
|
|
173
175
|
// Create the worktree
|
|
174
176
|
let createResult;
|
|
177
|
+
let needsRebase = false;
|
|
175
178
|
if (branchExists) {
|
|
176
179
|
// Use existing branch
|
|
177
180
|
createResult = spawnSync("git", ["worktree", "add", worktreePath, branch], {
|
|
178
181
|
stdio: "pipe",
|
|
179
182
|
});
|
|
183
|
+
// In chain mode with existing branch, mark for rebase onto previous chain link
|
|
184
|
+
if (chainMode && baseBranch) {
|
|
185
|
+
needsRebase = true;
|
|
186
|
+
}
|
|
180
187
|
}
|
|
181
188
|
else {
|
|
182
189
|
// Create new branch from base reference (origin/main or previous branch in chain)
|
|
@@ -187,6 +194,39 @@ async function ensureWorktree(issueNumber, title, verbose, packageManager, baseB
|
|
|
187
194
|
console.log(chalk.red(` ❌ Failed to create worktree: ${error}`));
|
|
188
195
|
return null;
|
|
189
196
|
}
|
|
197
|
+
// Rebase existing branch onto chain base if needed
|
|
198
|
+
let rebased = false;
|
|
199
|
+
if (needsRebase) {
|
|
200
|
+
if (verbose) {
|
|
201
|
+
console.log(chalk.gray(` 🔄 Rebasing existing branch onto previous chain link (${baseRef})...`));
|
|
202
|
+
}
|
|
203
|
+
const rebaseResult = spawnSync("git", ["-C", worktreePath, "rebase", baseRef], {
|
|
204
|
+
stdio: "pipe",
|
|
205
|
+
});
|
|
206
|
+
if (rebaseResult.status !== 0) {
|
|
207
|
+
const rebaseError = rebaseResult.stderr.toString();
|
|
208
|
+
// Check if it's a conflict
|
|
209
|
+
if (rebaseError.includes("CONFLICT") ||
|
|
210
|
+
rebaseError.includes("could not apply")) {
|
|
211
|
+
console.log(chalk.yellow(` ⚠️ Rebase conflict detected. Aborting rebase and keeping original branch state.`));
|
|
212
|
+
console.log(chalk.yellow(` ℹ️ Branch ${branch} is not properly chained. Manual rebase may be required.`));
|
|
213
|
+
// Abort the rebase to restore branch state
|
|
214
|
+
spawnSync("git", ["-C", worktreePath, "rebase", "--abort"], {
|
|
215
|
+
stdio: "pipe",
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
console.log(chalk.yellow(` ⚠️ Rebase failed: ${rebaseError.trim()}`));
|
|
220
|
+
console.log(chalk.yellow(` ℹ️ Continuing with branch in its original state.`));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
rebased = true;
|
|
225
|
+
if (verbose) {
|
|
226
|
+
console.log(chalk.green(` ✅ Branch rebased onto ${baseRef}`));
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
190
230
|
// Copy .env.local if it exists
|
|
191
231
|
const envLocalSrc = path.join(gitRoot, ".env.local");
|
|
192
232
|
const envLocalDst = path.join(worktreePath, ".env.local");
|
|
@@ -225,6 +265,7 @@ async function ensureWorktree(issueNumber, title, verbose, packageManager, baseB
|
|
|
225
265
|
path: worktreePath,
|
|
226
266
|
branch,
|
|
227
267
|
existed: false,
|
|
268
|
+
rebased,
|
|
228
269
|
};
|
|
229
270
|
}
|
|
230
271
|
/**
|
|
@@ -236,7 +277,7 @@ async function ensureWorktrees(issues, verbose, packageManager, baseBranch) {
|
|
|
236
277
|
const baseDisplay = baseBranch || "main";
|
|
237
278
|
console.log(chalk.blue(`\n 📂 Preparing worktrees from ${baseDisplay}...`));
|
|
238
279
|
for (const issue of issues) {
|
|
239
|
-
const worktree = await ensureWorktree(issue.number, issue.title, verbose, packageManager, baseBranch);
|
|
280
|
+
const worktree = await ensureWorktree(issue.number, issue.title, verbose, packageManager, baseBranch, false);
|
|
240
281
|
if (worktree) {
|
|
241
282
|
worktrees.set(issue.number, worktree);
|
|
242
283
|
}
|
|
@@ -260,7 +301,8 @@ async function ensureWorktreesChain(issues, verbose, packageManager, baseBranch)
|
|
|
260
301
|
// First issue starts from the specified base branch (or main)
|
|
261
302
|
let previousBranch = baseBranch;
|
|
262
303
|
for (const issue of issues) {
|
|
263
|
-
const worktree = await ensureWorktree(issue.number, issue.title, verbose, packageManager, previousBranch)
|
|
304
|
+
const worktree = await ensureWorktree(issue.number, issue.title, verbose, packageManager, previousBranch, // Chain from previous branch (or base branch for first issue)
|
|
305
|
+
true);
|
|
264
306
|
if (worktree) {
|
|
265
307
|
worktrees.set(issue.number, worktree);
|
|
266
308
|
previousBranch = worktree.branch; // Next issue will branch from this
|
|
@@ -273,8 +315,13 @@ async function ensureWorktreesChain(issues, verbose, packageManager, baseBranch)
|
|
|
273
315
|
}
|
|
274
316
|
const created = Array.from(worktrees.values()).filter((w) => !w.existed).length;
|
|
275
317
|
const reused = Array.from(worktrees.values()).filter((w) => w.existed).length;
|
|
318
|
+
const rebased = Array.from(worktrees.values()).filter((w) => w.rebased).length;
|
|
276
319
|
if (created > 0 || reused > 0) {
|
|
277
|
-
|
|
320
|
+
let msg = ` Chained worktrees: ${created} created, ${reused} reused`;
|
|
321
|
+
if (rebased > 0) {
|
|
322
|
+
msg += `, ${rebased} rebased`;
|
|
323
|
+
}
|
|
324
|
+
console.log(chalk.gray(msg));
|
|
278
325
|
}
|
|
279
326
|
// Show chain structure
|
|
280
327
|
if (worktrees.size > 0) {
|