easy-worktree 0.1.2__tar.gz → 0.1.3__tar.gz
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.
- {easy_worktree-0.1.2 → easy_worktree-0.1.3}/PKG-INFO +13 -2
- {easy_worktree-0.1.2 → easy_worktree-0.1.3}/README.md +12 -1
- {easy_worktree-0.1.2 → easy_worktree-0.1.3}/README_ja.md +12 -1
- {easy_worktree-0.1.2 → easy_worktree-0.1.3}/easy_worktree/__init__.py +94 -23
- {easy_worktree-0.1.2 → easy_worktree-0.1.3}/pyproject.toml +1 -1
- {easy_worktree-0.1.2 → easy_worktree-0.1.3}/tests/test_integration.py +100 -0
- {easy_worktree-0.1.2 → easy_worktree-0.1.3}/uv.lock +1 -1
- easy_worktree-0.1.2/.p10k.zsh +0 -1775
- easy_worktree-0.1.2/test_clone_manual/.claude/commands/artifacts-variants.md +0 -189
- easy_worktree-0.1.2/test_clone_manual/.claude/commands/artifacts.md +0 -115
- easy_worktree-0.1.2/test_clone_manual/.claude/commands/bucket-list.md +0 -99
- easy_worktree-0.1.2/test_clone_manual/.claude/commands/daily-task.md +0 -174
- easy_worktree-0.1.2/test_clone_manual/.claude/commands/memo-scratch.md +0 -108
- easy_worktree-0.1.2/test_clone_manual/.claude/commands/new-year-resolution.md +0 -244
- easy_worktree-0.1.2/test_clone_manual/.claude/commands/screenshot.md +0 -93
- easy_worktree-0.1.2/test_clone_manual/.claude/commands/tech-blog.md +0 -178
- easy_worktree-0.1.2/test_clone_manual/.claude/settings.json +0 -6
- easy_worktree-0.1.2/test_clone_manual/.cursor/rules/artifacts-variants.md +0 -175
- easy_worktree-0.1.2/test_clone_manual/.cursor/rules/artifacts.md +0 -105
- easy_worktree-0.1.2/test_clone_manual/.cursor/rules/bucket-list.md +0 -96
- easy_worktree-0.1.2/test_clone_manual/.cursor/rules/daily-task.md +0 -172
- easy_worktree-0.1.2/test_clone_manual/.cursor/rules/memo-scratch.md +0 -105
- easy_worktree-0.1.2/test_clone_manual/.cursor/rules/new-year-resolution.md +0 -244
- easy_worktree-0.1.2/test_clone_manual/.cursor/rules/tech-blog.md +0 -175
- easy_worktree-0.1.2/test_clone_manual/.github/chatmodes/artifacts-variants.chatmode.md +0 -154
- easy_worktree-0.1.2/test_clone_manual/.github/chatmodes/artifacts.chatmode.md +0 -108
- easy_worktree-0.1.2/test_clone_manual/.github/chatmodes/bucket-list.chatmode.md +0 -99
- easy_worktree-0.1.2/test_clone_manual/.github/chatmodes/daily-task.chatmode.md +0 -176
- easy_worktree-0.1.2/test_clone_manual/.github/chatmodes/memo-scratch.chatmode.md +0 -108
- easy_worktree-0.1.2/test_clone_manual/.github/chatmodes/new-year-resolution.chatmode.md +0 -247
- easy_worktree-0.1.2/test_clone_manual/.github/chatmodes/tech-blog.chatmode.md +0 -178
- easy_worktree-0.1.2/test_clone_manual/.github/instructions/main.instructions.md +0 -8
- easy_worktree-0.1.2/test_clone_manual/.gitignore +0 -4
- easy_worktree-0.1.2/test_clone_manual/.vscode/mcp.json +0 -18
- easy_worktree-0.1.2/test_clone_manual/.vscode/settings.json +0 -22
- easy_worktree-0.1.2/test_clone_manual/.wt/.gitignore +0 -1
- easy_worktree-0.1.2/test_clone_manual/.wt/README.md +0 -81
- easy_worktree-0.1.2/test_clone_manual/.wt/config.toml +0 -3
- easy_worktree-0.1.2/test_clone_manual/.wt/post-add +0 -28
- easy_worktree-0.1.2/test_clone_manual/CLAUDE.md +0 -76
- easy_worktree-0.1.2/test_clone_manual/README.md +0 -6
- easy_worktree-0.1.2/test_clone_manual/artifacts/ai-review-prototype/README.md +0 -119
- easy_worktree-0.1.2/test_clone_manual/artifacts/ai-review-prototype/index.html +0 -386
- easy_worktree-0.1.2/test_clone_manual/artifacts/ai-review-prototype/screenshots/ai-review-category-changed.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/ai-review-prototype/screenshots/ai-review-loading-state.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/ai-review-prototype/screenshots/ai-review-mobile-view.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/ai-review-prototype/screenshots/ai-review-prototype-initial.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/ai-review-prototype/screenshots/ai-review-translation-tab.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/ai-review-prototype/screenshots/popover-all-checked-new.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/ai-review-prototype/screenshots/popover-all-checked.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/ai-review-prototype/screenshots/popover-closed-final-new.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/ai-review-prototype/screenshots/popover-closed-final.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/ai-review-prototype/screenshots/popover-opened.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/ai-review-prototype/screenshots/updated-initial-view.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/ai-review-prototype/variants/README.md +0 -183
- easy_worktree-0.1.2/test_clone_manual/artifacts/ai-review-prototype/variants/analytics-dashboard-initial.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/ai-review-prototype/variants/analytics-dashboard.html +0 -841
- easy_worktree-0.1.2/test_clone_manual/artifacts/ai-review-prototype/variants/batch-processing-initial.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/ai-review-prototype/variants/batch-processing.html +0 -596
- easy_worktree-0.1.2/test_clone_manual/artifacts/ai-review-prototype/variants/collaboration-initial.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/ai-review-prototype/variants/collaboration.html +0 -796
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/README.md +0 -114
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/index.html +0 -488
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/screenshot-initial.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern1-ai-auto-correction.html +0 -628
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern1-ai-auto-correction.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern10-table-with-precedent.html +0 -954
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern10-table-with-precedent.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern11-interactive-matrix.html +0 -1038
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern11-interactive-matrix.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern12-smart-dashboard.html +0 -1228
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern12-smart-dashboard.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern13-translation-focused.html +0 -1117
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern13-translation-focused.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern14-smart-workbench.html +0 -1278
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern14-smart-workbench.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern15-slide-match.html +0 -1644
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern15-slide-match.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern2-collaboration.html +0 -794
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern2-collaboration.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern3-intelligent-analysis.html +0 -888
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern3-intelligent-analysis.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern4-card-view.html +0 -768
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern4-card-view.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern5-table-view.html +0 -1005
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern5-table-view.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern6-timeline-view.html +0 -879
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern6-timeline-view.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern7-industry-reference.html +0 -881
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern7-industry-reference.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern8-precedent-search.html +0 -915
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern8-precedent-search.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern9-trust-approval.html +0 -1092
- easy_worktree-0.1.2/test_clone_manual/artifacts/translation-list-prototype/variants/pattern9-trust-approval.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/blog/2025-06-30-tech-trends-2025-mid-year.md +0 -562
- easy_worktree-0.1.2/test_clone_manual/blog/2025-06-30-vscode-custom-chat-modes-guide.md +0 -289
- easy_worktree-0.1.2/test_clone_manual/blog/engineer-designer-collaboration-guide.md +0 -616
- easy_worktree-0.1.2/test_clone_manual/blog/img/429.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/blog/img/case-management.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/blog/img/ddtrace.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/blog/img/irhub-file.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/blog/img/term.png +0 -0
- easy_worktree-0.1.2/test_clone_manual/blog/irhub-translation-development-thinking-list-raw.md +0 -38
- easy_worktree-0.1.2/test_clone_manual/blog/irhub-translation-development-thinking-list.md +0 -304
- easy_worktree-0.1.2/test_clone_manual/blog/irhub-translation-development.md +0 -156
- easy_worktree-0.1.2/test_clone_manual/daily-tasks/2025-06-27.md +0 -45
- easy_worktree-0.1.2/test_clone_manual/daily-tasks/2025-06-30.md +0 -41
- easy_worktree-0.1.2/test_clone_manual/daily-tasks/2025-07-02.md +0 -50
- easy_worktree-0.1.2/test_clone_manual/daily-tasks/2025-07-03.md +0 -56
- easy_worktree-0.1.2/test_clone_manual/daily-tasks/2025-07-04.md +0 -76
- easy_worktree-0.1.2/test_clone_manual/daily-tasks/2025-07-07.md +0 -77
- easy_worktree-0.1.2/test_clone_manual/daily-tasks/2025-07-08.md +0 -84
- easy_worktree-0.1.2/test_clone_manual/daily-tasks/2025-07-09.md +0 -83
- easy_worktree-0.1.2/test_clone_manual/daily-tasks/2025-07-10.md +0 -84
- easy_worktree-0.1.2/test_clone_manual/daily-tasks/2025-07-16.md +0 -80
- easy_worktree-0.1.2/test_clone_manual/daily-tasks/2025-07-17.md +0 -78
- easy_worktree-0.1.2/test_clone_manual/daily-tasks/2025-07-18.md +0 -76
- easy_worktree-0.1.2/test_clone_manual/daily-tasks/2025-07-22.md +0 -81
- easy_worktree-0.1.2/test_clone_manual/daily-tasks/2025-07-23.md +0 -81
- easy_worktree-0.1.2/test_clone_manual/daily-tasks/2025-07-25.md +0 -77
- easy_worktree-0.1.2/test_clone_manual/daily-tasks/2025-07-30.md +0 -78
- easy_worktree-0.1.2/test_clone_manual/daily-tasks/2025-08-03.md +0 -82
- easy_worktree-0.1.2/test_clone_manual/daily-tasks/2025-08-27.md +0 -83
- easy_worktree-0.1.2/test_clone_manual/daily-tasks/2025-12-04.md +0 -77
- easy_worktree-0.1.2/test_clone_manual/memo/2025-12-10-interview.md +0 -53
- easy_worktree-0.1.2/test_clone_manual/memo/hoge.md +0 -1
- easy_worktree-0.1.2/test_clone_manual/memo-scratch.md +0 -57
- easy_worktree-0.1.2/test_clone_manual/new-year-resolution.md +0 -300
- easy_worktree-0.1.2/test_clone_manual/trash-box/Makefile +0 -9
- easy_worktree-0.1.2/test_clone_manual/trash-box/datadoglog.json +0 -28
- easy_worktree-0.1.2/test_clone_manual/trash-box/docs/a.md +0 -9
- easy_worktree-0.1.2/test_clone_manual/trash-box/docs/b.md +0 -44
- easy_worktree-0.1.2/test_clone_manual/trash-box/docs/c.md +0 -4
- easy_worktree-0.1.2/test_clone_manual/trash-box/docs/d.md +0 -27
- easy_worktree-0.1.2/test_clone_manual/trash-box/docs/e.md +0 -43
- easy_worktree-0.1.2/test_clone_manual/trash-box/docs/f.md +0 -14
- easy_worktree-0.1.2/test_clone_manual/trash-box/inbox.md +0 -5
- easy_worktree-0.1.2/test_clone_manual/trash-box/spec.template.md +0 -72
- easy_worktree-0.1.2/test_clone_manual/work-goal/2025/first-half-goal.md +0 -82
- easy_worktree-0.1.2/test_clone_manual/work-goal/2025/memo/ai-task-tree.md +0 -154
- easy_worktree-0.1.2/test_clone_manual/work-goal/2025/memo/problem-solution-tree.md +0 -79
- easy_worktree-0.1.2/test_clone_manual/work-goal/2025/memo/weekly-schedule-analysis.md +0 -80
- easy_worktree-0.1.2/test_clone_manual/work-goal/2025/todo-list.md +0 -29
- easy_worktree-0.1.2/test_clone_manual/workspace/practice.py +0 -450
- {easy_worktree-0.1.2 → easy_worktree-0.1.3}/.gitignore +0 -0
- {easy_worktree-0.1.2 → easy_worktree-0.1.3}/.python-version +0 -0
- {easy_worktree-0.1.2 → easy_worktree-0.1.3}/DEPLOY.md +0 -0
- {easy_worktree-0.1.2 → easy_worktree-0.1.3}/GEMINI.md +0 -0
- {easy_worktree-0.1.2 → easy_worktree-0.1.3}/LICENSE +0 -0
- {easy_worktree-0.1.2 → easy_worktree-0.1.3}/hero.png +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: easy-worktree
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: Git worktree を簡単に管理するための CLI ツール
|
|
5
5
|
Project-URL: Homepage, https://github.com/igtm/easy-worktree
|
|
6
6
|
Project-URL: Repository, https://github.com/igtm/easy-worktree
|
|
@@ -107,6 +107,14 @@ You can also specify a base branch:
|
|
|
107
107
|
wt add feature-1 main
|
|
108
108
|
```
|
|
109
109
|
|
|
110
|
+
#### Skip Setup
|
|
111
|
+
|
|
112
|
+
If you want to create a worktree without running the automatic setup (file copy and hooks):
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
wt add feature-1 --skip-setup
|
|
116
|
+
```
|
|
117
|
+
|
|
110
118
|
#### List worktrees
|
|
111
119
|
|
|
112
120
|
```bash
|
|
@@ -235,9 +243,12 @@ Customize behavior in `.wt/config.toml`:
|
|
|
235
243
|
```toml
|
|
236
244
|
worktrees_dir = ".worktrees" # Directory where worktrees are created
|
|
237
245
|
setup_files = [".env"] # Files to auto-copy during setup
|
|
238
|
-
auto_copy_on_add = true # Enable auto-copy on worktree creation
|
|
239
246
|
```
|
|
240
247
|
|
|
248
|
+
#### Local Configuration Override
|
|
249
|
+
|
|
250
|
+
You can create `.wt/config.local.toml` to override settings locally. This file is automatically added to `.gitignore` and ignores `config.toml` settings.
|
|
251
|
+
|
|
241
252
|
## Hooks
|
|
242
253
|
|
|
243
254
|
You can define scripts to run automatically after `wt add`.
|
|
@@ -85,6 +85,14 @@ You can also specify a base branch:
|
|
|
85
85
|
wt add feature-1 main
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
+
#### Skip Setup
|
|
89
|
+
|
|
90
|
+
If you want to create a worktree without running the automatic setup (file copy and hooks):
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
wt add feature-1 --skip-setup
|
|
94
|
+
```
|
|
95
|
+
|
|
88
96
|
#### List worktrees
|
|
89
97
|
|
|
90
98
|
```bash
|
|
@@ -213,9 +221,12 @@ Customize behavior in `.wt/config.toml`:
|
|
|
213
221
|
```toml
|
|
214
222
|
worktrees_dir = ".worktrees" # Directory where worktrees are created
|
|
215
223
|
setup_files = [".env"] # Files to auto-copy during setup
|
|
216
|
-
auto_copy_on_add = true # Enable auto-copy on worktree creation
|
|
217
224
|
```
|
|
218
225
|
|
|
226
|
+
#### Local Configuration Override
|
|
227
|
+
|
|
228
|
+
You can create `.wt/config.local.toml` to override settings locally. This file is automatically added to `.gitignore` and ignores `config.toml` settings.
|
|
229
|
+
|
|
219
230
|
## Hooks
|
|
220
231
|
|
|
221
232
|
You can define scripts to run automatically after `wt add`.
|
|
@@ -83,6 +83,14 @@ my-repo/ (main)
|
|
|
83
83
|
wt add feature-1 main
|
|
84
84
|
```
|
|
85
85
|
|
|
86
|
+
#### セットアップをスキップする
|
|
87
|
+
|
|
88
|
+
自動セットアップ(ファイルのコピーや hook の実行)を行わずに worktree を作成したい場合は、`--skip-setup` フラグを使用します:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
wt add feature-1 --skip-setup
|
|
92
|
+
```
|
|
93
|
+
|
|
86
94
|
#### 一覧を表示 (ショートカット: `ls`)
|
|
87
95
|
|
|
88
96
|
```bash
|
|
@@ -211,9 +219,12 @@ wt clean --days 30
|
|
|
211
219
|
```toml
|
|
212
220
|
worktrees_dir = ".worktrees" # worktree を作成するディレクトリ名
|
|
213
221
|
setup_files = [".env"] # 自動セットアップでコピーするファイル一覧
|
|
214
|
-
auto_copy_on_add = true # wt add 時にファイルを自動コピーするか
|
|
215
222
|
```
|
|
216
223
|
|
|
224
|
+
#### ローカル設定の上書き
|
|
225
|
+
|
|
226
|
+
`.wt/config.local.toml` を作成すると、設定をローカルでのみ上書きできます。このファイルは自動的に `.gitignore` に追加され、リポジトリにはコミットされません。
|
|
227
|
+
|
|
217
228
|
## Hook
|
|
218
229
|
|
|
219
230
|
`wt add` の後に自動実行されるスクリプトを記述できます。
|
|
@@ -226,10 +226,11 @@ def get_repository_name(url: str) -> str:
|
|
|
226
226
|
def load_config(base_dir: Path) -> dict:
|
|
227
227
|
"""設定ファイルを読み込む"""
|
|
228
228
|
config_file = base_dir / ".wt" / "config.toml"
|
|
229
|
+
local_config_file = base_dir / ".wt" / "config.local.toml"
|
|
230
|
+
|
|
229
231
|
default_config = {
|
|
230
232
|
"worktrees_dir": ".worktrees",
|
|
231
233
|
"setup_files": [".env"],
|
|
232
|
-
"auto_copy_on_add": True,
|
|
233
234
|
}
|
|
234
235
|
|
|
235
236
|
if config_file.exists():
|
|
@@ -240,6 +241,14 @@ def load_config(base_dir: Path) -> dict:
|
|
|
240
241
|
except Exception as e:
|
|
241
242
|
print(msg("error", f"Failed to load config: {e}"), file=sys.stderr)
|
|
242
243
|
|
|
244
|
+
if local_config_file.exists():
|
|
245
|
+
try:
|
|
246
|
+
with open(local_config_file, "r", encoding="utf-8") as f:
|
|
247
|
+
local_config = toml.load(f)
|
|
248
|
+
default_config.update(local_config)
|
|
249
|
+
except Exception as e:
|
|
250
|
+
print(msg("error", f"Failed to load local config: {e}"), file=sys.stderr)
|
|
251
|
+
|
|
243
252
|
return default_config
|
|
244
253
|
|
|
245
254
|
|
|
@@ -268,7 +277,6 @@ def create_hook_template(base_dir: Path):
|
|
|
268
277
|
{
|
|
269
278
|
"worktrees_dir": ".worktrees",
|
|
270
279
|
"setup_files": [".env"],
|
|
271
|
-
"auto_copy_on_add": True,
|
|
272
280
|
},
|
|
273
281
|
)
|
|
274
282
|
|
|
@@ -331,9 +339,24 @@ def create_hook_template(base_dir: Path):
|
|
|
331
339
|
|
|
332
340
|
# .gitignore
|
|
333
341
|
gitignore_file = wt_dir / ".gitignore"
|
|
342
|
+
|
|
343
|
+
ignores = ["post-add.local", "config.local.toml"]
|
|
344
|
+
|
|
334
345
|
if not gitignore_file.exists():
|
|
335
|
-
gitignore_content = "
|
|
346
|
+
gitignore_content = "\n".join(ignores) + "\n"
|
|
336
347
|
gitignore_file.write_text(gitignore_content)
|
|
348
|
+
else:
|
|
349
|
+
content = gitignore_file.read_text()
|
|
350
|
+
updated = False
|
|
351
|
+
for ignore in ignores:
|
|
352
|
+
if ignore not in content:
|
|
353
|
+
if content and not content.endswith("\n"):
|
|
354
|
+
content += "\n"
|
|
355
|
+
content += f"{ignore}\n"
|
|
356
|
+
updated = True
|
|
357
|
+
if updated:
|
|
358
|
+
gitignore_file.write_text(content)
|
|
359
|
+
|
|
337
360
|
|
|
338
361
|
# README.md (言語に応じて)
|
|
339
362
|
readme_file = wt_dir / "README.md"
|
|
@@ -356,6 +379,9 @@ wt clone <repository_url>
|
|
|
356
379
|
# 新しい worktree を作成(新規ブランチ)
|
|
357
380
|
wt add <作業名>
|
|
358
381
|
|
|
382
|
+
# セットアップ(フック実行など)をスキップして作成
|
|
383
|
+
wt add <作業名> --skip-setup
|
|
384
|
+
|
|
359
385
|
# 既存ブランチから worktree を作成
|
|
360
386
|
wt add <作業名> <既存ブランチ名>
|
|
361
387
|
|
|
@@ -368,6 +394,19 @@ wt rm <作業名>
|
|
|
368
394
|
|
|
369
395
|
詳細は https://github.com/igtm/easy-worktree を参照してください。
|
|
370
396
|
|
|
397
|
+
## 設定 (config.toml)
|
|
398
|
+
|
|
399
|
+
`.wt/config.toml` で以下の設定が可能です。
|
|
400
|
+
|
|
401
|
+
```toml
|
|
402
|
+
worktrees_dir = ".worktrees" # worktree を作成するディレクトリ名
|
|
403
|
+
setup_files = [".env"] # 自動セットアップでコピーするファイル一覧
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### ローカル設定 (config.local.toml)
|
|
407
|
+
|
|
408
|
+
`config.local.toml` を作成すると、設定をローカルでのみ上書きできます。このファイルは自動的に `.gitignore` に追加され、リポジトリにはコミットされません。
|
|
409
|
+
|
|
371
410
|
## post-add フック
|
|
372
411
|
|
|
373
412
|
`post-add` フックは、worktree 作成後に自動実行されるスクリプトです。
|
|
@@ -411,6 +450,9 @@ wt clone <repository_url>
|
|
|
411
450
|
# Create a new worktree (new branch)
|
|
412
451
|
wt add <work_name>
|
|
413
452
|
|
|
453
|
+
# Skip setup (hook execution etc)
|
|
454
|
+
wt add <work_name> --skip-setup
|
|
455
|
+
|
|
414
456
|
# Create a worktree from an existing branch
|
|
415
457
|
wt add <work_name> <existing_branch_name>
|
|
416
458
|
|
|
@@ -423,6 +465,19 @@ wt remove <work_name>
|
|
|
423
465
|
|
|
424
466
|
For more details, see https://github.com/igtm/easy-worktree
|
|
425
467
|
|
|
468
|
+
## Configuration (config.toml)
|
|
469
|
+
|
|
470
|
+
You can customize behavior in `.wt/config.toml`:
|
|
471
|
+
|
|
472
|
+
```toml
|
|
473
|
+
worktrees_dir = ".worktrees" # Directory where worktrees are created
|
|
474
|
+
setup_files = [".env"] # Files to auto-copy during setup
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
### Local Configuration (config.local.toml)
|
|
478
|
+
|
|
479
|
+
You can create `config.local.toml` to override settings locally. This file is automatically added to `.gitignore` and serves as a local override that won't be committed.
|
|
480
|
+
|
|
426
481
|
## post-add Hook
|
|
427
482
|
|
|
428
483
|
The `post-add` hook is a script that runs automatically after creating a worktree.
|
|
@@ -607,6 +662,7 @@ def add_worktree(
|
|
|
607
662
|
branch_to_use: str = None,
|
|
608
663
|
new_branch_base: str = None,
|
|
609
664
|
base_dir: Path = None,
|
|
665
|
+
skip_setup: bool = False,
|
|
610
666
|
) -> Path:
|
|
611
667
|
"""Core logic to add a worktree, reused by cmd_add and cmd_stash"""
|
|
612
668
|
if not base_dir:
|
|
@@ -616,24 +672,24 @@ def add_worktree(
|
|
|
616
672
|
print(msg("run_in_wt_dir"), file=sys.stderr)
|
|
617
673
|
sys.exit(1)
|
|
618
674
|
|
|
619
|
-
#
|
|
675
|
+
# settings loading
|
|
620
676
|
config = load_config(base_dir)
|
|
621
677
|
worktrees_dir_name = config.get("worktrees_dir", ".worktrees")
|
|
622
678
|
worktrees_dir = base_dir / worktrees_dir_name
|
|
623
679
|
worktrees_dir.mkdir(exist_ok=True)
|
|
624
680
|
|
|
625
|
-
# worktree
|
|
681
|
+
# worktree path decision
|
|
626
682
|
worktree_path = worktrees_dir / work_name
|
|
627
683
|
|
|
628
684
|
if worktree_path.exists():
|
|
629
685
|
print(msg("error", msg("already_exists", worktree_path)), file=sys.stderr)
|
|
630
686
|
sys.exit(1)
|
|
631
687
|
|
|
632
|
-
#
|
|
688
|
+
# update branch
|
|
633
689
|
print(msg("fetching"), file=sys.stderr)
|
|
634
690
|
run_command(["git", "fetch", "--all"], cwd=base_dir)
|
|
635
691
|
|
|
636
|
-
#
|
|
692
|
+
# main update to base branch latest
|
|
637
693
|
result = run_command(
|
|
638
694
|
["git", "rev-parse", "--abbrev-ref", "HEAD"], cwd=base_dir, check=False
|
|
639
695
|
)
|
|
@@ -649,10 +705,10 @@ def add_worktree(
|
|
|
649
705
|
["git", "pull", "origin", current_branch], cwd=base_dir, check=False
|
|
650
706
|
)
|
|
651
707
|
|
|
652
|
-
#
|
|
708
|
+
# create branch / checkout
|
|
653
709
|
final_branch_name = None
|
|
654
710
|
if new_branch_base:
|
|
655
|
-
#
|
|
711
|
+
# create new branch from base
|
|
656
712
|
final_branch_name = work_name
|
|
657
713
|
print(
|
|
658
714
|
msg("creating_branch", final_branch_name, new_branch_base), file=sys.stderr
|
|
@@ -671,7 +727,7 @@ def add_worktree(
|
|
|
671
727
|
check=False,
|
|
672
728
|
)
|
|
673
729
|
elif branch_to_use:
|
|
674
|
-
#
|
|
730
|
+
# checkout specified branch
|
|
675
731
|
final_branch_name = branch_to_use
|
|
676
732
|
print(msg("creating_worktree", worktree_path), file=sys.stderr)
|
|
677
733
|
result = run_command(
|
|
@@ -680,8 +736,8 @@ def add_worktree(
|
|
|
680
736
|
check=False,
|
|
681
737
|
)
|
|
682
738
|
else:
|
|
683
|
-
#
|
|
684
|
-
#
|
|
739
|
+
# auto detect
|
|
740
|
+
# use work_name as branch name
|
|
685
741
|
final_branch_name = work_name
|
|
686
742
|
|
|
687
743
|
check_local = run_command(
|
|
@@ -717,7 +773,7 @@ def add_worktree(
|
|
|
717
773
|
check=False,
|
|
718
774
|
)
|
|
719
775
|
else:
|
|
720
|
-
#
|
|
776
|
+
# find default branch
|
|
721
777
|
result_sym = run_command(
|
|
722
778
|
["git", "symbolic-ref", "refs/remotes/origin/HEAD", "--short"],
|
|
723
779
|
cwd=base_dir,
|
|
@@ -728,7 +784,7 @@ def add_worktree(
|
|
|
728
784
|
if result_sym.returncode == 0 and result_sym.stdout.strip():
|
|
729
785
|
detected_base = result_sym.stdout.strip()
|
|
730
786
|
else:
|
|
731
|
-
# remote/local main/master
|
|
787
|
+
# search in order: remote/local main/master
|
|
732
788
|
for b in ["origin/main", "origin/master", "main", "master"]:
|
|
733
789
|
if (
|
|
734
790
|
run_command(
|
|
@@ -742,7 +798,7 @@ def add_worktree(
|
|
|
742
798
|
break
|
|
743
799
|
|
|
744
800
|
if not detected_base:
|
|
745
|
-
#
|
|
801
|
+
# fallback to current branch
|
|
746
802
|
res_curr = run_command(
|
|
747
803
|
["git", "rev-parse", "--abbrev-ref", "HEAD"],
|
|
748
804
|
cwd=base_dir,
|
|
@@ -776,8 +832,8 @@ def add_worktree(
|
|
|
776
832
|
)
|
|
777
833
|
|
|
778
834
|
if result.returncode == 0:
|
|
779
|
-
|
|
780
|
-
|
|
835
|
+
if not skip_setup:
|
|
836
|
+
# automatic sync
|
|
781
837
|
setup_files = config.get("setup_files", [])
|
|
782
838
|
for file_name in setup_files:
|
|
783
839
|
src = base_dir / file_name
|
|
@@ -788,8 +844,9 @@ def add_worktree(
|
|
|
788
844
|
|
|
789
845
|
shutil.copy2(src, dst)
|
|
790
846
|
|
|
791
|
-
|
|
792
|
-
|
|
847
|
+
# post-add hook
|
|
848
|
+
run_post_add_hook(worktree_path, work_name, base_dir, final_branch_name)
|
|
849
|
+
|
|
793
850
|
return worktree_path
|
|
794
851
|
else:
|
|
795
852
|
if result.stderr:
|
|
@@ -798,15 +855,29 @@ def add_worktree(
|
|
|
798
855
|
|
|
799
856
|
|
|
800
857
|
def cmd_add(args: list[str]):
|
|
801
|
-
"""wt add <work_name> [<base_branch>] - Add a worktree"""
|
|
858
|
+
"""wt add <work_name> [<base_branch>] [--skip-setup] - Add a worktree"""
|
|
802
859
|
if len(args) < 1:
|
|
803
860
|
print(msg("usage_add"), file=sys.stderr)
|
|
804
861
|
sys.exit(1)
|
|
805
862
|
|
|
806
|
-
|
|
807
|
-
|
|
863
|
+
# parse options
|
|
864
|
+
clean_args = []
|
|
865
|
+
skip_setup = False
|
|
866
|
+
|
|
867
|
+
for arg in args:
|
|
868
|
+
if arg == "--skip-setup":
|
|
869
|
+
skip_setup = True
|
|
870
|
+
else:
|
|
871
|
+
clean_args.append(arg)
|
|
872
|
+
|
|
873
|
+
if not clean_args:
|
|
874
|
+
print(msg("usage_add"), file=sys.stderr)
|
|
875
|
+
sys.exit(1)
|
|
876
|
+
|
|
877
|
+
work_name = clean_args[0]
|
|
878
|
+
branch_to_use = clean_args[1] if len(clean_args) >= 2 else None
|
|
808
879
|
|
|
809
|
-
add_worktree(work_name, branch_to_use=branch_to_use)
|
|
880
|
+
add_worktree(work_name, branch_to_use=branch_to_use, skip_setup=skip_setup)
|
|
810
881
|
|
|
811
882
|
|
|
812
883
|
def cmd_stash(args: list[str]):
|
|
@@ -632,5 +632,105 @@ fi
|
|
|
632
632
|
self.assertEqual(res.stdout.strip(), "env-session")
|
|
633
633
|
|
|
634
634
|
|
|
635
|
+
def test_17_skip_setup(self):
|
|
636
|
+
"""Test 'wt add --skip-setup'"""
|
|
637
|
+
project_dir = self.test_dir / "skip-setup-test"
|
|
638
|
+
if project_dir.exists():
|
|
639
|
+
shutil.rmtree(project_dir)
|
|
640
|
+
project_dir.mkdir()
|
|
641
|
+
subprocess.run(["git", "init"], cwd=project_dir)
|
|
642
|
+
(project_dir / "README.md").write_text("Hello")
|
|
643
|
+
subprocess.run(["git", "add", "."], cwd=project_dir)
|
|
644
|
+
subprocess.run(["git", "commit", "-m", "Initial commit"], cwd=project_dir)
|
|
645
|
+
self.run_wt(["init"], cwd=project_dir)
|
|
646
|
+
|
|
647
|
+
# Config setup files
|
|
648
|
+
config_file = project_dir / ".wt" / "config.toml"
|
|
649
|
+
# We need to make sure config exists (init creates it)
|
|
650
|
+
with open(config_file, "r") as f:
|
|
651
|
+
config = toml.load(f)
|
|
652
|
+
config["setup_files"] = ["setup_me.txt"]
|
|
653
|
+
with open(config_file, "w") as f:
|
|
654
|
+
toml.dump(config, f)
|
|
655
|
+
|
|
656
|
+
# Create the setup file
|
|
657
|
+
(project_dir / "setup_me.txt").write_text("setup content")
|
|
658
|
+
|
|
659
|
+
# Create post-add hook that creates a file
|
|
660
|
+
hook_path = project_dir / ".wt" / "post-add"
|
|
661
|
+
hook_path.write_text("""#!/bin/sh
|
|
662
|
+
touch hook_ran.txt
|
|
663
|
+
""")
|
|
664
|
+
hook_path.chmod(0o755)
|
|
665
|
+
|
|
666
|
+
print("\nTesting wt add --skip-setup...")
|
|
667
|
+
self.run_wt(["add", "wt-skipped", "--skip-setup"], cwd=project_dir)
|
|
668
|
+
|
|
669
|
+
wt_dir = project_dir / ".worktrees" / "wt-skipped"
|
|
670
|
+
|
|
671
|
+
# Verify setup file NOT copied
|
|
672
|
+
self.assertFalse((wt_dir / "setup_me.txt").exists(), "Setup file should NOT be copied")
|
|
673
|
+
|
|
674
|
+
# Verify hook NOT ran
|
|
675
|
+
self.assertFalse((wt_dir / "hook_ran.txt").exists(), "Hook should NOT run")
|
|
676
|
+
|
|
677
|
+
print("\nTesting wt add WITHOUT --skip-setup (control)...")
|
|
678
|
+
self.run_wt(["add", "wt-normal"], cwd=project_dir)
|
|
679
|
+
wt_normal_dir = project_dir / ".worktrees" / "wt-normal"
|
|
680
|
+
|
|
681
|
+
# Verify setup file copied
|
|
682
|
+
self.assertTrue((wt_normal_dir / "setup_me.txt").exists(), "Setup file SHOULD be copied")
|
|
683
|
+
|
|
684
|
+
# Verify hook ran
|
|
685
|
+
self.assertTrue((wt_normal_dir / "hook_ran.txt").exists(), "Hook SHOULD run")
|
|
686
|
+
|
|
687
|
+
|
|
688
|
+
def test_18_config_local(self):
|
|
689
|
+
"""Test 'config.local.toml' priority and .gitignore update"""
|
|
690
|
+
project_dir = self.test_dir / "local-config-test"
|
|
691
|
+
if project_dir.exists():
|
|
692
|
+
shutil.rmtree(project_dir)
|
|
693
|
+
project_dir.mkdir()
|
|
694
|
+
subprocess.run(["git", "init"], cwd=project_dir)
|
|
695
|
+
(project_dir / "README.md").write_text("Hello")
|
|
696
|
+
subprocess.run(["git", "add", "."], cwd=project_dir)
|
|
697
|
+
subprocess.run(["git", "commit", "-m", "Initial commit"], cwd=project_dir)
|
|
698
|
+
self.run_wt(["init"], cwd=project_dir)
|
|
699
|
+
|
|
700
|
+
# 1. Verify .wt/.gitignore contains config.local.toml
|
|
701
|
+
wt_gitignore = project_dir / ".wt" / ".gitignore"
|
|
702
|
+
self.assertTrue(wt_gitignore.exists())
|
|
703
|
+
self.assertIn("config.local.toml", wt_gitignore.read_text())
|
|
704
|
+
|
|
705
|
+
# 2. Config setup files basic
|
|
706
|
+
config_file = project_dir / ".wt" / "config.toml"
|
|
707
|
+
with open(config_file, "r") as f:
|
|
708
|
+
config = toml.load(f)
|
|
709
|
+
config["setup_files"] = ["base.txt"]
|
|
710
|
+
with open(config_file, "w") as f:
|
|
711
|
+
toml.dump(config, f)
|
|
712
|
+
|
|
713
|
+
# 3. Create overrides in config.local.toml
|
|
714
|
+
local_config_file = project_dir / ".wt" / "config.local.toml"
|
|
715
|
+
local_config_data = {
|
|
716
|
+
"setup_files": ["local.txt"]
|
|
717
|
+
}
|
|
718
|
+
with open(local_config_file, "w") as f:
|
|
719
|
+
toml.dump(local_config_data, f)
|
|
720
|
+
|
|
721
|
+
# Create files
|
|
722
|
+
(project_dir / "base.txt").write_text("base")
|
|
723
|
+
(project_dir / "local.txt").write_text("local")
|
|
724
|
+
|
|
725
|
+
# 4. Run add (should use local.txt, NOT base.txt due to override)
|
|
726
|
+
print("\nTesting wt add with config.local.toml override...")
|
|
727
|
+
self.run_wt(["add", "wt-local"], cwd=project_dir)
|
|
728
|
+
|
|
729
|
+
wt_dir = project_dir / ".worktrees" / "wt-local"
|
|
730
|
+
|
|
731
|
+
self.assertTrue((wt_dir / "local.txt").exists(), "Should have copied local.txt from config.local.toml")
|
|
732
|
+
self.assertFalse((wt_dir / "base.txt").exists(), "Should NOT have copied base.txt (overridden)")
|
|
733
|
+
|
|
734
|
+
|
|
635
735
|
if __name__ == "__main__":
|
|
636
736
|
unittest.main()
|