@gw-tools/gw 0.6.1 → 0.9.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/README.md +92 -10
- package/install.js +33 -0
- package/package.json +4 -2
- package/uninstall.js +50 -0
package/README.md
CHANGED
|
@@ -21,17 +21,24 @@ A command-line tool for managing git worktrees, built with Deno.
|
|
|
21
21
|
- [Options](#options)
|
|
22
22
|
- [Examples](#examples)
|
|
23
23
|
- [Auto-Copy Configuration](#auto-copy-configuration)
|
|
24
|
-
- [
|
|
24
|
+
- [cd](#cd)
|
|
25
|
+
- [Arguments](#arguments-1)
|
|
25
26
|
- [Examples](#examples-1)
|
|
26
27
|
- [How It Works](#how-it-works)
|
|
27
|
-
- [
|
|
28
|
+
- [install-shell](#install-shell)
|
|
28
29
|
- [Options](#options-1)
|
|
29
30
|
- [Examples](#examples-2)
|
|
31
|
+
- [root](#root)
|
|
32
|
+
- [Examples](#examples-3)
|
|
33
|
+
- [How It Works](#how-it-works-1)
|
|
34
|
+
- [init](#init)
|
|
35
|
+
- [Options](#options-2)
|
|
36
|
+
- [Examples](#examples-4)
|
|
30
37
|
- [When to Use](#when-to-use)
|
|
31
38
|
- [sync](#sync)
|
|
32
|
-
- [Arguments](#arguments-
|
|
33
|
-
- [Options](#options-
|
|
34
|
-
- [Examples](#examples-
|
|
39
|
+
- [Arguments](#arguments-2)
|
|
40
|
+
- [Options](#options-3)
|
|
41
|
+
- [Examples](#examples-5)
|
|
35
42
|
- [Git Worktree Proxy Commands](#git-worktree-proxy-commands)
|
|
36
43
|
- [list (ls)](#list-ls)
|
|
37
44
|
- [remove (rm)](#remove-rm)
|
|
@@ -68,8 +75,8 @@ npm install -g @gw-tools/gw
|
|
|
68
75
|
# Create a new worktree and copy files
|
|
69
76
|
gw add feat-new-feature .env secrets/
|
|
70
77
|
|
|
71
|
-
#
|
|
72
|
-
cd feat-new-feature
|
|
78
|
+
# Navigate to your new worktree
|
|
79
|
+
gw cd feat-new-feature
|
|
73
80
|
```
|
|
74
81
|
|
|
75
82
|
**Or with auto-copy (one-time setup):**
|
|
@@ -80,12 +87,14 @@ gw init --root $(gw root) --auto-copy-files .env,secrets/
|
|
|
80
87
|
|
|
81
88
|
# Now just create worktrees - files are copied automatically
|
|
82
89
|
gw add feat-another-feature
|
|
83
|
-
cd feat-another-feature
|
|
90
|
+
gw cd feat-another-feature
|
|
84
91
|
```
|
|
85
92
|
|
|
86
93
|
## Features
|
|
87
94
|
|
|
95
|
+
- **Quick navigation**: Navigate to worktrees instantly with smart partial matching (`gw cd feat` finds `feat-branch`)
|
|
88
96
|
- **Copy files between worktrees**: Easily copy secrets, environment files, and configurations from one worktree to another
|
|
97
|
+
- **Automatic shell integration**: Shell function installs automatically on npm install for seamless `gw cd` navigation
|
|
89
98
|
- **Multi-command architecture**: Extensible framework for adding new worktree management commands
|
|
90
99
|
- **Auto-configured per repository**: Each repository gets its own local config file, automatically created on first use
|
|
91
100
|
- **Dry-run mode**: Preview what would be copied without making changes
|
|
@@ -226,6 +235,78 @@ This creates:
|
|
|
226
235
|
|
|
227
236
|
Now every time you run `gw add`, these files will be automatically copied from your default source worktree (usually `main`) to the new worktree.
|
|
228
237
|
|
|
238
|
+
### cd
|
|
239
|
+
|
|
240
|
+
Navigate directly to a worktree by name or partial match. The command uses smart matching to find worktrees, searching both branch names and worktree paths.
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
gw cd <worktree>
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
#### Arguments
|
|
247
|
+
|
|
248
|
+
- `<worktree>`: Name or partial name of the worktree (matches branch name or path)
|
|
249
|
+
|
|
250
|
+
#### Examples
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
# Navigate to a worktree by exact name
|
|
254
|
+
gw cd feat-branch
|
|
255
|
+
|
|
256
|
+
# Navigate using partial match (finds "feat-new-feature")
|
|
257
|
+
gw cd feat
|
|
258
|
+
|
|
259
|
+
# If multiple matches found, shows list with helpful error:
|
|
260
|
+
gw cd api
|
|
261
|
+
# Output: Multiple worktrees match "api":
|
|
262
|
+
# api-refactor -> /path/to/repo/api-refactor
|
|
263
|
+
# graphql-api -> /path/to/repo/graphql-api
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
#### How It Works
|
|
267
|
+
|
|
268
|
+
The `cd` command integrates with your shell through an automatically installed function (see [install-shell](#install-shell)). When you run `gw cd <worktree>`:
|
|
269
|
+
|
|
270
|
+
1. The command finds the matching worktree path
|
|
271
|
+
2. The shell function intercepts the call and navigates you there
|
|
272
|
+
3. All other `gw` commands pass through normally
|
|
273
|
+
|
|
274
|
+
**Note**: Shell integration is automatically installed when you install via npm. If needed, you can manually install or remove it using `gw install-shell`.
|
|
275
|
+
|
|
276
|
+
### install-shell
|
|
277
|
+
|
|
278
|
+
Install or remove shell integration for the `gw cd` command. This is automatically run during `npm install`, but can be run manually if needed.
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
gw install-shell [options]
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
#### Options
|
|
285
|
+
|
|
286
|
+
- `--remove`: Remove shell integration
|
|
287
|
+
- `--quiet, -q`: Suppress output messages
|
|
288
|
+
- `-h, --help`: Show help message
|
|
289
|
+
|
|
290
|
+
#### Examples
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
# Install shell integration (usually not needed - auto-installed)
|
|
294
|
+
gw install-shell
|
|
295
|
+
|
|
296
|
+
# Remove shell integration
|
|
297
|
+
gw install-shell --remove
|
|
298
|
+
|
|
299
|
+
# Install quietly (for automation)
|
|
300
|
+
gw install-shell --quiet
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**Supported Shells:**
|
|
304
|
+
- **Zsh** (~/.zshrc)
|
|
305
|
+
- **Bash** (~/.bashrc)
|
|
306
|
+
- **Fish** (~/.config/fish/functions/gw.fish)
|
|
307
|
+
|
|
308
|
+
The command is idempotent - running it multiple times won't create duplicate entries.
|
|
309
|
+
|
|
229
310
|
### root
|
|
230
311
|
|
|
231
312
|
Get the root directory of the current git repository. For git worktrees, returns the parent directory containing all worktrees.
|
|
@@ -473,8 +554,8 @@ gw init --root $(gw root) --auto-copy-files .env,components/agents/.env,componen
|
|
|
473
554
|
# Create a new worktree with auto-copy
|
|
474
555
|
gw add feat-new-feature
|
|
475
556
|
|
|
476
|
-
#
|
|
477
|
-
cd feat-new-feature
|
|
557
|
+
# Navigate to your new worktree
|
|
558
|
+
gw cd feat-new-feature
|
|
478
559
|
|
|
479
560
|
# Alternative: Create worktree and copy specific files
|
|
480
561
|
gw add feat-bugfix .env custom-config.json
|
|
@@ -482,6 +563,7 @@ gw add feat-bugfix .env custom-config.json
|
|
|
482
563
|
# Alternative: Use the manual sync command
|
|
483
564
|
git worktree add feat-manual
|
|
484
565
|
gw sync feat-manual .env
|
|
566
|
+
gw cd feat-manual
|
|
485
567
|
```
|
|
486
568
|
|
|
487
569
|
## Development
|
package/install.js
CHANGED
|
@@ -112,7 +112,13 @@ async function install() {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
console.log('✓ Installation complete!');
|
|
115
|
+
|
|
116
|
+
// Install shell integration
|
|
117
|
+
console.log('\n⚙️ Setting up shell integration...');
|
|
118
|
+
await installShellIntegration(binaryPath);
|
|
119
|
+
|
|
115
120
|
console.log('\nRun "gw --help" to get started.');
|
|
121
|
+
console.log('Tip: Restart your terminal or run "source ~/.zshrc" (or ~/.bashrc) to use "gw cd"');
|
|
116
122
|
} catch (error) {
|
|
117
123
|
console.error('\n✗ Installation failed:', error.message);
|
|
118
124
|
console.error('\nYou can manually download the binary from:');
|
|
@@ -125,5 +131,32 @@ async function install() {
|
|
|
125
131
|
}
|
|
126
132
|
}
|
|
127
133
|
|
|
134
|
+
/**
|
|
135
|
+
* Install shell integration
|
|
136
|
+
*/
|
|
137
|
+
async function installShellIntegration(binaryPath) {
|
|
138
|
+
const { spawn } = require('child_process');
|
|
139
|
+
|
|
140
|
+
return new Promise((resolve) => {
|
|
141
|
+
const child = spawn(binaryPath, ['install-shell', '--quiet'], {
|
|
142
|
+
stdio: 'inherit'
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
child.on('close', (code) => {
|
|
146
|
+
if (code === 0) {
|
|
147
|
+
console.log('✓ Shell integration installed!');
|
|
148
|
+
} else {
|
|
149
|
+
console.log(' (Shell integration can be installed later with: gw install-shell)');
|
|
150
|
+
}
|
|
151
|
+
resolve();
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
child.on('error', (err) => {
|
|
155
|
+
console.log(' (Shell integration can be installed later with: gw install-shell)');
|
|
156
|
+
resolve();
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
128
161
|
// Run installation
|
|
129
162
|
install();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gw-tools/gw",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "A command-line tool for managing git worktrees - copy files between worktrees with ease",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"git",
|
|
@@ -25,11 +25,13 @@
|
|
|
25
25
|
"gw": "./bin/gw.js"
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
|
-
"postinstall": "node install.js"
|
|
28
|
+
"postinstall": "node install.js",
|
|
29
|
+
"preuninstall": "node uninstall.js"
|
|
29
30
|
},
|
|
30
31
|
"files": [
|
|
31
32
|
"bin/",
|
|
32
33
|
"install.js",
|
|
34
|
+
"uninstall.js",
|
|
33
35
|
"README.md"
|
|
34
36
|
],
|
|
35
37
|
"engines": {
|
package/uninstall.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Preuninstall script for @gw-tools/gw
|
|
5
|
+
* Removes shell integration before uninstalling the package
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { existsSync } = require('fs');
|
|
9
|
+
const { join } = require('path');
|
|
10
|
+
const { platform } = require('os');
|
|
11
|
+
const { spawnSync } = require('child_process');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Remove shell integration
|
|
15
|
+
*/
|
|
16
|
+
function uninstall() {
|
|
17
|
+
const binDir = join(__dirname, 'bin');
|
|
18
|
+
const binaryPath = join(binDir, platform() === 'win32' ? 'gw.exe' : 'gw');
|
|
19
|
+
|
|
20
|
+
// Check if binary exists
|
|
21
|
+
if (!existsSync(binaryPath)) {
|
|
22
|
+
console.log('Binary not found, skipping shell integration removal.');
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
console.log('🧹 Removing shell integration...');
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
const result = spawnSync(binaryPath, ['install-shell', '--remove', '--quiet'], {
|
|
30
|
+
stdio: 'inherit',
|
|
31
|
+
timeout: 5000
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
if (result.error) {
|
|
35
|
+
console.log(' (Could not remove shell integration automatically)');
|
|
36
|
+
console.log(' You can manually remove it with: gw install-shell --remove');
|
|
37
|
+
} else if (result.status === 0) {
|
|
38
|
+
console.log('✓ Shell integration removed!');
|
|
39
|
+
} else {
|
|
40
|
+
console.log(' (Shell integration may not have been installed)');
|
|
41
|
+
}
|
|
42
|
+
} catch (error) {
|
|
43
|
+
console.log(' (Could not remove shell integration)');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
console.log('\nTip: Restart your terminal to complete the removal.');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Run uninstall
|
|
50
|
+
uninstall();
|