codeowners-git 1.7.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +283 -35
- package/dist/cli.js +4335 -612
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -11,8 +11,9 @@ Managing large-scale migrations in big monorepos with multiple codeowners can be
|
|
|
11
11
|
- Identifying files owned by specific teams using the CODEOWNERS file.
|
|
12
12
|
- Creating compact, team-specific branches with only their affected files.
|
|
13
13
|
- Streamlining the review process with smaller, targeted PRs.
|
|
14
|
+
- **Graceful error handling** with automatic recovery from failures.
|
|
14
15
|
|
|
15
|
-
> **Note:**
|
|
16
|
+
> **Note:** Starting from v2.0.0, this tool works with **staged files**. Stage your changes with `git add` before running commands.
|
|
16
17
|
|
|
17
18
|
https://github.com/user-attachments/assets/7cc0a924-f03e-47f3-baad-63eca9e8e4a8
|
|
18
19
|
|
|
@@ -24,8 +25,6 @@ Run commands directly without installation:
|
|
|
24
25
|
|
|
25
26
|
```bash
|
|
26
27
|
npx codeowners-git <command>
|
|
27
|
-
# or use the short alias
|
|
28
|
-
npx cg <command>
|
|
29
28
|
```
|
|
30
29
|
|
|
31
30
|
### Install globally via npm
|
|
@@ -69,10 +68,47 @@ gh auth login
|
|
|
69
68
|
```
|
|
70
69
|
|
|
71
70
|
The tool will automatically:
|
|
71
|
+
|
|
72
72
|
- Use PR templates if they exist in your repository (`.github/pull_request_template.md`, etc.)
|
|
73
73
|
- Set the PR title to your commit message
|
|
74
74
|
- Create PRs against the repository's default branch
|
|
75
75
|
|
|
76
|
+
### Owner Pattern Matching
|
|
77
|
+
|
|
78
|
+
The `--include` and `--ignore` options support glob patterns for flexible owner filtering:
|
|
79
|
+
|
|
80
|
+
| Pattern | Description | Example Match |
|
|
81
|
+
|---------|-------------|---------------|
|
|
82
|
+
| `@org/team` | Exact match | `@org/team` only |
|
|
83
|
+
| `*team` | Ends with | `@org/team`, `@company/team` |
|
|
84
|
+
| `@org/*` | Starts with (org) | `@org/team-a`, `@org/team-b` |
|
|
85
|
+
| `*ce-*` | Contains | `@org/ce-orca`, `@company/ce-team` |
|
|
86
|
+
| `*orca,*rme` | Multiple patterns | Either pattern matches |
|
|
87
|
+
|
|
88
|
+
**Key behavior:**
|
|
89
|
+
- `*` matches any character **including `/`** (slashes are normalized)
|
|
90
|
+
- `*/ce-orca` and `*ce-orca` behave identically
|
|
91
|
+
- Patterns are case-sensitive
|
|
92
|
+
- Multiple patterns can be comma-separated
|
|
93
|
+
|
|
94
|
+
### Path Pattern Matching
|
|
95
|
+
|
|
96
|
+
Path patterns use [micromatch](https://github.com/micromatch/micromatch) syntax:
|
|
97
|
+
|
|
98
|
+
| Pattern | Description | Example Match |
|
|
99
|
+
|---------|-------------|---------------|
|
|
100
|
+
| `src` | Directory (auto-appends `/**`) | All files in `src/` |
|
|
101
|
+
| `src/` | Directory with trailing slash | All files in `src/` |
|
|
102
|
+
| `**/*.ts` | Glob pattern | All `.ts` files |
|
|
103
|
+
| `{src,docs}` | Brace expansion | Files in `src/` or `docs/` |
|
|
104
|
+
| `packages/{a,b}/**` | Combined | Files in `packages/a/` or `packages/b/` |
|
|
105
|
+
| `packages/**/{foo,bar}` | Nested braces | Directories named `foo` or `bar` under packages |
|
|
106
|
+
|
|
107
|
+
**Key behavior:**
|
|
108
|
+
- Directories without glob chars automatically match all files inside (`src` → `src/**`)
|
|
109
|
+
- Use brace expansion `{a,b}` for multiple patterns (not comma-separated)
|
|
110
|
+
- Supports full micromatch/glob syntax: `*`, `**`, `?`, `[...]`, `{...}`
|
|
111
|
+
|
|
76
112
|
## Commands
|
|
77
113
|
|
|
78
114
|
### `--version`
|
|
@@ -91,44 +127,78 @@ cg --version
|
|
|
91
127
|
|
|
92
128
|
### `list`
|
|
93
129
|
|
|
94
|
-
List
|
|
130
|
+
List changed files with their CODEOWNERS.
|
|
95
131
|
|
|
96
132
|
Usage:
|
|
97
133
|
|
|
98
134
|
```bash
|
|
99
|
-
codeowners-git list [options]
|
|
135
|
+
codeowners-git list [pattern] [options]
|
|
100
136
|
# or
|
|
101
|
-
cg list [options]
|
|
137
|
+
cg list [pattern] [options]
|
|
102
138
|
```
|
|
103
139
|
|
|
140
|
+
Arguments:
|
|
141
|
+
|
|
142
|
+
- `[pattern]` Optional path pattern to filter files (micromatch syntax)
|
|
143
|
+
|
|
104
144
|
Options:
|
|
105
145
|
|
|
106
|
-
- `--
|
|
107
|
-
- `--
|
|
146
|
+
- `--include, -i` Filter by owner patterns (glob syntax)
|
|
147
|
+
- `--group, -g` Group files by code owner
|
|
148
|
+
- `--exclusive, -e` Only include files with a single owner (no co-owned files)
|
|
149
|
+
- `--co-owned, -c` Only include files with multiple owners (co-owned files)
|
|
108
150
|
|
|
109
|
-
|
|
151
|
+
Examples:
|
|
110
152
|
|
|
111
153
|
```bash
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
154
|
+
# List all changed files with owners
|
|
155
|
+
cg list
|
|
156
|
+
|
|
157
|
+
# Filter by path pattern
|
|
158
|
+
cg list src/
|
|
159
|
+
cg list "packages/{basics,shared}/**"
|
|
160
|
+
|
|
161
|
+
# Filter by owner pattern
|
|
162
|
+
cg list --include "*ce-*"
|
|
163
|
+
|
|
164
|
+
# Group output by owner
|
|
165
|
+
cg list --group
|
|
166
|
+
|
|
167
|
+
# Combine filters
|
|
168
|
+
cg list "packages/" --include "@myorg/*" --group
|
|
169
|
+
|
|
170
|
+
# List only files with a single owner (exclude co-owned files)
|
|
171
|
+
cg list --exclusive
|
|
172
|
+
|
|
173
|
+
# List only files where @myteam is the sole owner
|
|
174
|
+
cg list --include "@myteam" --exclusive
|
|
175
|
+
|
|
176
|
+
# List only co-owned files (files with multiple owners)
|
|
177
|
+
cg list --co-owned
|
|
178
|
+
|
|
179
|
+
# List co-owned files where @myteam is one of the owners
|
|
180
|
+
cg list --include "@myteam" --co-owned
|
|
115
181
|
```
|
|
116
182
|
|
|
117
183
|
### `branch`
|
|
118
184
|
|
|
119
|
-
|
|
185
|
+
Create a branch with changes owned by a specific codeowner.
|
|
120
186
|
|
|
121
187
|
Usage:
|
|
122
188
|
|
|
123
189
|
```bash
|
|
124
|
-
codeowners-git branch [options]
|
|
190
|
+
codeowners-git branch [pattern] [options]
|
|
125
191
|
# or
|
|
126
|
-
cg branch [options]
|
|
192
|
+
cg branch [pattern] [options]
|
|
127
193
|
```
|
|
128
194
|
|
|
195
|
+
Arguments:
|
|
196
|
+
|
|
197
|
+
- `[pattern]` Optional path pattern to filter files (micromatch syntax). Examples: `packages`, `**/*.tsx`, `{packages,apps}`
|
|
198
|
+
|
|
129
199
|
Options:
|
|
130
200
|
|
|
131
|
-
- `--
|
|
201
|
+
- `--include, -i` Code owner pattern to filter files (supports glob patterns like `*team`, `@org/*`)
|
|
132
202
|
- `--branch, -b` Specify branch pattern
|
|
133
203
|
- `--message, -m` Commit message for changes
|
|
134
204
|
- `--no-verify, -n` Skips lint-staged and other checks before committing
|
|
@@ -140,23 +210,47 @@ Options:
|
|
|
140
210
|
- `--append` Add commits to existing branch instead of creating a new one
|
|
141
211
|
- `--pr` Create a pull request after pushing (requires `--push` and GitHub CLI)
|
|
142
212
|
- `--draft-pr` Create a draft pull request after pushing (requires `--push` and GitHub CLI)
|
|
213
|
+
- `--exclusive, -e` Only include files where the owner is the sole owner (no co-owned files)
|
|
214
|
+
- `--co-owned, -c` Only include files with multiple owners (co-owned files)
|
|
143
215
|
|
|
144
216
|
Example:
|
|
145
217
|
|
|
146
218
|
```bash
|
|
147
|
-
# Create a new branch
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
219
|
+
# Create a new branch with all files owned by @myteam
|
|
220
|
+
cg branch -i @myteam -b "feature/new-feature" -m "Add new feature" -p
|
|
221
|
+
|
|
222
|
+
# Filter to only files in the packages directory
|
|
223
|
+
cg branch "packages" -i @myteam -b "feature/packages" -m "Update packages" -p
|
|
224
|
+
|
|
225
|
+
# Filter with glob pattern (only .tsx files)
|
|
226
|
+
cg branch "**/*.tsx" -i @myteam -b "feature/tsx" -m "Update tsx files" -p
|
|
227
|
+
|
|
228
|
+
# Filter multiple directories (brace expansion)
|
|
229
|
+
cg branch "{packages,apps}" -i @myteam -b "feature/update" -m "Update packages and apps" -p
|
|
151
230
|
|
|
152
231
|
# Create a branch and automatically create a pull request
|
|
153
|
-
cg branch -
|
|
232
|
+
cg branch -i @myteam -b "feature/new-feature" -m "Add new feature" -p --pr
|
|
154
233
|
|
|
155
234
|
# Create a branch and automatically create a draft pull request
|
|
156
|
-
cg branch -
|
|
235
|
+
cg branch -i @myteam -b "feature/new-feature" -m "Add new feature" -p --draft-pr
|
|
157
236
|
|
|
158
237
|
# Add more commits to the same branch later
|
|
159
|
-
cg branch -
|
|
238
|
+
cg branch -i @myteam -b "feature/new-feature" -m "Add more changes" --append -p
|
|
239
|
+
|
|
240
|
+
# Use glob patterns to match multiple teams
|
|
241
|
+
cg branch -i "*ce-*" -b "feature/ce-teams" -m "Changes for CE teams" -p
|
|
242
|
+
|
|
243
|
+
# Match all teams in an organization
|
|
244
|
+
cg branch -i "@myorg/*" -b "feature/org-changes" -m "Org-wide changes" -p
|
|
245
|
+
|
|
246
|
+
# Match multiple specific patterns
|
|
247
|
+
cg branch -i "*orca,*rme" -b "feature/specific-teams" -m "Targeted changes" -p
|
|
248
|
+
|
|
249
|
+
# Only include files where @myteam is the sole owner (exclude co-owned files)
|
|
250
|
+
cg branch -i @myteam -b "feature/exclusive" -m "Team exclusive changes" -p --exclusive
|
|
251
|
+
|
|
252
|
+
# Only include co-owned files where @myteam is one of the owners
|
|
253
|
+
cg branch -i @myteam -b "feature/co-owned" -m "Co-owned changes" -p --co-owned
|
|
160
254
|
```
|
|
161
255
|
|
|
162
256
|
### `multi-branch`
|
|
@@ -166,11 +260,15 @@ Create branches for all codeowners with changes.
|
|
|
166
260
|
Usage:
|
|
167
261
|
|
|
168
262
|
```bash
|
|
169
|
-
codeowners-git multi-branch [options]
|
|
263
|
+
codeowners-git multi-branch [pattern] [options]
|
|
170
264
|
# or
|
|
171
|
-
cg multi-branch [options]
|
|
265
|
+
cg multi-branch [pattern] [options]
|
|
172
266
|
```
|
|
173
267
|
|
|
268
|
+
Arguments:
|
|
269
|
+
|
|
270
|
+
- `[pattern]` Optional path pattern to filter files (micromatch syntax). Examples: `packages`, `**/*.tsx`, `{packages,apps}`
|
|
271
|
+
|
|
174
272
|
Options:
|
|
175
273
|
|
|
176
274
|
- `--branch, -b` Base branch name (will be suffixed with codeowner name)
|
|
@@ -182,44 +280,65 @@ Options:
|
|
|
182
280
|
- `--force, -f` Force push to remote
|
|
183
281
|
- `--keep-branch-on-failure, -k` Keep created branches even if operation fails
|
|
184
282
|
- `--default-owner, -d` Default owner to use when no codeowners are found for changed files
|
|
185
|
-
- `--ignore`
|
|
186
|
-
- `--include`
|
|
283
|
+
- `--ignore` Glob patterns to exclude codeowners (e.g., `*team-a`, `@org/*`)
|
|
284
|
+
- `--include` Glob patterns to include codeowners (e.g., `*ce-*`, `@org/*`)
|
|
187
285
|
- `--append` Add commits to existing branches instead of creating new ones
|
|
188
286
|
- `--pr` Create pull requests after pushing (requires `--push` and GitHub CLI)
|
|
189
287
|
- `--draft-pr` Create draft pull requests after pushing (requires `--push` and GitHub CLI)
|
|
288
|
+
- `--exclusive, -e` Only include files where each owner is the sole owner (no co-owned files)
|
|
289
|
+
- `--co-owned, -c` Only include files with multiple owners (co-owned files)
|
|
190
290
|
|
|
191
|
-
> **Note:** You cannot use both `--ignore` and `--include` options at the same time.
|
|
291
|
+
> **Note:** You cannot use both `--ignore` and `--include` options at the same time. You also cannot use both `--exclusive` and `--co-owned` options at the same time.
|
|
192
292
|
|
|
193
293
|
Example:
|
|
194
294
|
|
|
195
295
|
```bash
|
|
196
296
|
# Create branches for all codeowners
|
|
197
|
-
codeowners-git multi-branch -b "feature/new-feature" -m "Add new feature" -p
|
|
198
|
-
# or
|
|
199
297
|
cg multi-branch -b "feature/new-feature" -m "Add new feature" -p
|
|
200
298
|
|
|
299
|
+
# Filter to only files in the packages directory
|
|
300
|
+
cg multi-branch "packages" -b "feature/packages" -m "Update packages" -p
|
|
301
|
+
|
|
302
|
+
# Filter with glob pattern (only .tsx files)
|
|
303
|
+
cg multi-branch "**/*.tsx" -b "feature/tsx" -m "Update tsx files" -p
|
|
304
|
+
|
|
305
|
+
# Filter multiple directories (brace expansion)
|
|
306
|
+
cg multi-branch "{packages,apps}" -b "feature/update" -m "Update" -p
|
|
307
|
+
|
|
201
308
|
# Create branches and automatically create pull requests for each
|
|
202
309
|
cg multi-branch -b "feature/new-feature" -m "Add new feature" -p --pr
|
|
203
310
|
|
|
204
311
|
# Create branches and automatically create draft pull requests for each
|
|
205
312
|
cg multi-branch -b "feature/new-feature" -m "Add new feature" -p --draft-pr
|
|
206
313
|
|
|
207
|
-
# Exclude specific teams
|
|
208
|
-
cg multi-branch -b "feature/new-feature" -m "Add new feature" --ignore "
|
|
314
|
+
# Exclude specific teams using glob patterns
|
|
315
|
+
cg multi-branch -b "feature/new-feature" -m "Add new feature" --ignore "*ce-orca,*ce-ece"
|
|
316
|
+
|
|
317
|
+
# Exclude all teams in an organization
|
|
318
|
+
cg multi-branch -b "feature/new-feature" -m "Add new feature" --ignore "@excluded-org/*"
|
|
319
|
+
|
|
320
|
+
# Include only teams matching a pattern
|
|
321
|
+
cg multi-branch -b "feature/new-feature" -m "Add new feature" --include "*ce-*"
|
|
209
322
|
|
|
210
|
-
# Include only specific
|
|
211
|
-
cg multi-branch -b "feature/new-feature" -m "Add new feature" --include "@
|
|
323
|
+
# Include only specific organization
|
|
324
|
+
cg multi-branch -b "feature/new-feature" -m "Add new feature" --include "@myorg/*"
|
|
212
325
|
|
|
213
326
|
# Use default owner when no codeowners found
|
|
214
327
|
cg multi-branch -b "feature/new-feature" -m "Add new feature" -d "@default-team"
|
|
215
328
|
|
|
216
329
|
# Add more commits to existing branches
|
|
217
330
|
cg multi-branch -b "feature/new-feature" -m "Add more changes" --append -p
|
|
331
|
+
|
|
332
|
+
# Only include files where each owner is the sole owner (exclude co-owned files)
|
|
333
|
+
cg multi-branch -b "feature/exclusive" -m "Exclusive changes" -p --exclusive
|
|
334
|
+
|
|
335
|
+
# Only include co-owned files
|
|
336
|
+
cg multi-branch -b "feature/co-owned" -m "Co-owned changes" -p --co-owned
|
|
218
337
|
```
|
|
219
338
|
|
|
220
339
|
This will:
|
|
221
340
|
|
|
222
|
-
1. Find all codeowners for the staged files
|
|
341
|
+
1. Find all codeowners for the staged files
|
|
223
342
|
2. Apply any ignore/include filters if specified
|
|
224
343
|
3. For each codeowner (e.g., @team-a, @team-b):
|
|
225
344
|
- Create a branch like `feature/new-feature/team-a`
|
|
@@ -227,6 +346,135 @@ This will:
|
|
|
227
346
|
- Add a commit message like "Add new feature - @team-a"
|
|
228
347
|
- Push each branch to the remote if the `-p` flag is provided
|
|
229
348
|
|
|
349
|
+
### `extract`
|
|
350
|
+
|
|
351
|
+
Extract file changes from a source branch or commit to your working directory. This is useful when you want to copy changes from another branch to review and then stage them for committing using the `branch` command.
|
|
352
|
+
|
|
353
|
+
Usage:
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
codeowners-git extract [pattern] [options]
|
|
357
|
+
# or
|
|
358
|
+
cg extract [pattern] [options]
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
Arguments:
|
|
362
|
+
|
|
363
|
+
- `[pattern]` Optional path pattern to filter files (micromatch syntax). Examples: `packages`, `**/*.tsx`, `{packages,apps}`
|
|
364
|
+
|
|
365
|
+
Options:
|
|
366
|
+
|
|
367
|
+
- `--source, -s` **(required)** Source branch or commit to extract from
|
|
368
|
+
- `--include, -i` Filter extracted files by code owner (supports glob patterns like `*team`, `@org/*`)
|
|
369
|
+
- `--compare-main` Compare source against main branch instead of detecting merge-base
|
|
370
|
+
- `--exclusive, -e` Only include files where the owner is the sole owner (no co-owned files)
|
|
371
|
+
- `--co-owned, -c` Only include files with multiple owners (co-owned files)
|
|
372
|
+
|
|
373
|
+
Examples:
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
# Extract all changes from a branch (files will be unstaged in working directory)
|
|
377
|
+
cg extract -s feature/other-team
|
|
378
|
+
|
|
379
|
+
# Extract only specific owner's files
|
|
380
|
+
cg extract -s feature/other-team -i "@my-team"
|
|
381
|
+
|
|
382
|
+
# Extract using glob patterns
|
|
383
|
+
cg extract -s feature/other-team -i "*ce-*"
|
|
384
|
+
cg extract -s feature/other-team -i "@myorg/*"
|
|
385
|
+
|
|
386
|
+
# Extract from a commit hash
|
|
387
|
+
cg extract -s abc123def
|
|
388
|
+
|
|
389
|
+
# Extract comparing against main (instead of detecting merge-base)
|
|
390
|
+
cg extract -s feature/long-running --compare-main
|
|
391
|
+
|
|
392
|
+
# Filter by path pattern
|
|
393
|
+
cg extract "packages/" -s feature/other-team
|
|
394
|
+
cg extract "{packages,apps}" -s feature/other-team -i "@my-team"
|
|
395
|
+
|
|
396
|
+
# Extract only files where owner is the sole owner (no co-owned files)
|
|
397
|
+
cg extract -s feature/other-team -i "@my-team" --exclusive
|
|
398
|
+
|
|
399
|
+
# Extract only co-owned files (files with multiple owners)
|
|
400
|
+
cg extract -s feature/other-team --co-owned
|
|
401
|
+
|
|
402
|
+
# Extract co-owned files where @my-team is one of the owners
|
|
403
|
+
cg extract -s feature/other-team -i "@my-team" --co-owned
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
> **Note:** Files are extracted to your working directory (unstaged), allowing you to review and modify them. Stage the files with `git add`, then use the `branch` command to create a branch, commit, push, and create PRs.
|
|
407
|
+
|
|
408
|
+
### `recover`
|
|
409
|
+
|
|
410
|
+
Recover from failed or incomplete operations. When `branch` or `multi-branch` commands fail, the tool tracks the operation state and allows you to clean up and return to your original branch.
|
|
411
|
+
|
|
412
|
+
Usage:
|
|
413
|
+
|
|
414
|
+
```bash
|
|
415
|
+
codeowners-git recover [options]
|
|
416
|
+
# or
|
|
417
|
+
cg recover [options]
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
Options:
|
|
421
|
+
|
|
422
|
+
- `--list` List all incomplete operations
|
|
423
|
+
- `--id <operationId>` Recover specific operation by UUID
|
|
424
|
+
- `--keep-branches` Keep created branches instead of deleting them
|
|
425
|
+
- `--auto` Automatically recover most recent operation without prompts
|
|
426
|
+
|
|
427
|
+
Examples:
|
|
428
|
+
|
|
429
|
+
```bash
|
|
430
|
+
# List all incomplete operations
|
|
431
|
+
cg recover --list
|
|
432
|
+
|
|
433
|
+
# Automatically recover from most recent failure
|
|
434
|
+
cg recover --auto
|
|
435
|
+
|
|
436
|
+
# Recover specific operation
|
|
437
|
+
cg recover --id abc12345-6789-...
|
|
438
|
+
|
|
439
|
+
# Recover but keep the created branches
|
|
440
|
+
cg recover --id abc12345-6789-... --keep-branches
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
**When to use:**
|
|
444
|
+
|
|
445
|
+
- Operation failed due to network errors
|
|
446
|
+
- Process was interrupted (Ctrl+C)
|
|
447
|
+
- Push failed but branch was created
|
|
448
|
+
- Need to clean up after errors
|
|
449
|
+
|
|
450
|
+
**What it does:**
|
|
451
|
+
|
|
452
|
+
1. Returns to your original branch
|
|
453
|
+
2. Optionally deletes created branches (unless `--keep-branches`)
|
|
454
|
+
3. Cleans up state files
|
|
455
|
+
|
|
456
|
+
**How it works:**
|
|
457
|
+
|
|
458
|
+
Every `branch` and `multi-branch` operation is tracked with a unique UUID in your home directory (`~/.codeowners-git/state/`). If an operation fails, you'll see recovery instructions:
|
|
459
|
+
|
|
460
|
+
```bash
|
|
461
|
+
✗ Operation failed: Push failed with exit code 128
|
|
462
|
+
|
|
463
|
+
Recovery options:
|
|
464
|
+
1. Run 'codeowners-git recover --id abc12345...' to clean up
|
|
465
|
+
2. Run 'codeowners-git recover --id abc12345... --keep-branches' to keep branches
|
|
466
|
+
3. Run 'codeowners-git recover --list' to see all incomplete operations
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
The tool automatically handles:
|
|
470
|
+
|
|
471
|
+
- Graceful shutdown on Ctrl+C (SIGINT/SIGTERM)
|
|
472
|
+
- State persistence across crashes
|
|
473
|
+
- Detailed operation tracking (branch creation, commits, pushes, PR creation)
|
|
474
|
+
- Clean recovery to original state
|
|
475
|
+
|
|
476
|
+
> **Note:** State files are stored in `~/.codeowners-git/state/` outside your project directory, so no `.gitignore` entries are needed.
|
|
477
|
+
|
|
230
478
|
## Contributing
|
|
231
479
|
|
|
232
480
|
1. Clone the repository
|