git-worktree-wrapper 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,473 @@
1
+ Metadata-Version: 2.4
2
+ Name: git-worktree-wrapper
3
+ Version: 0.1.0
4
+ Summary: Git Worktree Wrapper - CLI tool for managing git worktrees with configurable path templates
5
+ Author: Vadim Volk
6
+ License: MIT
7
+ Keywords: cli,git,worktree,wrapper
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: MacOS
13
+ Classifier: Operating System :: POSIX :: Linux
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Software Development :: Version Control :: Git
19
+ Requires-Python: >=3.11
20
+ Requires-Dist: ruamel-yaml>=0.18.0
21
+ Requires-Dist: simpleeval>=1.0.0
22
+ Provides-Extra: dev
23
+ Requires-Dist: mypy>=1.8.0; extra == 'dev'
24
+ Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
25
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
26
+ Description-Content-Type: text/markdown
27
+
28
+ <!-- Language switcher -->
29
+ **English** | [Русский](README.ru.md)
30
+
31
+ > ⚠️ **Warning**: GWW is not heavily tested, use at your own risk!
32
+
33
+ # 🚀 GWW - Git Worktree Wrapper
34
+
35
+ [![CI](https://github.com/vadimvolk/git-worktree-wrapper/actions/workflows/ci.yml/badge.svg)](https://github.com/vadimvolk/git-worktree-wrapper/actions/workflows/ci.yml)
36
+
37
+ A CLI tool that wraps git worktree functionality with configurable path templates, condition-based routing, and project-specific actions.
38
+
39
+ ## ✨ Features
40
+
41
+ - **📝 Configurable path templates**: Dynamic path generation using templates with functions like `path(n)`, `branch()`, `norm_branch()`, `tag()`
42
+ - **🔄 Condition-based routing**: Route repositories to different locations based on URI conditions (host, path, protocol, tags)
43
+ - **🏷️ Tag support**: Pass custom tags via `--tag` option for conditional routing and path organization
44
+ - **⚙️ Project actions**: Execute custom actions (file copies, commands) after clone or worktree creation
45
+ - **🐚 Shell completion**: Bash, Zsh, and Fish completion support
46
+
47
+ ## 📋 Requirements
48
+
49
+ - 🐍 Python 3.11+
50
+ - 🔧 Git
51
+ - 🖥️ Unix-like system (Linux, macOS)
52
+
53
+ ## 📦 Installation
54
+
55
+ ### Install from PyPI (recommended)
56
+
57
+ The package is published on PyPI as `git-worktree-wrapper`; the CLI
58
+ command it installs is `gww`.
59
+
60
+ #### Using uv
61
+
62
+ ```bash
63
+ uv tool install git-worktree-wrapper
64
+ gww --help
65
+ ```
66
+
67
+ #### Using pipx
68
+
69
+ ```bash
70
+ pipx install git-worktree-wrapper
71
+ gww --help
72
+ ```
73
+
74
+ #### Using pip
75
+
76
+ ```bash
77
+ python -m pip install --user git-worktree-wrapper
78
+ gww --help
79
+ ```
80
+
81
+ ### From Git (no PyPI)
82
+
83
+ Use this if you need a specific commit or branch that hasn't been
84
+ released yet.
85
+
86
+ #### Using uv
87
+
88
+ ```bash
89
+ uv tool install "git+https://github.com/vadimvolk/git-worktree-wrapper.git"
90
+ gww --help
91
+ ```
92
+
93
+ #### Using pipx
94
+
95
+ ```bash
96
+ pipx install "git+https://github.com/vadimvolk/git-worktree-wrapper.git"
97
+ gww --help
98
+ ```
99
+
100
+ ### From source (development)
101
+
102
+ ```bash
103
+ # Clone the repository
104
+ git clone git@github.com:vadimvolk/git-worktree-wrapper.git
105
+ cd git-worktree-wrapper
106
+
107
+ # Install with uv
108
+ uv sync
109
+
110
+ # Run gww
111
+ uv run gww --help
112
+ ```
113
+
114
+ ### From source using pip
115
+
116
+ ```bash
117
+ # From a local checkout
118
+ cd git-worktree-wrapper
119
+ python -m pip install .
120
+ gww --help
121
+ ```
122
+
123
+ ## 🚀 Quick Start
124
+
125
+ ### 1. ⚙️ Initialize Configuration
126
+
127
+ ```bash
128
+ gww init config
129
+ ```
130
+
131
+ This creates a default configuration file at `~/.config/gww/config.yml` (Linux), `~/Library/Application Support/gww/config.yml` (macOS), or `%APPDATA%\gww\config.yml` (Windows). On any platform, exporting `XDG_CONFIG_HOME` to an absolute path overrides the default and stores the config there instead. Edit these 2 values: `default_sources` and `default_worktrees`. Check the [tutorial section](#tutorial) for routing details.
132
+
133
+ ### 2. 🐚 Initialize Shell Integration
134
+
135
+ ```bash
136
+ gww init shell zsh # or bash, or fish
137
+ ```
138
+
139
+ This installs shell completion and aliases (`gwc`, `gwa`, `gwr`) for easier workflow. Follow the instructions printed by the command to enable them in your shell.
140
+
141
+ ### 3. 📥 Clone a Repository
142
+
143
+ ```bash
144
+ gwc https://github.com/user/repo.git
145
+ # Prompts: "Navigate to ~/Developer/sources/github/user/repo? [Y/n]"
146
+ # Navigates if you confirm (default: yes)
147
+ ```
148
+
149
+ ### 4. ➕ Add a Worktree
150
+
151
+ ```bash
152
+ cd ~/Developer/sources/github/user/repo
153
+ gwa feature-branch
154
+ # Prompts: "Navigate to ~/Developer/worktrees/github/user/repo/feature-branch? [Y/n]"
155
+ # Navigates if you confirm (default: yes)
156
+ ```
157
+
158
+ ### 5. ➖ Remove a Worktree
159
+
160
+ ```bash
161
+ gwr feature-branch
162
+ # If worktree has uncommitted changes or untracked files:
163
+ # Prompts: "Force removal? [y/N]"
164
+ # Removes with --force if you confirm
165
+ # Otherwise: Removes worktree immediately
166
+ # Output: Removed worktree: ~/Developer/worktrees/github/user/repo/feature-branch
167
+ ```
168
+
169
+ ### 6. 🔄 Update Source Repository
170
+
171
+ ```bash
172
+ gww pull
173
+ # Output: Updated source repository: ~/Developer/sources/github/user/repo
174
+ ```
175
+
176
+ **Note**: `gww pull` updates the source repository even from a worktree, as long as the source is clean and has `main` or `master` checked out. Useful for merge/rebase workflows.
177
+ ```bash
178
+ gww pull # from any repository worktree
179
+ git rebase main # rebase your current changes to updated main branch
180
+ ```
181
+
182
+ ### 7. 🚚 Migrate Repositories
183
+ Create a backup first!
184
+
185
+ ```bash
186
+ gww migrate ~/old-repos --dry-run
187
+ # Output:
188
+ # Would migrate 5 repositories:
189
+ # ~/old-repos/repo1 -> ~/Developer/sources/github/user/repo1
190
+ # ...
191
+
192
+ gww migrate ~/old-repos
193
+ # Copy (default): list, copy sources then worktrees, repair, summary
194
+
195
+ gww migrate ~/old-repos --inplace
196
+ # Move worktrees then sources, repair, clean empty folders
197
+ ```
198
+
199
+ The `migrate` command scans one or more directories for git repositories and migrates them to locations based on your current configuration. It's useful when:
200
+ - You've updated your configuration and want to reorganize existing repositories
201
+ - You're moving from manual repository management to GWW
202
+ - You need to consolidate repositories from different locations
203
+
204
+ **Options**:
205
+ - `--dry-run`, `-n`: Show what would be migrated without making changes
206
+ - `--copy` (default): Copy repositories to new locations; list, validate, copy sources then worktrees, run `git worktree repair`, then report summary. No folder cleanup.
207
+ - `--inplace`: Move repositories in place (worktrees first, then sources), run `git worktree repair`, then recursively clean empty source folders.
208
+
209
+ **Behavior**:
210
+ - Accepts one or more paths; scans each and merges repo lists (deduplicated)
211
+ - Classifies each repo as source or worktree; uses source path template for sources and worktree path template for worktrees
212
+ - **--inplace**: Two passes (worktrees then sources), move and repair, then remove vacated dirs and empty parents up to input roots
213
+ - **--copy**: List sources and worktrees, validate destinations, copy sources then worktrees, repair relations, report summary
214
+ - Skips repositories without remotes, detached HEAD worktrees, or already at target
215
+
216
+ ## Tutorial
217
+
218
+ A minimal config file looks like:
219
+ ```yaml
220
+ # Folder where all sources are checked out with gwc. path(-2)/path(-1) generates 2-level subfolders based on repository URI. Like https://github.com/user/repo.git -> ~/Developer/sources/user/repo
221
+ default_sources: ~/Developer/other/sources/path(-2)/path(-1)
222
+ # Folder where all worktrees are checked out with gwa. norm_branch() works better with remote branches, e.g. origin/remote-branch -> origin-remote-branch
223
+ default_worktrees: ~/Developer/other/worktrees/path(-2)/path(-1)/norm_branch()
224
+ ```
225
+ The generated file will have more options commented out, including the functions reference.
226
+
227
+ ### Checkout based on where repository is hosted
228
+ Useful to separate e.g. open source projects (where you learn or get inspired) from your work projects.
229
+ ```yaml
230
+ # Still needed in case the config fails to find a section. You may prefer a non-nested sources structure, but make sure the result folder is unique
231
+ default_sources: ~/Developer/sources/host()-path(-2)-path(-1)
232
+ default_worktrees: ~/Developer/worktrees/host()-path(-2)-path(-1)-norm_branch()
233
+ sources:
234
+ # ... other rules
235
+ work:
236
+ when: "your.org.host" in host()
237
+ sources: ~/Developer/work/sources/path(-2)-path(-1)
238
+ worktrees: ~/Developer/work/sources/path(-2)-path(-1)-norm_branch()
239
+
240
+ ```
241
+ That's enough to separate work sources from all others, but you can create more sections with various rules. The library uses [simpleeval](https://github.com/danthedeckie/simpleeval) to evaluate templates, so you can use its [operators](https://github.com/danthedeckie/simpleeval?tab=readme-ov-file#operators) and functions below to get necessary routing.
242
+
243
+ #### 🌐 URI Functions (available in templates and `when` conditions)
244
+
245
+ | Function | Description | Example |
246
+ |----------|-------------|---------|
247
+ | `uri()` | Get full URI string | `uri()` → `"https://loca-repo-manager.com:8081/user/repo.git"` |
248
+ | `host()` | Get URI hostname | `host()` → `"loca-repo-manager.com"` |
249
+ | `port()` | Get URI port (empty string if not specified) | `port()` → `"8081"` or `""` usually |
250
+ | `protocol()` | Get URI protocol/scheme | `protocol()` → `"https"` / `"ssh"` / `git` |
251
+ | `path(n)` | Get URI path segment by index (0-based, negative for reverse) | `path(-1)` → `"repo"`, `path(0)` → `"user"` |
252
+
253
+ #### 🌿 Branch Functions (available in templates)
254
+
255
+ | Function | Description | Example |
256
+ |----------|-------------|---------|
257
+ | `branch()` | Get current branch name | `branch()` → `"feature/new/ui"` |
258
+ | `norm_branch(replacement)` | Branch name with `/` replaced (default: `"-"`) | `norm_branch()` → `"feature-new-ui"`, `norm_branch("_")` → `"feature_new_ui"` |
259
+
260
+ Need to checkout temporary projects separately? Add this to your config:
261
+ ```yml
262
+ sources:
263
+ # ... other rules
264
+ temp:
265
+ when: tag_exist("temp") # See [tags section](#-tags) for details about tags
266
+ sources: ~/Downloads/temp/sources/time_id()-host()-path(-2)-path(-1)
267
+ worktrees: ~/Downloads/temp/worktrees/time_id()-host()-path(-2)-path(-1)-norm-branch()
268
+ ```
269
+ `time_id(fmt)` generates a datetime-based identifier (cached per template evaluation). Default format is `"20260120-2134.03"` (short, seconds accuracy unique). Use [format codes](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes) for more detailed/nested results. Works properly if used multiple times.
270
+ ```yml
271
+ worktrees: ~/Downloads/temp/worktrees/time_id("%Y")/time_id("%m")/time_id("%H-%M$.%S")/host()-path(-2)-path(-1)-norm-branch()
272
+ ```
273
+ Generates nested structure: `YYYY/HH-MM.ss/host()-path(-2)-path(-1)-norm-branch()`
274
+
275
+
276
+ #### ⚙️ Actions (available in `actions` section)
277
+ Run actions after checking out a repository, after adding a worktree, or **before removing a worktree**. Common example: copying `local.properties` for Gradle projects.
278
+ ```yml
279
+ actions:
280
+ - when: file_exists("settings.gradle") # Check if it's actually a Gradle project
281
+ after_clone:
282
+ - copy: ["~/sources/default-local.properties", "local.properties"] # Copies your default file right after cloning the repo
283
+ after_add:
284
+ - copy: ["source_path('local.properties')", "local.properties"] # Inherit existing repository file to worktree
285
+ ```
286
+ You can have multiple `when` subsections in actions. After clone/add, the library goes top-to-bottom and executes all actions with matching `when` conditions.
287
+ Other functions available in the actions section:
288
+ | Action | Description | Example |
289
+ |--------|-------------|---------|
290
+ | `copy` | Copy a file or directory tree from a template-evaluated source to a template-evaluated destination (relative to `current_worktree()`) | `copy: ["source_path('local.properties')", "local.properties"]` or `copy: ["~/sources/default-local.properties", "local.properties"]` |
291
+ | `command` | Execute external command (runs in destination directory, template functions available) | `command: "npm install"` or `command: "claude init"` |
292
+
293
+ Each action rule also accepts an optional `critical:` flag (default `true`). When `true`, a failing action in that rule aborts the remaining actions in the rule and makes the command exit `1`. Set `critical: false` for non-critical rules — failures are reported in the action execution summary but the command still exits `0`. See [Failure handling](#-failure-handling) below for the full exit-code table.
294
+ ```yml
295
+ actions:
296
+ - when: file_exists("package.json")
297
+ critical: false # non-critical: a missing node_modules is annoying, not fatal
298
+ after_clone:
299
+ - command: "npm install"
300
+ ```
301
+
302
+ ##### 🪓 `before_remove` — cleanup actions before `gww remove`
303
+ A third action kind, `before_remove`, runs user-defined cleanup steps **before** `git worktree remove` deletes the worktree. Use it to archive the worktree, post a notification, run a hook, etc. The same `critical:` / `command:` / `copy:` machinery applies; a critical `before_remove` failure aborts the remove and exits `1`, a non-critical failure is reported but the remove still proceeds. `--force` is git-only and does *not* bypass `before_remove`.
304
+
305
+ In `before_remove` rules, `current_worktree()` is the worktree being removed, `source_path()` is its parent source repo, and `branch()` resolves to the worktree's currently checked-out branch (or `""` on detached HEAD). The `gww remove` command also accepts `--tag key=value`, which flows into `tag()` / `tag_exist()` predicates so per-call cleanup can be tag-driven.
306
+
307
+ ```yml
308
+ actions:
309
+ # Critical: archive the worktree before letting `gww remove` delete it.
310
+ - when: 'tag_exist("archive")'
311
+ before_remove:
312
+ - command: "tar -czf ~/archives/norm_branch()-time_id('%Y%m%d').tar.gz current_worktree()"
313
+
314
+ # Non-critical: notify a Slack channel. A failed notification should not block the remove.
315
+ - when: tag("notify") == "slack"
316
+ critical: false
317
+ before_remove:
318
+ - command: "curl -sf -X POST https://hooks.slack.com/... -d branch=branch()"
319
+
320
+ # Path-based remove: when removing by absolute path, `branch()` still resolves.
321
+ - when: branch() == "main"
322
+ before_remove:
323
+ - command: "echo refusing to remove main branch"
324
+ ```
325
+ > Note: `gww remove` accepts an absolute worktree path as well as a branch name. When invoked with a path, `branch()` reads the worktree's current branch via `git rev-parse --abbrev-ref HEAD` and falls back to `""` for detached HEAD, so predicates referencing `branch()` never raise.
326
+
327
+ #### ❗ Failure handling
328
+ Action failures are reported per-rule, grouped at the end of the action loop on stderr as the **action execution summary**. The summary lists every failing rule by its index in `actions:`, its criticality flag, and the failing action's error. Its non-emptiness also gates the success line: `say()` (the line scripts `cd $(gwc …)`) is suppressed whenever the summary has any entry, so `cd` only ever lands on a fully-configured worktree.
329
+
330
+ | Outcome | Exit code |
331
+ |---|---|
332
+ | Clean run (no failures) | `0` |
333
+ | Non-critical rule failure only | `0` |
334
+ | Critical rule failure | `1` |
335
+ | `when:` predicate or `command:` template failed to evaluate | `2` |
336
+
337
+ #### 📁 Actions Functions (available in `command` actions and `when` conditions)
338
+
339
+ | Function | Description | Example |
340
+ |----------|-------------|---------|
341
+ | `source_path(extra?)` | Get absolute path to source repository, optionally joined with `extra` | `source_path()` → `"/path/to/repo"`, `source_path("local.properties")` → `"/path/to/repo/local.properties"` |
342
+ | `current_worktree(extra?)` | Get absolute path to the current worktree, optionally joined with `extra` | `current_worktree()` → `"/path/to/worktree"`, `current_worktree("local.properties")` → `"/path/to/worktree/local.properties"` |
343
+ | `file_exists(path)` | Check if file exists relative to source repository | `file_exists("local.properties")` → `True` |
344
+ | `dir_exists(path)` | Check if directory exists relative to source repository | `dir_exists("config")` → `True` |
345
+ | `path_exists(path)` | Check if path exists (file or directory) relative to source repository | `path_exists("local.properties")` → `True` |
346
+
347
+ #### 🏷️ Tags
348
+
349
+ Still not flexible enough? Here comes tags. Tags specified using command line param `-t <tag-name>[=optional value]` (or `--tag`) for clone / add commands. Tags available in configuration with:
350
+
351
+ | Function | Description | Example |
352
+ |----------|-------------|---------|
353
+ | `tag(name)` | Get tag value by name (returns empty string if not set) | `tag("env")` → `"prod"` |
354
+ | `tag_exist(name)` | Check if tag exists (returns boolean) | `tag_exist("env")` → `True` |
355
+
356
+ **🏷️ Tag Usage Example**:
357
+ ```yaml
358
+ sources:
359
+ # Temporary checkout: Clone repositories to ~/Downloads/temp for quick access
360
+ # Usage: gwc <uri> -t temp
361
+ temp:
362
+ when: 'tag_exist("temp")'
363
+ sources: ~/Downloads/temp/time_id()-host()-path(-1)
364
+ worktrees: ~/Downloads/temp/time_id()-host()-path(-1)/norm_branch()
365
+
366
+ # Code review worktrees: Add worktrees to ~/Developer/worktree/code-review for review tasks
367
+ # Usage: gwa <branch> --tag review
368
+ review:
369
+ when: 'tag_exist("review")'
370
+ worktrees: ~/Developer/review/worktree/path(-1)/norm_branch()
371
+ # If used during clone, default source path is used
372
+ ```
373
+ ```
374
+
375
+ ```bash
376
+ # Clone to temporary location
377
+ gwc https://github.com/user/repo.git -t temp
378
+ # Output: ~/Downloads/temp/repo
379
+
380
+ # Add worktree for code review
381
+ cd ~/Developer/sources/github/user/repo
382
+ gwa feature-branch --tag review
383
+ # Output: ~/Developer/worktree/code-review/repo/feature-branch
384
+ ```
385
+
386
+ ## 📖 Commands
387
+
388
+ | Command | Description |
389
+ |---------|-------------|
390
+ | `gwc <uri> [--tag key=value]...` | 📥 Clone repository to configured location (tags available in templates/conditions) |
391
+ | `gwa <branch> [-c] [--tag key=value]...` | ➕ Add worktree for branch (optionally create branch, tags available in templates/conditions) |
392
+ | `gwr <branch\|path> [-f] [--tag key=value]...` | ➖ Remove worktree (tags available in `before_remove` predicates) |
393
+ | `gww pull` | 🔄 Update source repository (works from worktrees if source is clean and on main/master) |
394
+ | `gww migrate <path>... [--dry-run] [--copy \| --inplace]` | 🚚 Migrate repositories to new locations |
395
+ | `gww init config` | ⚙️ Create default configuration file |
396
+ | `gww init shell <shell>` | 🐚 Install shell completion (bash/zsh/fish) |
397
+
398
+ **Note**: `gwc`, `gwa`, and `gwr` are convenient shell aliases for `gww clone`, `gww add`, and `gww remove` respectively. They provide the same functionality with automatic navigation prompts. Install them with `gww init shell <shell>`.
399
+
400
+ **Common Options**:
401
+ - `--tag`, `-t`: Tag in the format `key=value` or just `key` (can be specified multiple times).
402
+
403
+ ## 🔄 Update
404
+
405
+ ### Using uv
406
+
407
+ ```bash
408
+ # Re-run the install command to update to the latest version
409
+ uv tool install "git+https://github.com/vadimvolk/git-worktree-wrapper.git"
410
+
411
+ # Or use the update command (if available)
412
+ uv tool update gww
413
+ ```
414
+
415
+ ### Using pipx
416
+
417
+ ```bash
418
+ pipx upgrade gww
419
+ ```
420
+
421
+ ### Using pip
422
+
423
+ ```bash
424
+ python -m pip install --upgrade gww
425
+ ```
426
+
427
+ ## 🗑️ Uninstall
428
+
429
+ ### Using uv
430
+
431
+ ```bash
432
+ uv tool uninstall gww
433
+ ```
434
+
435
+ ### Using pipx
436
+
437
+ ```bash
438
+ pipx uninstall gww
439
+ ```
440
+
441
+ ### Using pip
442
+
443
+ ```bash
444
+ python -m pip uninstall gww
445
+ ```
446
+
447
+ ## 🛠️ Development
448
+
449
+ ### 🧪 Running Tests
450
+
451
+ ```bash
452
+ # Run all tests
453
+ uv run pytest
454
+
455
+ # Run with coverage
456
+ uv run pytest --cov
457
+
458
+ # Run only unit tests
459
+ uv run pytest tests/unit/
460
+
461
+ # Run only integration tests
462
+ uv run pytest tests/integration/
463
+ ```
464
+
465
+ ### 🔍 Type Checking
466
+
467
+ ```bash
468
+ uv run mypy src/gww
469
+ ```
470
+
471
+ ## 📄 License
472
+
473
+ MIT
@@ -0,0 +1,35 @@
1
+ gww/__init__.py,sha256=vfQCT0-gHDKkxjf6xFD8aww8hH0pP2ogENG_rciXSZI,66
2
+ gww/actions/__init__.py,sha256=sFJGWqdKRy0dOpe-SJ4-I45tIwxHbggb-tljwRjH89M,8041
3
+ gww/actions/types.py,sha256=nwjNvB6uxaXs0YRRo_QvmX50fpW0lxLnve9bjPK-kTM,7004
4
+ gww/cli/__init__.py,sha256=mSTfwVlkSHus8bxd0nY_AjHU0G-Hj5fzI0baSkc3qE8,35
5
+ gww/cli/context.py,sha256=UR105KabnJb06lGSq6rT1KQ-gdWJ0F5E0AIfRuQUL2E,13826
6
+ gww/cli/main.py,sha256=UunuMuvjKO2zD_qcUbBNnnCu0E999_8fGpQ8Hi0on9Q,8419
7
+ gww/cli/commands/__init__.py,sha256=GYdoNv80KS2p7bCThuoRbhiLmIZW6ddPqPEFEx567nQ,35
8
+ gww/cli/commands/add.py,sha256=Slr-Xkx7jxIAl4VJUHkcJhgbT7k7h7V-bSosd45ge1I,3841
9
+ gww/cli/commands/clone.py,sha256=DZYyW_VfiJ9lJ-cZARdhOmxLkHvTFtmHRWA-Zk-0qAY,2904
10
+ gww/cli/commands/init.py,sha256=NyT43OVH_TvoW3BLaKfzTwAEzwwKhxL5_V9pMAx9IYs,4283
11
+ gww/cli/commands/migrate.py,sha256=6-NQnKcOxBsPZZLuSGMVUt_RDYWvaP4fNaBXi-1ddRA,2248
12
+ gww/cli/commands/pull.py,sha256=LqDKAD-LIjTEGIEelhlDLxUpiHJXz8VJdpW-ipNyy0M,1547
13
+ gww/cli/commands/remove.py,sha256=OJpjhRdeSZ4-YPDaQJpmwBLD_HWX9ueI17ni8HqMnZM,4782
14
+ gww/config/__init__.py,sha256=d00FAAaL_BSHLLmcjKtoc--KdvjeNCsojX0rObEBY8c,44
15
+ gww/config/loader.py,sha256=V4NQJP8QvXvXyZc2wpq_dA0SfQgFqynXLnBYTgxtLqY,11884
16
+ gww/config/resolver.py,sha256=FJR6mz8OHoRC0u1r2RCKVt6a0csxagurxSfyUoKuIaA,5086
17
+ gww/config/validator.py,sha256=TXDnmtiNn1KBtFiF6I2XLs_gQ_YrEVJKlU7sRQa02DQ,11001
18
+ gww/git/__init__.py,sha256=A4LQuKLpS4ZLNQbayH2JI01CfJJmXRSdLuY8d2w7v5A,30
19
+ gww/git/branch.py,sha256=-u9myGQdCaj8_vwqMjY7jHOWX8jeQItz-24yTQC3jmc,6280
20
+ gww/git/repository.py,sha256=Wk4f54QlefVqjqRsrSP1MNP8hpuV_pPHZaxC1lUNn-4,10469
21
+ gww/git/worktree.py,sha256=v8ujYxhp4FXL0QVkf6mgOAMArkmBP4lu0dlvOBNuYSg,11097
22
+ gww/migration/__init__.py,sha256=68rfmkXUBS42UGXtlSKcLG-u97kQYtBNVJY8N1hKCBM,1092
23
+ gww/migration/executor.py,sha256=nnM3TwaHOs9dsuIZ3Osl-ElB4l_cX5cwlDwNLXWop-U,12642
24
+ gww/migration/planner.py,sha256=2hz89kRw8KZE3wvyZi5QhoF0dluArRTekCbB4_EhGKs,8625
25
+ gww/template/__init__.py,sha256=dVv5IfFynYyrrYDDEu63FTcHNrqAG04TErWTaRQIz6g,34
26
+ gww/template/evaluator.py,sha256=NVeqfvvq8tJGhVHqjsejLjQg9cHm2Kbpd-2qhvqEKlc,8874
27
+ gww/template/functions.py,sha256=BEZpYsbXdYHkIMp1LEKc0DsK5uB5yAf_L0j10Ugfh3Q,12801
28
+ gww/utils/__init__.py,sha256=qHkwUQnAipyD7orncfDbJCaQ47mc02h90FgWy9ad_2o,25
29
+ gww/utils/shell.py,sha256=4AbJdFdh4zP7jD3o7eai_Mikzqc0-BT1GgrvoLooz-8,28663
30
+ gww/utils/uri.py,sha256=BtXPhvBz4rDoeFMKnFS_mGCXBAAzNnzBZQjMtk7r_vQ,4252
31
+ gww/utils/xdg.py,sha256=sozg8K2Secvbr-SOY96bMBRIFWvjPRUJT3mabuBBVw8,1969
32
+ git_worktree_wrapper-0.1.0.dist-info/METADATA,sha256=DW7ixqOIiIYO7s7DNM3oZ7jYTXGOwsctAQqeWYZLUqA,19430
33
+ git_worktree_wrapper-0.1.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
34
+ git_worktree_wrapper-0.1.0.dist-info/entry_points.txt,sha256=-nEszK-ay0Q-pKK5kMum48Ov4qZo-pUfAfmYwXLUePk,42
35
+ git_worktree_wrapper-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ gww = gww.cli.main:main
gww/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ """GWW - Git Worktree Wrapper CLI tool."""
2
+
3
+ __version__ = "0.1.0"