@mcadam/worktree 1.0.0
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/LICENSE +21 -0
- package/README.md +315 -0
- package/bin/worktree.js +2 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +63 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/config.d.ts +2 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +110 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/create.d.ts +2 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +75 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +90 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +2 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +82 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/components/WorktreeList.d.ts +10 -0
- package/dist/components/WorktreeList.d.ts.map +1 -0
- package/dist/components/WorktreeList.js +41 -0
- package/dist/components/WorktreeList.js.map +1 -0
- package/dist/config/detector.d.ts +4 -0
- package/dist/config/detector.d.ts.map +1 -0
- package/dist/config/detector.js +34 -0
- package/dist/config/detector.js.map +1 -0
- package/dist/config/manager.d.ts +19 -0
- package/dist/config/manager.d.ts.map +1 -0
- package/dist/config/manager.js +73 -0
- package/dist/config/manager.js.map +1 -0
- package/dist/config/schema.d.ts +77 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +19 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/utils/gh.d.ts +13 -0
- package/dist/utils/gh.d.ts.map +1 -0
- package/dist/utils/gh.js +41 -0
- package/dist/utils/gh.js.map +1 -0
- package/dist/utils/git.d.ts +14 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +91 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/sanitize.d.ts +3 -0
- package/dist/utils/sanitize.d.ts.map +1 -0
- package/dist/utils/sanitize.js +13 -0
- package/dist/utils/sanitize.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { execa } from 'execa';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
export async function createWorktree(basePath, worktreeName, branchName, gitRoot) {
|
|
4
|
+
const worktreePath = path.join(basePath, worktreeName);
|
|
5
|
+
// Check if branch exists
|
|
6
|
+
try {
|
|
7
|
+
await execa('git', ['rev-parse', '--verify', branchName], { cwd: gitRoot });
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
// Branch doesn't exist locally, check remote
|
|
11
|
+
try {
|
|
12
|
+
await execa('git', ['fetch', 'origin', branchName], { cwd: gitRoot });
|
|
13
|
+
await execa('git', ['worktree', 'add', worktreePath, `origin/${branchName}`], { cwd: gitRoot });
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
// Create new branch
|
|
18
|
+
await execa('git', ['worktree', 'add', '-b', branchName, worktreePath], { cwd: gitRoot });
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// Branch exists locally
|
|
23
|
+
await execa('git', ['worktree', 'add', worktreePath, branchName], { cwd: gitRoot });
|
|
24
|
+
}
|
|
25
|
+
export async function listWorktrees(gitRoot) {
|
|
26
|
+
try {
|
|
27
|
+
const { stdout } = await execa('git', ['worktree', 'list', '--porcelain'], { cwd: gitRoot });
|
|
28
|
+
const worktrees = [];
|
|
29
|
+
const lines = stdout.split('\n');
|
|
30
|
+
let currentWorktree = {};
|
|
31
|
+
for (const line of lines) {
|
|
32
|
+
if (line.startsWith('worktree ')) {
|
|
33
|
+
if (currentWorktree.path) {
|
|
34
|
+
worktrees.push(currentWorktree);
|
|
35
|
+
}
|
|
36
|
+
currentWorktree = {
|
|
37
|
+
path: line.substring(9),
|
|
38
|
+
isMain: false,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
else if (line.startsWith('HEAD ')) {
|
|
42
|
+
currentWorktree.commit = line.substring(5);
|
|
43
|
+
}
|
|
44
|
+
else if (line.startsWith('branch ')) {
|
|
45
|
+
currentWorktree.branch = line.substring(7).replace('refs/heads/', '');
|
|
46
|
+
}
|
|
47
|
+
else if (line === 'bare') {
|
|
48
|
+
currentWorktree.isMain = true;
|
|
49
|
+
}
|
|
50
|
+
else if (line === '') {
|
|
51
|
+
if (currentWorktree.path) {
|
|
52
|
+
worktrees.push(currentWorktree);
|
|
53
|
+
currentWorktree = {};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (currentWorktree.path) {
|
|
58
|
+
worktrees.push(currentWorktree);
|
|
59
|
+
}
|
|
60
|
+
// Check if branches are pushed to remote
|
|
61
|
+
for (const worktree of worktrees) {
|
|
62
|
+
if (!worktree.branch || worktree.isMain)
|
|
63
|
+
continue;
|
|
64
|
+
try {
|
|
65
|
+
await execa('git', ['rev-parse', `origin/${worktree.branch}`], { cwd: gitRoot });
|
|
66
|
+
worktree.isPushed = true;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
worktree.isPushed = false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return worktrees;
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
console.error('Error listing worktrees:', error);
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export async function removeWorktree(worktreePath, gitRoot) {
|
|
80
|
+
await execa('git', ['worktree', 'remove', worktreePath, '--force'], { cwd: gitRoot });
|
|
81
|
+
}
|
|
82
|
+
export async function getAllBranches(gitRoot) {
|
|
83
|
+
try {
|
|
84
|
+
const { stdout } = await execa('git', ['branch', '-a', '--format=%(refname:short)'], { cwd: gitRoot });
|
|
85
|
+
return stdout.split('\n').filter(Boolean);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/utils/sanitize.ts"],"names":[],"mappings":"AAAA,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAOzD;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAGzE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function sanitizeBranchName(branch) {
|
|
2
|
+
// Replace common special characters with hyphens
|
|
3
|
+
return branch
|
|
4
|
+
.replace(/[\\/:\s*?"<>|]/g, '-') // Replace special chars with hyphen
|
|
5
|
+
.replace(/^-+|-+$/g, '') // Remove leading/trailing hyphens
|
|
6
|
+
.replace(/-{2,}/g, '-') // Replace multiple hyphens with single
|
|
7
|
+
.toLowerCase(); // Convert to lowercase for consistency
|
|
8
|
+
}
|
|
9
|
+
export function createWorktreeName(branch, prefix) {
|
|
10
|
+
const sanitized = sanitizeBranchName(branch);
|
|
11
|
+
return `${prefix}${sanitized}`;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=sanitize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../src/utils/sanitize.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,iDAAiD;IACjD,OAAO,MAAM;SACV,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC,oCAAoC;SACpE,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,kCAAkC;SAC1D,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,uCAAuC;SAC9D,WAAW,EAAE,CAAA,CAAC,uCAAuC;AAC1D,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAc,EAAE,MAAc;IAC/D,MAAM,SAAS,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAA;IAC5C,OAAO,GAAG,MAAM,GAAG,SAAS,EAAE,CAAA;AAChC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mcadam/worktree",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A CLI tool for managing Git worktrees across multiple repositories",
|
|
5
|
+
"main": "dist/cli.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"worktree": "./bin/worktree.js"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [
|
|
11
|
+
"git",
|
|
12
|
+
"worktree",
|
|
13
|
+
"cli",
|
|
14
|
+
"development",
|
|
15
|
+
"workflow"
|
|
16
|
+
],
|
|
17
|
+
"author": "",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/un/worktree.git"
|
|
22
|
+
},
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/un/worktree/issues"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://github.com/un/worktree#readme",
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"chalk": "^5.3.0",
|
|
32
|
+
"commander": "^11.1.0",
|
|
33
|
+
"execa": "^8.0.1",
|
|
34
|
+
"fs-extra": "^11.2.0",
|
|
35
|
+
"ink": "^5.2.1",
|
|
36
|
+
"ink-select-input": "^6.2.0",
|
|
37
|
+
"ink-spinner": "^5.0.0",
|
|
38
|
+
"ink-text-input": "^6.0.0",
|
|
39
|
+
"ora": "^7.0.1",
|
|
40
|
+
"react": "^18.2.0",
|
|
41
|
+
"zod": "^3.22.4"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@biomejs/biome": "^1.5.0",
|
|
45
|
+
"@types/fs-extra": "^11.0.4",
|
|
46
|
+
"@types/node": "^20.10.5",
|
|
47
|
+
"@types/react": "^18.2.45",
|
|
48
|
+
"tsx": "^4.7.0",
|
|
49
|
+
"typescript": "^5.3.3"
|
|
50
|
+
},
|
|
51
|
+
"engines": {
|
|
52
|
+
"node": ">=18.0.0"
|
|
53
|
+
},
|
|
54
|
+
"packageManager": "pnpm@8.12.0",
|
|
55
|
+
"files": [
|
|
56
|
+
"dist",
|
|
57
|
+
"bin"
|
|
58
|
+
],
|
|
59
|
+
"scripts": {
|
|
60
|
+
"build": "tsc",
|
|
61
|
+
"dev": "tsx watch src/cli.tsx",
|
|
62
|
+
"typecheck": "tsc --noEmit",
|
|
63
|
+
"clean": "rm -rf dist",
|
|
64
|
+
"lint": "biome check .",
|
|
65
|
+
"lint:fix": "biome check --apply .",
|
|
66
|
+
"format": "biome format --write ."
|
|
67
|
+
}
|
|
68
|
+
}
|