@lsst/pik-plugin-worktree 0.4.2 → 0.5.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/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +62 -47
- package/dist/lib/git.d.ts +16 -22
- package/dist/lib/git.d.ts.map +1 -1
- package/package.json +4 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { worktreePlugin } from './lib/plugin.js';
|
|
2
2
|
export type { WorktreeConfig } from './lib/types.js';
|
|
3
|
-
export {
|
|
3
|
+
export { getGit, getRepoRoot, getCurrentBranch, isClean, listWorktrees, createWorktree, removeWorktree, listBranches, branchExists, deleteBranch, isWorktree, type Worktree, } from './lib/git.js';
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjD,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjD,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,OAAO,EACL,MAAM,EACN,WAAW,EACX,gBAAgB,EAChB,OAAO,EACP,aAAa,EACb,cAAc,EACd,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,KAAK,QAAQ,GACd,MAAM,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -6,34 +6,26 @@ import { execSync } from "child_process";
|
|
|
6
6
|
import { existsSync, mkdirSync, copyFileSync } from "fs";
|
|
7
7
|
import { glob } from "glob";
|
|
8
8
|
import { loadConfig } from "@lsst/pik-core";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
cwd,
|
|
13
|
-
encoding: "utf-8",
|
|
14
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
15
|
-
}).trim();
|
|
16
|
-
} catch (error) {
|
|
17
|
-
const err = error;
|
|
18
|
-
const gitError = new Error(
|
|
19
|
-
err.stderr?.toString().trim() || err.message
|
|
20
|
-
);
|
|
21
|
-
gitError.stderr = err.stderr?.toString();
|
|
22
|
-
throw gitError;
|
|
23
|
-
}
|
|
9
|
+
import { simpleGit } from "simple-git";
|
|
10
|
+
function getGit(cwd) {
|
|
11
|
+
return simpleGit(cwd);
|
|
24
12
|
}
|
|
25
|
-
function getRepoRoot(cwd) {
|
|
26
|
-
|
|
13
|
+
async function getRepoRoot(cwd) {
|
|
14
|
+
const git = getGit(cwd);
|
|
15
|
+
return (await git.revparse(["--show-toplevel"])).trim();
|
|
27
16
|
}
|
|
28
|
-
function getCurrentBranch(cwd) {
|
|
29
|
-
|
|
17
|
+
async function getCurrentBranch(cwd) {
|
|
18
|
+
const git = getGit(cwd);
|
|
19
|
+
return (await git.revparse(["--abbrev-ref", "HEAD"])).trim();
|
|
30
20
|
}
|
|
31
|
-
function isClean(cwd) {
|
|
32
|
-
const
|
|
33
|
-
|
|
21
|
+
async function isClean(cwd) {
|
|
22
|
+
const git = getGit(cwd);
|
|
23
|
+
const status = await git.status();
|
|
24
|
+
return status.isClean();
|
|
34
25
|
}
|
|
35
|
-
function listWorktrees(cwd) {
|
|
36
|
-
const
|
|
26
|
+
async function listWorktrees(cwd) {
|
|
27
|
+
const git = getGit(cwd);
|
|
28
|
+
const output = await git.raw(["worktree", "list", "--porcelain"]);
|
|
37
29
|
if (!output) return [];
|
|
38
30
|
const worktrees = [];
|
|
39
31
|
let current = {};
|
|
@@ -63,7 +55,8 @@ function listWorktrees(cwd) {
|
|
|
63
55
|
}
|
|
64
56
|
return worktrees;
|
|
65
57
|
}
|
|
66
|
-
function createWorktree(path, branch, options, cwd) {
|
|
58
|
+
async function createWorktree(path, branch, options, cwd) {
|
|
59
|
+
const git = getGit(cwd);
|
|
67
60
|
const args = ["worktree", "add"];
|
|
68
61
|
if (options?.newBranch) {
|
|
69
62
|
args.push("-b", branch);
|
|
@@ -74,36 +67,56 @@ function createWorktree(path, branch, options, cwd) {
|
|
|
74
67
|
} else {
|
|
75
68
|
args.push(path, branch);
|
|
76
69
|
}
|
|
77
|
-
git(args
|
|
70
|
+
await git.raw(args);
|
|
78
71
|
}
|
|
79
|
-
function removeWorktree(path, force, cwd) {
|
|
72
|
+
async function removeWorktree(path, force, cwd) {
|
|
73
|
+
const git = getGit(cwd);
|
|
80
74
|
const args = ["worktree", "remove"];
|
|
81
75
|
if (force) {
|
|
82
76
|
args.push("--force");
|
|
83
77
|
}
|
|
84
78
|
args.push(path);
|
|
85
|
-
git(args
|
|
79
|
+
await git.raw(args);
|
|
86
80
|
}
|
|
87
|
-
function listBranches(cwd) {
|
|
88
|
-
const
|
|
89
|
-
|
|
81
|
+
async function listBranches(cwd) {
|
|
82
|
+
const git = getGit(cwd);
|
|
83
|
+
const result = await git.branchLocal();
|
|
84
|
+
return result.all;
|
|
90
85
|
}
|
|
91
|
-
function branchExists(branch, cwd) {
|
|
86
|
+
async function branchExists(branch, cwd) {
|
|
87
|
+
const git = getGit(cwd);
|
|
92
88
|
try {
|
|
93
|
-
git(["
|
|
89
|
+
await git.revparse(["--verify", branch]);
|
|
94
90
|
return true;
|
|
95
91
|
} catch {
|
|
96
92
|
return false;
|
|
97
93
|
}
|
|
98
94
|
}
|
|
95
|
+
async function deleteBranch(branch, force, cwd) {
|
|
96
|
+
const git = getGit(cwd);
|
|
97
|
+
if (force) {
|
|
98
|
+
await git.branch(["-D", branch]);
|
|
99
|
+
} else {
|
|
100
|
+
await git.branch(["-d", branch]);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async function isWorktree(path) {
|
|
104
|
+
const git = getGit(path);
|
|
105
|
+
try {
|
|
106
|
+
const gitDir = await git.revparse(["--git-dir"]);
|
|
107
|
+
return gitDir.includes(".git/worktrees/");
|
|
108
|
+
} catch {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
99
112
|
const createCommand = new Command("create").alias("add").description("Create a new worktree").argument("[name]", "Name for the worktree directory").option("-b, --branch <branch>", "Branch to checkout (or create with -n)").option("-n, --new", "Create a new branch").action(async (name, options) => {
|
|
100
113
|
try {
|
|
101
|
-
const repoRoot = getRepoRoot();
|
|
114
|
+
const repoRoot = await getRepoRoot();
|
|
102
115
|
const config = await loadConfig(repoRoot);
|
|
103
116
|
const worktreeConfig = config?.worktree ?? {};
|
|
104
|
-
const currentBranch = getCurrentBranch(repoRoot);
|
|
105
|
-
const branches = listBranches(repoRoot);
|
|
106
|
-
const existingWorktrees = listWorktrees(repoRoot);
|
|
117
|
+
const currentBranch = await getCurrentBranch(repoRoot);
|
|
118
|
+
const branches = await listBranches(repoRoot);
|
|
119
|
+
const existingWorktrees = await listWorktrees(repoRoot);
|
|
107
120
|
const existingPaths = new Set(existingWorktrees.map((w) => w.path));
|
|
108
121
|
let branch = options.branch;
|
|
109
122
|
let isNewBranch = options.new ?? false;
|
|
@@ -119,9 +132,9 @@ const createCommand = new Command("create").alias("add").description("Create a n
|
|
|
119
132
|
isNewBranch = true;
|
|
120
133
|
branch = await input({
|
|
121
134
|
message: "New branch name:",
|
|
122
|
-
validate: (value) => {
|
|
135
|
+
validate: async (value) => {
|
|
123
136
|
if (!value.trim()) return "Branch name is required";
|
|
124
|
-
if (branchExists(value, repoRoot)) return "Branch already exists";
|
|
137
|
+
if (await branchExists(value, repoRoot)) return "Branch already exists";
|
|
125
138
|
return true;
|
|
126
139
|
}
|
|
127
140
|
});
|
|
@@ -165,7 +178,7 @@ const createCommand = new Command("create").alias("add").description("Create a n
|
|
|
165
178
|
process.exit(1);
|
|
166
179
|
}
|
|
167
180
|
console.log(pc.dim(`Creating worktree at ${worktreePath}...`));
|
|
168
|
-
createWorktree(
|
|
181
|
+
await createWorktree(
|
|
169
182
|
worktreePath,
|
|
170
183
|
branch,
|
|
171
184
|
{ newBranch: isNewBranch, baseBranch: currentBranch },
|
|
@@ -223,8 +236,8 @@ const createCommand = new Command("create").alias("add").description("Create a n
|
|
|
223
236
|
});
|
|
224
237
|
const listCommand = new Command("list").alias("ls").description("List all worktrees").option("--json", "Output in JSON format").action(async (options) => {
|
|
225
238
|
try {
|
|
226
|
-
const repoRoot = getRepoRoot();
|
|
227
|
-
const worktrees = listWorktrees(repoRoot);
|
|
239
|
+
const repoRoot = await getRepoRoot();
|
|
240
|
+
const worktrees = await listWorktrees(repoRoot);
|
|
228
241
|
if (options.json) {
|
|
229
242
|
console.log(JSON.stringify(worktrees, null, 2));
|
|
230
243
|
return;
|
|
@@ -252,8 +265,8 @@ const listCommand = new Command("list").alias("ls").description("List all worktr
|
|
|
252
265
|
});
|
|
253
266
|
const removeCommand = new Command("remove").alias("rm").description("Remove a worktree").argument("[path]", "Path to the worktree to remove").option("-f, --force", "Force removal even if worktree is dirty").option("-D, --delete-branch", "Also delete the branch").action(async (pathArg, options) => {
|
|
254
267
|
try {
|
|
255
|
-
const repoRoot = getRepoRoot();
|
|
256
|
-
const worktrees = listWorktrees(repoRoot);
|
|
268
|
+
const repoRoot = await getRepoRoot();
|
|
269
|
+
const worktrees = await listWorktrees(repoRoot);
|
|
257
270
|
const removableWorktrees = worktrees.filter((w) => !w.isMain);
|
|
258
271
|
if (removableWorktrees.length === 0) {
|
|
259
272
|
console.log(pc.yellow("No removable worktrees found"));
|
|
@@ -295,7 +308,7 @@ const removeCommand = new Command("remove").alias("rm").description("Remove a wo
|
|
|
295
308
|
return;
|
|
296
309
|
}
|
|
297
310
|
console.log(pc.dim("Removing worktree..."));
|
|
298
|
-
removeWorktree(targetWorktree.path, options.force, repoRoot);
|
|
311
|
+
await removeWorktree(targetWorktree.path, options.force, repoRoot);
|
|
299
312
|
console.log(pc.green(`✓ Removed worktree ${relativePath}`));
|
|
300
313
|
if (options.deleteBranch && targetWorktree.branch) {
|
|
301
314
|
const shouldDeleteBranch = await confirm({
|
|
@@ -304,7 +317,7 @@ const removeCommand = new Command("remove").alias("rm").description("Remove a wo
|
|
|
304
317
|
});
|
|
305
318
|
if (shouldDeleteBranch) {
|
|
306
319
|
try {
|
|
307
|
-
|
|
320
|
+
await deleteBranch(targetWorktree.branch, true, repoRoot);
|
|
308
321
|
console.log(pc.green(`✓ Deleted branch ${targetWorktree.branch}`));
|
|
309
322
|
} catch (error) {
|
|
310
323
|
if (error instanceof Error) {
|
|
@@ -341,10 +354,12 @@ const worktreePlugin = {
|
|
|
341
354
|
export {
|
|
342
355
|
branchExists,
|
|
343
356
|
createWorktree,
|
|
357
|
+
deleteBranch,
|
|
344
358
|
getCurrentBranch,
|
|
359
|
+
getGit,
|
|
345
360
|
getRepoRoot,
|
|
346
|
-
git,
|
|
347
361
|
isClean,
|
|
362
|
+
isWorktree,
|
|
348
363
|
listBranches,
|
|
349
364
|
listWorktrees,
|
|
350
365
|
removeWorktree,
|
package/dist/lib/git.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SimpleGit } from 'simple-git';
|
|
1
2
|
export interface Worktree {
|
|
2
3
|
path: string;
|
|
3
4
|
branch: string;
|
|
@@ -5,58 +6,51 @@ export interface Worktree {
|
|
|
5
6
|
isBare: boolean;
|
|
6
7
|
isMain: boolean;
|
|
7
8
|
}
|
|
8
|
-
export interface GitError extends Error {
|
|
9
|
-
stderr?: string;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Execute a git command and return stdout
|
|
13
|
-
*/
|
|
14
|
-
export declare function git(args: string[], cwd?: string): string;
|
|
15
9
|
/**
|
|
16
|
-
*
|
|
10
|
+
* Get a simple-git instance for the given directory
|
|
17
11
|
*/
|
|
18
|
-
export declare function
|
|
19
|
-
code: number;
|
|
20
|
-
stdout: string;
|
|
21
|
-
stderr: string;
|
|
22
|
-
}>;
|
|
12
|
+
export declare function getGit(cwd?: string): SimpleGit;
|
|
23
13
|
/**
|
|
24
14
|
* Get the root directory of the git repository
|
|
25
15
|
*/
|
|
26
|
-
export declare function getRepoRoot(cwd?: string): string
|
|
16
|
+
export declare function getRepoRoot(cwd?: string): Promise<string>;
|
|
27
17
|
/**
|
|
28
18
|
* Get the current branch name
|
|
29
19
|
*/
|
|
30
|
-
export declare function getCurrentBranch(cwd?: string): string
|
|
20
|
+
export declare function getCurrentBranch(cwd?: string): Promise<string>;
|
|
31
21
|
/**
|
|
32
22
|
* Check if working directory is clean
|
|
33
23
|
*/
|
|
34
|
-
export declare function isClean(cwd?: string): boolean
|
|
24
|
+
export declare function isClean(cwd?: string): Promise<boolean>;
|
|
35
25
|
/**
|
|
36
26
|
* List all worktrees
|
|
37
27
|
*/
|
|
38
|
-
export declare function listWorktrees(cwd?: string): Worktree[]
|
|
28
|
+
export declare function listWorktrees(cwd?: string): Promise<Worktree[]>;
|
|
39
29
|
/**
|
|
40
30
|
* Create a new worktree
|
|
41
31
|
*/
|
|
42
32
|
export declare function createWorktree(path: string, branch: string, options?: {
|
|
43
33
|
newBranch?: boolean;
|
|
44
34
|
baseBranch?: string;
|
|
45
|
-
}, cwd?: string): void
|
|
35
|
+
}, cwd?: string): Promise<void>;
|
|
46
36
|
/**
|
|
47
37
|
* Remove a worktree
|
|
48
38
|
*/
|
|
49
|
-
export declare function removeWorktree(path: string, force?: boolean, cwd?: string): void
|
|
39
|
+
export declare function removeWorktree(path: string, force?: boolean, cwd?: string): Promise<void>;
|
|
50
40
|
/**
|
|
51
41
|
* Get list of local branches
|
|
52
42
|
*/
|
|
53
|
-
export declare function listBranches(cwd?: string): string[]
|
|
43
|
+
export declare function listBranches(cwd?: string): Promise<string[]>;
|
|
54
44
|
/**
|
|
55
45
|
* Check if a branch exists
|
|
56
46
|
*/
|
|
57
|
-
export declare function branchExists(branch: string, cwd?: string): boolean
|
|
47
|
+
export declare function branchExists(branch: string, cwd?: string): Promise<boolean>;
|
|
48
|
+
/**
|
|
49
|
+
* Delete a branch
|
|
50
|
+
*/
|
|
51
|
+
export declare function deleteBranch(branch: string, force?: boolean, cwd?: string): Promise<void>;
|
|
58
52
|
/**
|
|
59
53
|
* Check if path is inside a git worktree
|
|
60
54
|
*/
|
|
61
|
-
export declare function isWorktree(path: string): boolean
|
|
55
|
+
export declare function isWorktree(path: string): Promise<boolean>;
|
|
62
56
|
//# sourceMappingURL=git.d.ts.map
|
package/dist/lib/git.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,SAAS,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAE9C;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG/D;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGpE;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAI5D;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAoCrE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,EACtD,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAef;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,OAAO,EACf,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAQf;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAIlE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,OAAO,EACf,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAOf;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAS/D"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lsst/pik-plugin-worktree",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Git worktree management plugin for pik CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -27,10 +27,11 @@
|
|
|
27
27
|
"!**/*.tsbuildinfo"
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@lsst/pik-core": "*",
|
|
31
30
|
"@inquirer/prompts": "^8.1.0",
|
|
31
|
+
"@lsst/pik-core": "*",
|
|
32
32
|
"commander": "^14.0.2",
|
|
33
33
|
"glob": "^10.5.0",
|
|
34
|
-
"picocolors": "^1.1.1"
|
|
34
|
+
"picocolors": "^1.1.1",
|
|
35
|
+
"simple-git": "^3.30.0"
|
|
35
36
|
}
|
|
36
37
|
}
|