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.
Files changed (3) hide show
  1. package/README.md +283 -35
  2. package/dist/cli.js +4335 -612
  3. 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:** This tool works with **unstaged files**. Make sure to check if your files are unstaged before proceeding.
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 current CODEOWNERS entries.
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
- - `--owner, -o` Filter by specific owner
107
- - `--include, -i` Include specific patterns
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
- Example:
151
+ Examples:
110
152
 
111
153
  ```bash
112
- codeowners-git list -o @myteam
113
- # or
114
- cg list -o @myteam
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
- Manage branch permissions in CODEOWNERS file.
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
- - `--owner, -o` Specify owner(s) to add/remove
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
- codeowners-git branch -o @myteam -b "feature/new-feature" -m "Add new feature" -p
149
- # or
150
- cg branch -o @myteam -b "feature/new-feature" -m "Add new feature" -p
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 -o @myteam -b "feature/new-feature" -m "Add new feature" -p --pr
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 -o @myteam -b "feature/new-feature" -m "Add new feature" -p --draft-pr
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 -o @myteam -b "feature/new-feature" -m "Add more changes" --append -p
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` Comma-separated patterns to exclude codeowners (e.g., 'team-a,team-b')
186
- - `--include` Comma-separated patterns to include codeowners (e.g., 'team-_,@org/_')
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 "@ce-orca,@ce-ece"
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 patterns
211
- cg multi-branch -b "feature/new-feature" -m "Add new feature" --include "@team-*"
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 in your repository
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