@desplega.ai/wts 0.2.0 → 0.2.2
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/index.js +60 -15
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1877,7 +1877,7 @@ var {
|
|
|
1877
1877
|
// package.json
|
|
1878
1878
|
var package_default = {
|
|
1879
1879
|
name: "@desplega.ai/wts",
|
|
1880
|
-
version: "0.2.
|
|
1880
|
+
version: "0.2.2",
|
|
1881
1881
|
description: "Git worktree manager with tmux integration",
|
|
1882
1882
|
type: "module",
|
|
1883
1883
|
bin: {
|
|
@@ -3337,7 +3337,12 @@ function printWorktreeTable(worktrees, projectName) {
|
|
|
3337
3337
|
}
|
|
3338
3338
|
|
|
3339
3339
|
// src/commands/merge.ts
|
|
3340
|
-
|
|
3340
|
+
async function getCommitsToMerge(branch, baseBranch, cwd) {
|
|
3341
|
+
const result = await Bun.$`git log ${baseBranch}..${branch} --oneline`.cwd(cwd).quiet();
|
|
3342
|
+
return result.stdout.toString().trim().split(`
|
|
3343
|
+
`).filter(Boolean);
|
|
3344
|
+
}
|
|
3345
|
+
var mergeCommand = new Command2("merge").description("Merge a worktree branch into main").argument("[alias]", "Alias of the worktree to merge").option("--no-cleanup", "Skip cleanup prompt").option("--no-pull", "Skip pulling latest main").option("-f, --force", "Skip confirmations (except cleanup)").action(async (alias, options) => {
|
|
3341
3346
|
const gitRoot = await getGitRoot();
|
|
3342
3347
|
if (!gitRoot) {
|
|
3343
3348
|
console.error(source_default.red("Error: Not in a git repository"));
|
|
@@ -3345,6 +3350,12 @@ var mergeCommand = new Command2("merge").description("Merge a worktree branch in
|
|
|
3345
3350
|
}
|
|
3346
3351
|
const config = await resolveConfig(gitRoot);
|
|
3347
3352
|
const worktrees = await listWorktrees(gitRoot, config.projectName);
|
|
3353
|
+
const mainWorktree = worktrees.find((wt) => wt.isMain);
|
|
3354
|
+
if (!mainWorktree) {
|
|
3355
|
+
console.error(source_default.red("Error: Could not find main worktree"));
|
|
3356
|
+
process.exit(1);
|
|
3357
|
+
}
|
|
3358
|
+
const mainPath = mainWorktree.path;
|
|
3348
3359
|
let worktree;
|
|
3349
3360
|
if (alias) {
|
|
3350
3361
|
worktree = await findWorktreeByAlias(alias, gitRoot);
|
|
@@ -3381,16 +3392,37 @@ Merging ${source_default.cyan(branchToMerge)} into ${source_default.cyan(default
|
|
|
3381
3392
|
}
|
|
3382
3393
|
}
|
|
3383
3394
|
console.log(source_default.dim(`Switching to ${defaultBranch}...`));
|
|
3384
|
-
await Bun.$`git checkout ${defaultBranch}`.cwd(
|
|
3385
|
-
if (
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3395
|
+
await Bun.$`git checkout ${defaultBranch}`.cwd(mainPath);
|
|
3396
|
+
if (options.pull !== false) {
|
|
3397
|
+
if (!options.force) {
|
|
3398
|
+
const proceed = await confirm(`Pull latest ${defaultBranch}?`, true);
|
|
3399
|
+
if (!proceed) {
|
|
3400
|
+
console.log(source_default.dim("Skipped pull"));
|
|
3401
|
+
} else {
|
|
3402
|
+
console.log(source_default.dim(`Pulling latest...`));
|
|
3403
|
+
await Bun.$`git pull`.cwd(mainPath);
|
|
3404
|
+
}
|
|
3405
|
+
} else {
|
|
3406
|
+
console.log(source_default.dim(`Pulling latest...`));
|
|
3407
|
+
await Bun.$`git pull`.cwd(mainPath);
|
|
3390
3408
|
}
|
|
3391
3409
|
}
|
|
3392
|
-
|
|
3393
|
-
|
|
3410
|
+
const commitsToMerge = await getCommitsToMerge(branchToMerge, defaultBranch, mainPath);
|
|
3411
|
+
if (commitsToMerge.length === 0) {
|
|
3412
|
+
console.log(source_default.yellow(`
|
|
3413
|
+
No commits to merge - ${branchToMerge} has no new commits compared to ${defaultBranch}`));
|
|
3414
|
+
console.log(source_default.dim("The branch may need to be rebased on latest main first."));
|
|
3415
|
+
console.log(source_default.dim("Aborting to prevent accidental data loss."));
|
|
3416
|
+
process.exit(1);
|
|
3417
|
+
}
|
|
3418
|
+
console.log(source_default.dim(`
|
|
3419
|
+
Commits to merge (${commitsToMerge.length}):`));
|
|
3420
|
+
for (const commit of commitsToMerge.slice(0, 5)) {
|
|
3421
|
+
console.log(source_default.dim(` ${commit}`));
|
|
3422
|
+
}
|
|
3423
|
+
if (commitsToMerge.length > 5) {
|
|
3424
|
+
console.log(source_default.dim(` ... and ${commitsToMerge.length - 5} more`));
|
|
3425
|
+
}
|
|
3394
3426
|
if (!options.force) {
|
|
3395
3427
|
const proceed = await confirm(`Merge ${branchToMerge}?`, true);
|
|
3396
3428
|
if (!proceed) {
|
|
@@ -3399,18 +3431,26 @@ Merging ${source_default.cyan(branchToMerge)} into ${source_default.cyan(default
|
|
|
3399
3431
|
}
|
|
3400
3432
|
}
|
|
3401
3433
|
console.log(source_default.dim(`Merging ${branchToMerge}...`));
|
|
3402
|
-
await Bun.$`git merge ${branchToMerge}`.cwd(
|
|
3434
|
+
const mergeResult = await Bun.$`git merge ${branchToMerge}`.cwd(mainPath).quiet();
|
|
3435
|
+
const mergeOutput = mergeResult.stdout.toString();
|
|
3436
|
+
console.log(source_default.dim(mergeOutput.trim()));
|
|
3437
|
+
if (mergeOutput.includes("Already up to date")) {
|
|
3438
|
+
console.log(source_default.yellow(`
|
|
3439
|
+
Merge reported 'Already up to date' - no changes were made`));
|
|
3440
|
+
console.log(source_default.red("Aborting cleanup to prevent data loss"));
|
|
3441
|
+
process.exit(1);
|
|
3442
|
+
}
|
|
3403
3443
|
if (!options.force) {
|
|
3404
3444
|
const proceed = await confirm(`Push to origin?`, true);
|
|
3405
3445
|
if (!proceed) {
|
|
3406
3446
|
console.log(source_default.dim("Skipped push"));
|
|
3407
3447
|
} else {
|
|
3408
3448
|
console.log(source_default.dim(`Pushing...`));
|
|
3409
|
-
await Bun.$`git push`.cwd(
|
|
3449
|
+
await Bun.$`git push`.cwd(mainPath);
|
|
3410
3450
|
}
|
|
3411
3451
|
} else {
|
|
3412
3452
|
console.log(source_default.dim(`Pushing...`));
|
|
3413
|
-
await Bun.$`git push`.cwd(
|
|
3453
|
+
await Bun.$`git push`.cwd(mainPath);
|
|
3414
3454
|
}
|
|
3415
3455
|
console.log(source_default.green(`
|
|
3416
3456
|
✓ Merged ${branchToMerge} into ${defaultBranch}`));
|
|
@@ -3419,9 +3459,14 @@ Merging ${source_default.cyan(branchToMerge)} into ${source_default.cyan(default
|
|
|
3419
3459
|
Clean up worktree and branch?`, false);
|
|
3420
3460
|
if (cleanup) {
|
|
3421
3461
|
console.log(source_default.dim(`Removing worktree...`));
|
|
3422
|
-
await removeWorktree(worktree.path, true,
|
|
3462
|
+
await removeWorktree(worktree.path, true, mainPath);
|
|
3423
3463
|
console.log(source_default.dim(`Deleting branch ${branchToMerge}...`));
|
|
3424
|
-
|
|
3464
|
+
try {
|
|
3465
|
+
await deleteBranch(branchToMerge, false, mainPath);
|
|
3466
|
+
} catch {
|
|
3467
|
+
console.error(source_default.red("Branch not fully merged - keeping branch for safety"));
|
|
3468
|
+
console.log(source_default.dim("Use 'git branch -D <branch>' to force delete if intended"));
|
|
3469
|
+
}
|
|
3425
3470
|
console.log(source_default.green(`✓ Cleaned up`));
|
|
3426
3471
|
}
|
|
3427
3472
|
}
|