git-wtree 0.1.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 +94 -0
- package/dist/commands/add.d.ts +2 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +44 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/config.d.ts +4 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +36 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/ls.d.ts +2 -0
- package/dist/commands/ls.d.ts.map +1 -0
- package/dist/commands/ls.js +20 -0
- package/dist/commands/ls.js.map +1 -0
- package/dist/commands/open.d.ts +2 -0
- package/dist/commands/open.d.ts.map +1 -0
- package/dist/commands/open.js +27 -0
- package/dist/commands/open.js.map +1 -0
- package/dist/commands/rm.d.ts +2 -0
- package/dist/commands/rm.d.ts.map +1 -0
- package/dist/commands/rm.js +26 -0
- package/dist/commands/rm.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +48 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/config.d.ts +9 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +24 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/env.d.ts +2 -0
- package/dist/lib/env.d.ts.map +1 -0
- package/dist/lib/env.js +76 -0
- package/dist/lib/env.js.map +1 -0
- package/dist/lib/git.d.ts +15 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +89 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/ide.d.ts +3 -0
- package/dist/lib/ide.d.ts.map +1 -0
- package/dist/lib/ide.js +73 -0
- package/dist/lib/ide.js.map +1 -0
- package/dist/lib/packageManager.d.ts +5 -0
- package/dist/lib/packageManager.d.ts.map +1 -0
- package/dist/lib/packageManager.js +18 -0
- package/dist/lib/packageManager.js.map +1 -0
- package/package.json +46 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Lionel Giberné
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# git-wtree
|
|
2
|
+
|
|
3
|
+
> Git worktree manager with .env syncing and IDE integration
|
|
4
|
+
|
|
5
|
+
Streamline your git worktree workflow: create isolated branches, sync environment files, install dependencies, and open your IDE — all in one command.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g git-wtree
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
gitwtree <command>
|
|
17
|
+
# or
|
|
18
|
+
gwt <command>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Commands
|
|
22
|
+
|
|
23
|
+
| Command | Description |
|
|
24
|
+
| ----------------------------- | -------------------------------------------------------------- |
|
|
25
|
+
| `gwt add <branch>` | Create a worktree, sync `.env` files, and install dependencies |
|
|
26
|
+
| `gwt rm <branch>` | Remove a worktree |
|
|
27
|
+
| `gwt ls` | List all worktrees |
|
|
28
|
+
| `gwt open <branch>` | Open a worktree in your IDE |
|
|
29
|
+
| `gwt config` | Show current configuration |
|
|
30
|
+
| `gwt config ide` | Configure your IDE |
|
|
31
|
+
| `gwt config scan-dirs [dirs]` | Set directories to scan for `.env` files |
|
|
32
|
+
| `gwt help` | Show help |
|
|
33
|
+
|
|
34
|
+
### `gwt add <branch>`
|
|
35
|
+
|
|
36
|
+
Creates a git worktree for the given branch (creates the branch from `HEAD` if it doesn't exist), copies `.env` files from the main repo, and runs the package manager install.
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
gwt add my-feature
|
|
40
|
+
# Worktree created at ../myrepo-my-feature
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### `gwt open <branch>`
|
|
44
|
+
|
|
45
|
+
Opens the worktree in your configured IDE. On first use, a wizard will prompt you to choose your IDE.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
gwt open my-feature
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
To reconfigure your IDE at any time:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
gwt config ide
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### `.env` syncing
|
|
58
|
+
|
|
59
|
+
By default, `gwt add` recursively scans the repo for `.env*` files (excluding `node_modules`, `.git`, `dist`, etc.) and copies them into the new worktree.
|
|
60
|
+
|
|
61
|
+
To restrict scanning to specific directories:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
gwt config scan-dirs apps/api,apps/web
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
To reset back to auto scan:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
gwt config scan-dirs --reset
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Worktree location
|
|
74
|
+
|
|
75
|
+
Worktrees are created as siblings of your repo directory:
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
~/projects/
|
|
79
|
+
myrepo/ ← main repo
|
|
80
|
+
myrepo-my-feature ← worktree created by gwt
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Supported IDEs
|
|
84
|
+
|
|
85
|
+
VS Code, Cursor, Zed, WebStorm, IntelliJ IDEA, PyCharm, GoLand, Vim, Neovim, Sublime Text — or any custom IDE via the "Other" option in the wizard.
|
|
86
|
+
|
|
87
|
+
## Requirements
|
|
88
|
+
|
|
89
|
+
- Node.js >= 18
|
|
90
|
+
- Git >= 2.5
|
|
91
|
+
|
|
92
|
+
## License
|
|
93
|
+
|
|
94
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAWA,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAyC9D"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { intro, outro, log } from "@clack/prompts";
|
|
2
|
+
import { getRepoRoot, getWorktreePath, worktreeExists, addWorktree, } from "../lib/git.js";
|
|
3
|
+
import { copyEnvFiles } from "../lib/env.js";
|
|
4
|
+
import { installDeps, detectPackageManager } from "../lib/packageManager.js";
|
|
5
|
+
import { readConfig } from "../lib/config.js";
|
|
6
|
+
export async function commandAdd(branch) {
|
|
7
|
+
intro(`wtree add ${branch}`);
|
|
8
|
+
let root;
|
|
9
|
+
try {
|
|
10
|
+
root = getRepoRoot();
|
|
11
|
+
}
|
|
12
|
+
catch (e) {
|
|
13
|
+
log.error(e.message);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
const worktreePath = getWorktreePath(branch);
|
|
17
|
+
if (worktreeExists(worktreePath)) {
|
|
18
|
+
log.warn(`Worktree already exists at ${worktreePath}`);
|
|
19
|
+
outro("Done");
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
log.step("Creating git worktree…");
|
|
23
|
+
try {
|
|
24
|
+
addWorktree(worktreePath, branch);
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
log.error(e.message);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
log.step("Syncing .env files…");
|
|
31
|
+
const config = readConfig();
|
|
32
|
+
copyEnvFiles(root, worktreePath, config.scanDirs);
|
|
33
|
+
const pm = detectPackageManager(root);
|
|
34
|
+
log.step(`Installing dependencies with ${pm}…`);
|
|
35
|
+
try {
|
|
36
|
+
installDeps(worktreePath);
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
log.error(e.message);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
outro(`Worktree ready!\n Path: ${worktreePath}\n Branch: ${branch}`);
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=add.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EACL,WAAW,EACX,eAAe,EACf,cAAc,EACd,WAAW,GACZ,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAc;IAC7C,KAAK,CAAC,aAAa,MAAM,EAAE,CAAC,CAAC;IAE7B,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,WAAW,EAAE,CAAC;IACvB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,GAAG,CAAC,KAAK,CAAE,CAAW,CAAC,OAAO,CAAC,CAAC;QAChC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,YAAY,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IAE7C,IAAI,cAAc,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,GAAG,CAAC,IAAI,CAAC,8BAA8B,YAAY,EAAE,CAAC,CAAC;QACvD,KAAK,CAAC,MAAM,CAAC,CAAC;QACd,OAAO;IACT,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IACnC,IAAI,CAAC;QACH,WAAW,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,GAAG,CAAC,KAAK,CAAE,CAAW,CAAC,OAAO,CAAC,CAAC;QAChC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IAElD,MAAM,EAAE,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACtC,GAAG,CAAC,IAAI,CAAC,gCAAgC,EAAE,GAAG,CAAC,CAAC;IAChD,IAAI,CAAC;QACH,WAAW,CAAC,YAAY,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,GAAG,CAAC,KAAK,CAAE,CAAW,CAAC,OAAO,CAAC,CAAC;QAChC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,+BAA+B,YAAY,gBAAgB,MAAM,EAAE,CAAC,CAAC;AAC7E,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAIA,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAItD;AAED,wBAAgB,qBAAqB,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI,CAuB1E;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { intro, outro, log } from "@clack/prompts";
|
|
2
|
+
import { readConfig, updateConfig } from "../lib/config.js";
|
|
3
|
+
import { runIdeWizard } from "../lib/ide.js";
|
|
4
|
+
export async function commandConfigIde() {
|
|
5
|
+
intro("wtree config ide");
|
|
6
|
+
await runIdeWizard();
|
|
7
|
+
outro("Config saved");
|
|
8
|
+
}
|
|
9
|
+
export function commandConfigScanDirs(dirs, reset) {
|
|
10
|
+
if (reset) {
|
|
11
|
+
updateConfig({ scanDirs: null });
|
|
12
|
+
log.success("scan-dirs reset to auto (recursive scan)");
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (!dirs) {
|
|
16
|
+
const config = readConfig();
|
|
17
|
+
if (!config.scanDirs) {
|
|
18
|
+
console.log("scan-dirs: auto (recursive scan)");
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
console.log(`scan-dirs: ${config.scanDirs.join(", ")}`);
|
|
22
|
+
}
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const parsed = dirs
|
|
26
|
+
.split(",")
|
|
27
|
+
.map((d) => d.trim())
|
|
28
|
+
.filter(Boolean);
|
|
29
|
+
updateConfig({ scanDirs: parsed });
|
|
30
|
+
log.success(`scan-dirs set to: ${parsed.join(", ")}`);
|
|
31
|
+
}
|
|
32
|
+
export function commandConfigShow() {
|
|
33
|
+
const config = readConfig();
|
|
34
|
+
console.log(JSON.stringify(config, null, 2));
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAC1B,MAAM,YAAY,EAAE,CAAC;IACrB,KAAK,CAAC,cAAc,CAAC,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IAAa,EAAE,KAAe;IAClE,IAAI,KAAK,EAAE,CAAC;QACV,YAAY,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACjC,GAAG,CAAC,OAAO,CAAC,0CAA0C,CAAC,CAAC;QACxD,OAAO;IACT,CAAC;IAED,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;QAClD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC1D,CAAC;QACD,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAI;SAChB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CAAC;IACnB,YAAY,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IACnC,GAAG,CAAC,OAAO,CAAC,qBAAqB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ls.d.ts","sourceRoot":"","sources":["../../src/commands/ls.ts"],"names":[],"mappings":"AAGA,wBAAgB,SAAS,IAAI,IAAI,CAgBhC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import pc from "picocolors";
|
|
2
|
+
import { listWorktrees } from "../lib/git.js";
|
|
3
|
+
export function commandLs() {
|
|
4
|
+
let worktrees;
|
|
5
|
+
try {
|
|
6
|
+
worktrees = listWorktrees();
|
|
7
|
+
}
|
|
8
|
+
catch (e) {
|
|
9
|
+
console.error(pc.red(e.message));
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
console.log("");
|
|
13
|
+
for (const wt of worktrees) {
|
|
14
|
+
const tag = wt.isMain ? ` ${pc.green("(main)")}` : "";
|
|
15
|
+
console.log(` ${pc.bold(pc.cyan(wt.branch))}${tag}`);
|
|
16
|
+
console.log(` ${pc.dim(wt.path)}`);
|
|
17
|
+
console.log("");
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=ls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ls.js","sourceRoot":"","sources":["../../src/commands/ls.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,UAAU,SAAS;IACvB,IAAI,SAAS,CAAC;IACd,IAAI,CAAC;QACH,SAAS,GAAG,aAAa,EAAE,CAAC;IAC9B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAE,CAAW,CAAC,OAAO,CAAC,CAAC,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../../src/commands/open.ts"],"names":[],"mappings":"AAKA,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0B/D"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { intro, outro, log } from "@clack/prompts";
|
|
2
|
+
import { getWorktreePath, worktreeExists } from "../lib/git.js";
|
|
3
|
+
import { readConfig } from "../lib/config.js";
|
|
4
|
+
import { runIdeWizard, openInIde } from "../lib/ide.js";
|
|
5
|
+
export async function commandOpen(branch) {
|
|
6
|
+
intro(`wtree open ${branch}`);
|
|
7
|
+
let worktreePath;
|
|
8
|
+
try {
|
|
9
|
+
worktreePath = getWorktreePath(branch);
|
|
10
|
+
}
|
|
11
|
+
catch (e) {
|
|
12
|
+
log.error(e.message);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
if (!worktreeExists(worktreePath)) {
|
|
16
|
+
log.error(`No worktree found for branch '${branch}'\nRun: wtree add ${branch}`);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
const config = readConfig();
|
|
20
|
+
if (!config.ide) {
|
|
21
|
+
log.info("No IDE configured yet. Let's set that up:");
|
|
22
|
+
await runIdeWizard();
|
|
23
|
+
}
|
|
24
|
+
openInIde(worktreePath);
|
|
25
|
+
outro(`Opened ${worktreePath}`);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=open.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open.js","sourceRoot":"","sources":["../../src/commands/open.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAExD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAc;IAC9C,KAAK,CAAC,cAAc,MAAM,EAAE,CAAC,CAAC;IAE9B,IAAI,YAAoB,CAAC;IACzB,IAAI,CAAC;QACH,YAAY,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,GAAG,CAAC,KAAK,CAAE,CAAW,CAAC,OAAO,CAAC,CAAC;QAChC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,EAAE,CAAC;QAClC,GAAG,CAAC,KAAK,CACP,iCAAiC,MAAM,qBAAqB,MAAM,EAAE,CACrE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAChB,GAAG,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;QACtD,MAAM,YAAY,EAAE,CAAC;IACvB,CAAC;IAED,SAAS,CAAC,YAAY,CAAC,CAAC;IACxB,KAAK,CAAC,UAAU,YAAY,EAAE,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rm.d.ts","sourceRoot":"","sources":["../../src/commands/rm.ts"],"names":[],"mappings":"AAGA,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA6B7D"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { intro, outro, confirm, log, isCancel, cancel } from "@clack/prompts";
|
|
2
|
+
import { getWorktreePath, worktreeExists, removeWorktree } from "../lib/git.js";
|
|
3
|
+
export async function commandRm(branch) {
|
|
4
|
+
intro(`wtree rm ${branch}`);
|
|
5
|
+
const worktreePath = getWorktreePath(branch);
|
|
6
|
+
if (!worktreeExists(worktreePath)) {
|
|
7
|
+
log.error(`No worktree found for branch '${branch}'\nExpected at: ${worktreePath}`);
|
|
8
|
+
process.exit(1);
|
|
9
|
+
}
|
|
10
|
+
const confirmed = await confirm({
|
|
11
|
+
message: `Remove worktree at ${worktreePath}?`,
|
|
12
|
+
});
|
|
13
|
+
if (isCancel(confirmed) || !confirmed) {
|
|
14
|
+
cancel("Cancelled");
|
|
15
|
+
process.exit(0);
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
removeWorktree(worktreePath);
|
|
19
|
+
}
|
|
20
|
+
catch (e) {
|
|
21
|
+
log.error(e.message);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
outro(`Worktree '${branch}' removed`);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=rm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rm.js","sourceRoot":"","sources":["../../src/commands/rm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEhF,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAAc;IAC5C,KAAK,CAAC,YAAY,MAAM,EAAE,CAAC,CAAC;IAE5B,MAAM,YAAY,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IAE7C,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,EAAE,CAAC;QAClC,GAAG,CAAC,KAAK,CACP,iCAAiC,MAAM,mBAAmB,YAAY,EAAE,CACzE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC;QAC9B,OAAO,EAAE,sBAAsB,YAAY,GAAG;KAC/C,CAAC,CAAC;IAEH,IAAI,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QACtC,MAAM,CAAC,WAAW,CAAC,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,cAAc,CAAC,YAAY,CAAC,CAAC;IAC/B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,GAAG,CAAC,KAAK,CAAE,CAAW,CAAC,OAAO,CAAC,CAAC;QAChC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,aAAa,MAAM,WAAW,CAAC,CAAC;AACxC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { commandAdd } from "./commands/add.js";
|
|
4
|
+
import { commandRm } from "./commands/rm.js";
|
|
5
|
+
import { commandLs } from "./commands/ls.js";
|
|
6
|
+
import { commandOpen } from "./commands/open.js";
|
|
7
|
+
import { commandConfigIde, commandConfigScanDirs, commandConfigShow, } from "./commands/config.js";
|
|
8
|
+
const program = new Command();
|
|
9
|
+
program
|
|
10
|
+
.name("gitwtree")
|
|
11
|
+
.description("Git worktree manager with .env syncing and IDE integration")
|
|
12
|
+
.version("0.1.0")
|
|
13
|
+
.addHelpText("after", "\nAlias: gwt <command>\n\nExamples:\n gwt add my-feature\n gwt open my-feature\n gwt rm my-feature\n gwt config ide");
|
|
14
|
+
program
|
|
15
|
+
.command("add <branch>")
|
|
16
|
+
.description("Create a worktree, sync .env files, and install dependencies")
|
|
17
|
+
.action(commandAdd);
|
|
18
|
+
program
|
|
19
|
+
.command("rm <branch>")
|
|
20
|
+
.description("Remove a worktree")
|
|
21
|
+
.action(commandRm);
|
|
22
|
+
program.command("ls").description("List all worktrees").action(commandLs);
|
|
23
|
+
program
|
|
24
|
+
.command("open <branch>")
|
|
25
|
+
.description("Open a worktree in your IDE")
|
|
26
|
+
.action(commandOpen);
|
|
27
|
+
const configCmd = program
|
|
28
|
+
.command("config")
|
|
29
|
+
.description("Manage git-wtree configuration")
|
|
30
|
+
.action(commandConfigShow);
|
|
31
|
+
configCmd
|
|
32
|
+
.command("ide")
|
|
33
|
+
.description("Configure your IDE")
|
|
34
|
+
.action(commandConfigIde);
|
|
35
|
+
configCmd
|
|
36
|
+
.command("scan-dirs [dirs]")
|
|
37
|
+
.description("Set directories to scan for .env files (comma-separated). Omit to show current value.")
|
|
38
|
+
.option("--reset", "Reset to auto recursive scan")
|
|
39
|
+
.action((dirs, options) => commandConfigScanDirs(dirs, options.reset));
|
|
40
|
+
// Show help when called with no arguments
|
|
41
|
+
if (process.argv.length <= 2) {
|
|
42
|
+
program.help();
|
|
43
|
+
}
|
|
44
|
+
program.parseAsync(process.argv).catch((e) => {
|
|
45
|
+
console.error(e.message);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
});
|
|
48
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,4DAA4D,CAAC;KACzE,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CACV,OAAO,EACP,yHAAyH,CAC1H,CAAC;AAEJ,OAAO;KACJ,OAAO,CAAC,cAAc,CAAC;KACvB,WAAW,CAAC,8DAA8D,CAAC;KAC3E,MAAM,CAAC,UAAU,CAAC,CAAC;AAEtB,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,mBAAmB,CAAC;KAChC,MAAM,CAAC,SAAS,CAAC,CAAC;AAErB,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,oBAAoB,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AAE1E,OAAO;KACJ,OAAO,CAAC,eAAe,CAAC;KACxB,WAAW,CAAC,6BAA6B,CAAC;KAC1C,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,MAAM,SAAS,GAAG,OAAO;KACtB,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,gCAAgC,CAAC;KAC7C,MAAM,CAAC,iBAAiB,CAAC,CAAC;AAE7B,SAAS;KACN,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,oBAAoB,CAAC;KACjC,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAE5B,SAAS;KACN,OAAO,CAAC,kBAAkB,CAAC;KAC3B,WAAW,CACV,uFAAuF,CACxF;KACA,MAAM,CAAC,SAAS,EAAE,8BAA8B,CAAC;KACjD,MAAM,CAAC,CAAC,IAAwB,EAAE,OAA4B,EAAE,EAAE,CACjE,qBAAqB,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,CAC3C,CAAC;AAEJ,0CAA0C;AAC1C,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;IAC7B,OAAO,CAAC,IAAI,EAAE,CAAC;AACjB,CAAC;AAED,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAU,EAAE,EAAE;IACpD,OAAO,CAAC,KAAK,CAAE,CAAW,CAAC,OAAO,CAAC,CAAC;IACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface WtreeConfig {
|
|
2
|
+
ide?: string;
|
|
3
|
+
ideCommand?: string;
|
|
4
|
+
scanDirs?: string[] | null;
|
|
5
|
+
}
|
|
6
|
+
export declare function readConfig(): WtreeConfig;
|
|
7
|
+
export declare function writeConfig(config: WtreeConfig): void;
|
|
8
|
+
export declare function updateConfig(patch: Partial<WtreeConfig>): void;
|
|
9
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;CAC5B;AAKD,wBAAgB,UAAU,IAAI,WAAW,CAOxC;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAGrD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,CAG9D"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import os from "os";
|
|
4
|
+
const CONFIG_DIR = path.join(os.homedir(), ".config", "wtree");
|
|
5
|
+
const CONFIG_PATH = path.join(CONFIG_DIR, "config.json");
|
|
6
|
+
export function readConfig() {
|
|
7
|
+
if (!fs.existsSync(CONFIG_PATH))
|
|
8
|
+
return {};
|
|
9
|
+
try {
|
|
10
|
+
return JSON.parse(fs.readFileSync(CONFIG_PATH, "utf-8"));
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return {};
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function writeConfig(config) {
|
|
17
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
18
|
+
fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));
|
|
19
|
+
}
|
|
20
|
+
export function updateConfig(patch) {
|
|
21
|
+
const current = readConfig();
|
|
22
|
+
writeConfig({ ...current, ...patch });
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAQpB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAC/D,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEzD,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,EAAE,CAAC;IAC3C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAgB,CAAC;IAC1E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAmB;IAC7C,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAA2B;IACtD,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,WAAW,CAAC,EAAE,GAAG,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/lib/env.ts"],"names":[],"mappings":"AAgEA,wBAAgB,YAAY,CAC1B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,GACzB,IAAI,CAoBN"}
|
package/dist/lib/env.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { log } from "@clack/prompts";
|
|
4
|
+
const EXCLUDED_DIRS = new Set([
|
|
5
|
+
"node_modules",
|
|
6
|
+
".git",
|
|
7
|
+
"dist",
|
|
8
|
+
"build",
|
|
9
|
+
".nx",
|
|
10
|
+
".cache",
|
|
11
|
+
".next",
|
|
12
|
+
".turbo",
|
|
13
|
+
"coverage",
|
|
14
|
+
]);
|
|
15
|
+
const ENV_PATTERN = /^\.env/;
|
|
16
|
+
const EXCLUDED_FILES = new Set([
|
|
17
|
+
".env.test",
|
|
18
|
+
".env.example",
|
|
19
|
+
".env.tpl",
|
|
20
|
+
".env.template",
|
|
21
|
+
".env.sample",
|
|
22
|
+
]);
|
|
23
|
+
function scanDir(dir, results) {
|
|
24
|
+
let entries;
|
|
25
|
+
try {
|
|
26
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
for (const entry of entries) {
|
|
32
|
+
if (entry.isDirectory() && !EXCLUDED_DIRS.has(entry.name)) {
|
|
33
|
+
scanDir(path.join(dir, entry.name), results);
|
|
34
|
+
}
|
|
35
|
+
else if (entry.isFile() &&
|
|
36
|
+
ENV_PATTERN.test(entry.name) &&
|
|
37
|
+
!EXCLUDED_FILES.has(entry.name)) {
|
|
38
|
+
results.push(path.join(dir, entry.name));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function findEnvFiles(root, scanDirs) {
|
|
43
|
+
const files = [];
|
|
44
|
+
if (scanDirs && scanDirs.length > 0) {
|
|
45
|
+
for (const dir of scanDirs) {
|
|
46
|
+
const fullDir = path.join(root, dir);
|
|
47
|
+
if (fs.existsSync(fullDir)) {
|
|
48
|
+
scanDir(fullDir, files);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
scanDir(root, files);
|
|
54
|
+
}
|
|
55
|
+
return files;
|
|
56
|
+
}
|
|
57
|
+
export function copyEnvFiles(sourceRoot, destRoot, scanDirs) {
|
|
58
|
+
const files = findEnvFiles(sourceRoot, scanDirs);
|
|
59
|
+
let copied = 0;
|
|
60
|
+
for (const src of files) {
|
|
61
|
+
const relative = path.relative(sourceRoot, src);
|
|
62
|
+
const dest = path.join(destRoot, relative);
|
|
63
|
+
const destDir = path.dirname(dest);
|
|
64
|
+
if (!fs.existsSync(destDir))
|
|
65
|
+
continue;
|
|
66
|
+
fs.copyFileSync(src, dest);
|
|
67
|
+
copied++;
|
|
68
|
+
}
|
|
69
|
+
if (copied > 0) {
|
|
70
|
+
log.success(`Copied ${copied} .env file${copied !== 1 ? "s" : ""}`);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
log.info("No .env files found to copy");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/lib/env.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface WorktreeEntry {
|
|
2
|
+
path: string;
|
|
3
|
+
branch: string;
|
|
4
|
+
isMain: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function getRepoRoot(): string;
|
|
7
|
+
export declare function getRepoName(root: string): string;
|
|
8
|
+
export declare function sanitizeBranch(branch: string): string;
|
|
9
|
+
export declare function getWorktreePath(branch: string): string;
|
|
10
|
+
export declare function branchExists(branch: string): boolean;
|
|
11
|
+
export declare function worktreeExists(worktreePath: string): boolean;
|
|
12
|
+
export declare function addWorktree(worktreePath: string, branch: string): void;
|
|
13
|
+
export declare function removeWorktree(worktreePath: string): void;
|
|
14
|
+
export declare function listWorktrees(): WorktreeEntry[];
|
|
15
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,wBAAgB,WAAW,IAAI,MAAM,CAQpC;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKtD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CASpD;AAED,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAatE;AAED,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAOzD;AAED,wBAAgB,aAAa,IAAI,aAAa,EAAE,CA8B/C"}
|
package/dist/lib/git.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { execSync } from "child_process";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
export function getRepoRoot() {
|
|
5
|
+
try {
|
|
6
|
+
return execSync("git rev-parse --show-toplevel", {
|
|
7
|
+
encoding: "utf-8",
|
|
8
|
+
}).trim();
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
throw new Error("Not inside a git repository");
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export function getRepoName(root) {
|
|
15
|
+
return path.basename(root);
|
|
16
|
+
}
|
|
17
|
+
export function sanitizeBranch(branch) {
|
|
18
|
+
return branch.replace(/\//g, "-");
|
|
19
|
+
}
|
|
20
|
+
export function getWorktreePath(branch) {
|
|
21
|
+
const root = getRepoRoot();
|
|
22
|
+
const repoName = getRepoName(root);
|
|
23
|
+
const sanitized = sanitizeBranch(branch);
|
|
24
|
+
return path.resolve(root, "..", `${repoName}-${sanitized}`);
|
|
25
|
+
}
|
|
26
|
+
export function branchExists(branch) {
|
|
27
|
+
try {
|
|
28
|
+
execSync(`git show-ref --verify --quiet refs/heads/${branch}`, {
|
|
29
|
+
stdio: "ignore",
|
|
30
|
+
});
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export function worktreeExists(worktreePath) {
|
|
38
|
+
return fs.existsSync(worktreePath);
|
|
39
|
+
}
|
|
40
|
+
export function addWorktree(worktreePath, branch) {
|
|
41
|
+
const root = getRepoRoot();
|
|
42
|
+
if (branchExists(branch)) {
|
|
43
|
+
execSync(`git worktree add "${worktreePath}" "${branch}"`, {
|
|
44
|
+
cwd: root,
|
|
45
|
+
stdio: "inherit",
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
execSync(`git worktree add "${worktreePath}" -b "${branch}"`, {
|
|
50
|
+
cwd: root,
|
|
51
|
+
stdio: "inherit",
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export function removeWorktree(worktreePath) {
|
|
56
|
+
const root = getRepoRoot();
|
|
57
|
+
execSync(`git worktree remove "${worktreePath}" --force`, {
|
|
58
|
+
cwd: root,
|
|
59
|
+
stdio: "inherit",
|
|
60
|
+
});
|
|
61
|
+
execSync("git worktree prune", { cwd: root, stdio: "inherit" });
|
|
62
|
+
}
|
|
63
|
+
export function listWorktrees() {
|
|
64
|
+
const root = getRepoRoot();
|
|
65
|
+
const output = execSync("git worktree list --porcelain", {
|
|
66
|
+
cwd: root,
|
|
67
|
+
encoding: "utf-8",
|
|
68
|
+
});
|
|
69
|
+
const entries = [];
|
|
70
|
+
const blocks = output.trim().split("\n\n");
|
|
71
|
+
for (const block of blocks) {
|
|
72
|
+
const lines = block.split("\n");
|
|
73
|
+
const worktreeLine = lines.find((l) => l.startsWith("worktree "));
|
|
74
|
+
const branchLine = lines.find((l) => l.startsWith("branch "));
|
|
75
|
+
if (!worktreeLine)
|
|
76
|
+
continue;
|
|
77
|
+
const wtPath = worktreeLine.replace("worktree ", "");
|
|
78
|
+
const branch = branchLine
|
|
79
|
+
? branchLine.replace("branch refs/heads/", "")
|
|
80
|
+
: "(detached)";
|
|
81
|
+
entries.push({
|
|
82
|
+
path: wtPath,
|
|
83
|
+
branch,
|
|
84
|
+
isMain: wtPath === root,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return entries;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ide.d.ts","sourceRoot":"","sources":["../../src/lib/ide.ts"],"names":[],"mappings":"AAwBA,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAyDlD;AAED,wBAAgB,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAUpD"}
|
package/dist/lib/ide.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { select, text, isCancel, cancel, log } from "@clack/prompts";
|
|
2
|
+
import { execSync } from "child_process";
|
|
3
|
+
import { readConfig, updateConfig } from "./config.js";
|
|
4
|
+
const KNOWN_IDES = [
|
|
5
|
+
{ label: "VS Code", value: "vscode", command: "code --new-window {path}" },
|
|
6
|
+
{ label: "Cursor", value: "cursor", command: "cursor --new-window {path}" },
|
|
7
|
+
{ label: "Zed", value: "zed", command: "zed {path}" },
|
|
8
|
+
{ label: "WebStorm", value: "webstorm", command: "webstorm {path}" },
|
|
9
|
+
{ label: "IntelliJ IDEA", value: "idea", command: "idea {path}" },
|
|
10
|
+
{ label: "PyCharm", value: "pycharm", command: "pycharm {path}" },
|
|
11
|
+
{ label: "GoLand", value: "goland", command: "goland {path}" },
|
|
12
|
+
{ label: "Vim", value: "vim", command: null },
|
|
13
|
+
{ label: "Neovim", value: "nvim", command: null },
|
|
14
|
+
{ label: "Sublime Text", value: "sublime", command: "subl {path}" },
|
|
15
|
+
{ label: "Other…", value: "other", command: null },
|
|
16
|
+
];
|
|
17
|
+
export async function runIdeWizard() {
|
|
18
|
+
const selected = await select({
|
|
19
|
+
message: "Which IDE do you use?",
|
|
20
|
+
options: KNOWN_IDES.map((ide) => ({ label: ide.label, value: ide.value })),
|
|
21
|
+
});
|
|
22
|
+
if (isCancel(selected)) {
|
|
23
|
+
cancel("IDE setup cancelled");
|
|
24
|
+
process.exit(0);
|
|
25
|
+
}
|
|
26
|
+
if (selected === "other") {
|
|
27
|
+
const ideName = await text({
|
|
28
|
+
message: "IDE name:",
|
|
29
|
+
placeholder: "Sublime Text",
|
|
30
|
+
validate: (v) => (v.trim() ? undefined : "Name is required"),
|
|
31
|
+
});
|
|
32
|
+
if (isCancel(ideName)) {
|
|
33
|
+
cancel("IDE setup cancelled");
|
|
34
|
+
process.exit(0);
|
|
35
|
+
}
|
|
36
|
+
const ideCommand = await text({
|
|
37
|
+
message: "Command to open a folder (use {path} as placeholder):",
|
|
38
|
+
placeholder: "subl {path}",
|
|
39
|
+
validate: (v) => v.trim()
|
|
40
|
+
? v.includes("{path}")
|
|
41
|
+
? undefined
|
|
42
|
+
: "Command must include {path}"
|
|
43
|
+
: "Command is required",
|
|
44
|
+
});
|
|
45
|
+
if (isCancel(ideCommand)) {
|
|
46
|
+
cancel("IDE setup cancelled");
|
|
47
|
+
process.exit(0);
|
|
48
|
+
}
|
|
49
|
+
updateConfig({ ide: ideName, ideCommand: ideCommand });
|
|
50
|
+
log.success(`IDE configured: ${ideName}`);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const found = KNOWN_IDES.find((ide) => ide.value === selected);
|
|
54
|
+
if (!found)
|
|
55
|
+
return;
|
|
56
|
+
if (!found.command) {
|
|
57
|
+
updateConfig({ ide: selected, ideCommand: undefined });
|
|
58
|
+
log.info(`IDE set to ${found.label}. Terminal-based IDEs won't be auto-opened.\nUse "cd $(wtree path <branch>)" to navigate to the worktree.`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
updateConfig({ ide: selected, ideCommand: found.command });
|
|
62
|
+
log.success(`IDE configured: ${found.label}`);
|
|
63
|
+
}
|
|
64
|
+
export function openInIde(worktreePath) {
|
|
65
|
+
const config = readConfig();
|
|
66
|
+
if (!config.ideCommand) {
|
|
67
|
+
log.info(`Worktree path: ${worktreePath}`);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const cmd = config.ideCommand.replace("{path}", `"${worktreePath}"`);
|
|
71
|
+
execSync(cmd, { stdio: "ignore" });
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=ide.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ide.js","sourceRoot":"","sources":["../../src/lib/ide.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"packageManager.d.ts","sourceRoot":"","sources":["../../src/lib/packageManager.ts"],"names":[],"mappings":"AAIA,KAAK,cAAc,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;AAEtD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAKjE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAI9C"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { execSync } from "child_process";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
export function detectPackageManager(root) {
|
|
5
|
+
if (fs.existsSync(path.join(root, "bun.lockb")))
|
|
6
|
+
return "bun";
|
|
7
|
+
if (fs.existsSync(path.join(root, "pnpm-lock.yaml")))
|
|
8
|
+
return "pnpm";
|
|
9
|
+
if (fs.existsSync(path.join(root, "yarn.lock")))
|
|
10
|
+
return "yarn";
|
|
11
|
+
return "npm";
|
|
12
|
+
}
|
|
13
|
+
export function installDeps(root) {
|
|
14
|
+
const pm = detectPackageManager(root);
|
|
15
|
+
const cmd = `${pm} install`;
|
|
16
|
+
execSync(cmd, { cwd: root, stdio: "inherit" });
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=packageManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"packageManager.js","sourceRoot":"","sources":["../../src/lib/packageManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAIxB,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9D,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IACpE,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IAC/D,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,EAAE,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,GAAG,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;AACjD,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "git-wtree",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Git worktree manager with .env syncing and IDE integration",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"gitwtree": "./dist/index.js",
|
|
8
|
+
"gwt": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "tsc --watch",
|
|
13
|
+
"postbuild": "chmod +x dist/index.js",
|
|
14
|
+
"prepublishOnly": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"LICENSE",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@clack/prompts": "^0.9.0",
|
|
23
|
+
"commander": "^12.0.0",
|
|
24
|
+
"picocolors": "^1.1.0"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/node": "^22.0.0",
|
|
28
|
+
"typescript": "^5.5.0"
|
|
29
|
+
},
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=18.0.0"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"git",
|
|
35
|
+
"worktree",
|
|
36
|
+
"cli",
|
|
37
|
+
"ide",
|
|
38
|
+
"dev-tools"
|
|
39
|
+
],
|
|
40
|
+
"author": "Lionel Giberné",
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "git+https://github.com/liogi/git-wtree.git"
|
|
45
|
+
}
|
|
46
|
+
}
|