codeowners-git 2.1.0 → 2.2.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 +47 -3
- package/dist/cli.js +128 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ Managing large-scale migrations in big monorepos with multiple codeowners can be
|
|
|
15
15
|
- **Dry-run previews** to see exactly what will happen before committing.
|
|
16
16
|
- **JSON output** for piping to other tools, scripts, and agent workflows.
|
|
17
17
|
|
|
18
|
-
> ❗❗ ❗ **Note:** Starting from v2.0.0, this tool works with **staged files**. Stage your changes with `git add` before running commands.
|
|
18
|
+
> ❗❗ ❗ **Note:** Starting from v2.0.0, this tool works with **staged files**. Stage your changes with `git add` before running commands. Alternatively, use `multi-branch --source <branch>` to split directly from an existing branch or PR without staging.
|
|
19
19
|
|
|
20
20
|
https://github.com/user-attachments/assets/7cc0a924-f03e-47f3-baad-63eca9e8e4a8
|
|
21
21
|
|
|
@@ -221,11 +221,16 @@ Options:
|
|
|
221
221
|
- `--append` Add commits to existing branch instead of creating a new one
|
|
222
222
|
- `--pr` Create a pull request after pushing (requires `--push` and GitHub CLI)
|
|
223
223
|
- `--draft-pr` Create a draft pull request after pushing (requires `--push` and GitHub CLI)
|
|
224
|
+
- `--pr-body` Custom PR body text (overrides the repo's PR template). Requires `--pr` or `--draft-pr`.
|
|
224
225
|
- `--exclusive, -e` Only include files where the owner is the sole owner (no co-owned files)
|
|
225
226
|
- `--co-owned, -c` Only include files with multiple owners (co-owned files)
|
|
227
|
+
- `--source, -s` Source branch or commit to extract changes from (creates a temp branch from the default branch). No staging required.
|
|
228
|
+
- `--compare-main` Compare source against main branch instead of detecting merge-base (use with `--source`)
|
|
226
229
|
- `--dry-run` Preview the operation without making any changes
|
|
227
230
|
- `--json` Output results as JSON (suppresses all other output)
|
|
228
231
|
|
|
232
|
+
> **Note:** `--source` cannot be used when there are staged changes.
|
|
233
|
+
|
|
229
234
|
Example:
|
|
230
235
|
|
|
231
236
|
```bash
|
|
@@ -273,6 +278,19 @@ cg branch -i @myteam -b "feature/new" -m "Add feature" --dry-run --json
|
|
|
273
278
|
|
|
274
279
|
# Normal execution with JSON output
|
|
275
280
|
cg branch -i @myteam -b "feature/new" -m "Add feature" -p --json
|
|
281
|
+
|
|
282
|
+
# Create a PR with a custom body (overrides repo PR template)
|
|
283
|
+
cg branch -i @myteam -b "feature/new" -m "Add feature" -p --pr --pr-body "## Summary
|
|
284
|
+
Migrated files owned by @myteam.
|
|
285
|
+
|
|
286
|
+
## Reviewer Notes
|
|
287
|
+
Auto-generated PR from codeowners-git."
|
|
288
|
+
|
|
289
|
+
# Extract a single team's files from an existing branch
|
|
290
|
+
cg branch -s feature/big-migration -i @myteam -b "feature/myteam-migration" -m "Migrate" -p --pr
|
|
291
|
+
|
|
292
|
+
# Preview what would be extracted from a source branch
|
|
293
|
+
cg branch -s origin/feature/big-migration -i @myteam -b "feature/myteam" -m "Migrate" --dry-run
|
|
276
294
|
```
|
|
277
295
|
|
|
278
296
|
### `multi-branch`
|
|
@@ -307,12 +325,15 @@ Options:
|
|
|
307
325
|
- `--append` Add commits to existing branches instead of creating new ones
|
|
308
326
|
- `--pr` Create pull requests after pushing (requires `--push` and GitHub CLI)
|
|
309
327
|
- `--draft-pr` Create draft pull requests after pushing (requires `--push` and GitHub CLI)
|
|
328
|
+
- `--pr-body` Custom PR body text (overrides the repo's PR template). Requires `--pr` or `--draft-pr`. The same body is used for all branches.
|
|
310
329
|
- `--exclusive, -e` Only include files where each owner is the sole owner (no co-owned files)
|
|
311
330
|
- `--co-owned, -c` Only include files with multiple owners (co-owned files)
|
|
331
|
+
- `--source, -s` Source branch or commit to split (extracts changes onto a temp branch from the default branch). No staging required — the tool handles extraction automatically.
|
|
332
|
+
- `--compare-main` Compare source against main branch instead of detecting merge-base (use with `--source`)
|
|
312
333
|
- `--dry-run` Preview the operation without making any changes
|
|
313
334
|
- `--json` Output results as JSON (suppresses all other output)
|
|
314
335
|
|
|
315
|
-
> **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.
|
|
336
|
+
> **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. `--source` cannot be used when there are staged changes.
|
|
316
337
|
|
|
317
338
|
Example:
|
|
318
339
|
|
|
@@ -370,11 +391,27 @@ cg multi-branch -b "mig" -m "Fix" --dry-run --json | jq '.owners[] | select(.fil
|
|
|
370
391
|
|
|
371
392
|
# Normal execution with JSON output
|
|
372
393
|
cg multi-branch -b "feature/migration" -m "Migrate" -p --json
|
|
394
|
+
|
|
395
|
+
# Split an existing branch (e.g., from a PR) into per-team branches
|
|
396
|
+
cg multi-branch -s feature/big-migration -b "migration" -m "Migrate" -p --pr
|
|
397
|
+
|
|
398
|
+
# Split from a remote ref
|
|
399
|
+
cg multi-branch -s origin/feature/big-migration -b "migration" -m "Migrate" -p
|
|
400
|
+
|
|
401
|
+
# Preview a source split with dry-run
|
|
402
|
+
cg multi-branch -s feature/big-migration -b "migration" -m "Migrate" --dry-run
|
|
403
|
+
|
|
404
|
+
# Combine --source with path filtering
|
|
405
|
+
cg multi-branch -s feature/big-migration "src/services/**" -b "migration" -m "Migrate services" -p
|
|
406
|
+
|
|
407
|
+
# Use a custom PR body for all generated PRs
|
|
408
|
+
cg multi-branch -b "migration" -m "Migrate" -p --draft-pr --pr-body "## Summary
|
|
409
|
+
Auto-split migration PR by codeowner."
|
|
373
410
|
```
|
|
374
411
|
|
|
375
412
|
This will:
|
|
376
413
|
|
|
377
|
-
1. Find all codeowners for the staged files
|
|
414
|
+
1. Find all codeowners for the staged files (or from `--source` ref if provided)
|
|
378
415
|
2. Apply any ignore/include filters if specified
|
|
379
416
|
3. For each codeowner (e.g., @team-a, @team-b):
|
|
380
417
|
- Create a branch like `feature/new-feature/team-a`
|
|
@@ -382,6 +419,13 @@ This will:
|
|
|
382
419
|
- Add a commit message like "Add new feature - @team-a"
|
|
383
420
|
- Push each branch to the remote if the `-p` flag is provided
|
|
384
421
|
|
|
422
|
+
When `--source` is provided, the tool automatically:
|
|
423
|
+
|
|
424
|
+
1. Creates a temporary branch from the default branch (main/master)
|
|
425
|
+
2. Extracts the changed files from the source ref
|
|
426
|
+
3. Stages them and runs the normal split logic
|
|
427
|
+
4. Cleans up the temporary branch and returns to your original branch
|
|
428
|
+
|
|
385
429
|
### `extract`
|
|
386
430
|
|
|
387
431
|
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.
|
package/dist/cli.js
CHANGED
|
@@ -16372,6 +16372,16 @@ var getChangedFilesBetween = async (source, target) => {
|
|
|
16372
16372
|
throw new Error(`Failed to get changed files between ${source} and ${target || "base"}: ${error}`);
|
|
16373
16373
|
}
|
|
16374
16374
|
};
|
|
16375
|
+
var stageFiles = async (files) => {
|
|
16376
|
+
if (files.length === 0)
|
|
16377
|
+
return;
|
|
16378
|
+
try {
|
|
16379
|
+
await git.add(files);
|
|
16380
|
+
log.info(`Staged ${files.length} file${files.length !== 1 ? "s" : ""}`);
|
|
16381
|
+
} catch (error) {
|
|
16382
|
+
throw new Error(`Failed to stage files: ${error}`);
|
|
16383
|
+
}
|
|
16384
|
+
};
|
|
16375
16385
|
var extractFilesFromRef = async (ref, files) => {
|
|
16376
16386
|
try {
|
|
16377
16387
|
for (const file of files) {
|
|
@@ -16696,11 +16706,16 @@ var createPullRequest = async (options) => {
|
|
|
16696
16706
|
});
|
|
16697
16707
|
};
|
|
16698
16708
|
var createPRWithTemplate = async (title, branchName, options = {}) => {
|
|
16699
|
-
const template = await findPRTemplate();
|
|
16700
16709
|
let body = "";
|
|
16701
|
-
if (
|
|
16702
|
-
body =
|
|
16703
|
-
log.info("Using PR
|
|
16710
|
+
if (options.prBody) {
|
|
16711
|
+
body = options.prBody;
|
|
16712
|
+
log.info("Using provided PR body");
|
|
16713
|
+
} else {
|
|
16714
|
+
const template = await findPRTemplate();
|
|
16715
|
+
if (template) {
|
|
16716
|
+
body = template.content;
|
|
16717
|
+
log.info("Using PR template for pull request body");
|
|
16718
|
+
}
|
|
16704
16719
|
}
|
|
16705
16720
|
return createPullRequest({
|
|
16706
16721
|
title,
|
|
@@ -16859,6 +16874,8 @@ var branch = async (options) => {
|
|
|
16859
16874
|
let operationState = options.operationState || null;
|
|
16860
16875
|
const isSubOperation = !!options.operationState;
|
|
16861
16876
|
let autoRecoverySucceeded = false;
|
|
16877
|
+
let tempBranch = null;
|
|
16878
|
+
let sourceOriginalBranch = null;
|
|
16862
16879
|
if (options.json && !isSubOperation) {
|
|
16863
16880
|
setSilent(true);
|
|
16864
16881
|
}
|
|
@@ -16872,7 +16889,37 @@ var branch = async (options) => {
|
|
|
16872
16889
|
if (options.pr && options.draftPr) {
|
|
16873
16890
|
throw new Error("Cannot use both --pr and --draft-pr options");
|
|
16874
16891
|
}
|
|
16875
|
-
if (
|
|
16892
|
+
if (options.source && !isSubOperation) {
|
|
16893
|
+
if (await hasStagedChanges()) {
|
|
16894
|
+
throw new Error("Cannot use --source when there are staged changes. " + "Either commit/unstage your changes first, or omit --source to use staged files.");
|
|
16895
|
+
}
|
|
16896
|
+
sourceOriginalBranch = await getCurrentBranch();
|
|
16897
|
+
log.info(`Extracting changes from source: ${options.source}`);
|
|
16898
|
+
const defaultBranch = await getDefaultBranch();
|
|
16899
|
+
const compareTarget = options.compareMain ? defaultBranch : undefined;
|
|
16900
|
+
if (compareTarget) {
|
|
16901
|
+
log.info(`Comparing ${options.source} against ${compareTarget}...`);
|
|
16902
|
+
}
|
|
16903
|
+
let sourceFiles = await getChangedFilesBetween(options.source, compareTarget);
|
|
16904
|
+
if (sourceFiles.length === 0) {
|
|
16905
|
+
throw new Error(`No changed files found in ${options.source}`);
|
|
16906
|
+
}
|
|
16907
|
+
sourceFiles = filterByPathPatterns(sourceFiles, options.pathPattern);
|
|
16908
|
+
if (sourceFiles.length === 0) {
|
|
16909
|
+
throw new Error(options.pathPattern ? `No changed files found matching pattern: ${options.pathPattern}` : `No changed files found in ${options.source}`);
|
|
16910
|
+
}
|
|
16911
|
+
log.info(`Found ${sourceFiles.length} changed file${sourceFiles.length !== 1 ? "s" : ""} in source`);
|
|
16912
|
+
tempBranch = `cg-temp-${Date.now()}`;
|
|
16913
|
+
log.info(`Creating temporary branch "${tempBranch}" from "${defaultBranch}"...`);
|
|
16914
|
+
await checkout(defaultBranch);
|
|
16915
|
+
await createBranch(tempBranch);
|
|
16916
|
+
log.info("Extracting files from source...");
|
|
16917
|
+
await extractFilesFromRef(options.source, sourceFiles);
|
|
16918
|
+
await stageFiles(sourceFiles);
|
|
16919
|
+
log.info(`Files extracted and staged on temporary branch. Proceeding with branch creation...
|
|
16920
|
+
`);
|
|
16921
|
+
}
|
|
16922
|
+
if (!(options.source && !isSubOperation) && await hasUnstagedChanges()) {
|
|
16876
16923
|
const unstagedFiles = await getUnstagedFiles();
|
|
16877
16924
|
log.warn("Warning: Unstaged changes detected (these will be ignored):");
|
|
16878
16925
|
unstagedFiles.forEach((file) => log.warn(` - ${file}`));
|
|
@@ -17072,7 +17119,8 @@ Excluded staged files (${excludedFiles.length}):`));
|
|
|
17072
17119
|
const defaultBranch = await getDefaultBranch();
|
|
17073
17120
|
const prResult = await createPRWithTemplate(options.message, options.branch, {
|
|
17074
17121
|
draft: options.draftPr,
|
|
17075
|
-
base: defaultBranch
|
|
17122
|
+
base: defaultBranch,
|
|
17123
|
+
prBody: options.prBody
|
|
17076
17124
|
});
|
|
17077
17125
|
if (prResult) {
|
|
17078
17126
|
prUrl = prResult.url;
|
|
@@ -17231,15 +17279,30 @@ Auto-recovery failed. Manual recovery options:`);
|
|
|
17231
17279
|
process.exit(1);
|
|
17232
17280
|
} finally {
|
|
17233
17281
|
try {
|
|
17234
|
-
if (
|
|
17235
|
-
|
|
17236
|
-
|
|
17237
|
-
|
|
17282
|
+
if (tempBranch) {
|
|
17283
|
+
if (sourceOriginalBranch) {
|
|
17284
|
+
const currentBranch = await getCurrentBranch();
|
|
17285
|
+
if (currentBranch !== sourceOriginalBranch) {
|
|
17286
|
+
log.info(`Returning to original branch "${sourceOriginalBranch}"...`);
|
|
17287
|
+
await checkout(sourceOriginalBranch);
|
|
17288
|
+
}
|
|
17289
|
+
}
|
|
17290
|
+
log.info(`Cleaning up temporary branch "${tempBranch}"...`);
|
|
17291
|
+
await deleteBranch(tempBranch, true);
|
|
17292
|
+
} else {
|
|
17293
|
+
if (originalBranch) {
|
|
17294
|
+
const currentBranch = await getCurrentBranch();
|
|
17295
|
+
if (currentBranch !== originalBranch) {
|
|
17296
|
+
await checkout(originalBranch);
|
|
17297
|
+
}
|
|
17238
17298
|
}
|
|
17239
17299
|
}
|
|
17240
17300
|
} catch (finalError) {
|
|
17241
17301
|
log.error(`Error during final cleanup: ${finalError}`);
|
|
17242
17302
|
log.info("Some manual cleanup may be required.");
|
|
17303
|
+
if (tempBranch) {
|
|
17304
|
+
log.info(`You can manually delete the temp branch with: git branch -D ${tempBranch}`);
|
|
17305
|
+
}
|
|
17243
17306
|
}
|
|
17244
17307
|
}
|
|
17245
17308
|
};
|
|
@@ -18690,6 +18753,8 @@ Operation details:`);
|
|
|
18690
18753
|
var import_cli_table33 = __toESM(require_table(), 1);
|
|
18691
18754
|
var multiBranch = async (options) => {
|
|
18692
18755
|
let operationState = null;
|
|
18756
|
+
let tempBranch = null;
|
|
18757
|
+
let sourceOriginalBranch = null;
|
|
18693
18758
|
if (options.json) {
|
|
18694
18759
|
setSilent(true);
|
|
18695
18760
|
}
|
|
@@ -18706,7 +18771,37 @@ var multiBranch = async (options) => {
|
|
|
18706
18771
|
if (options.pr && options.draftPr) {
|
|
18707
18772
|
throw new Error("Cannot use both --pr and --draft-pr options");
|
|
18708
18773
|
}
|
|
18709
|
-
if (
|
|
18774
|
+
if (options.source) {
|
|
18775
|
+
if (await hasStagedChanges()) {
|
|
18776
|
+
throw new Error("Cannot use --source when there are staged changes. " + "Either commit/unstage your changes first, or omit --source to use staged files.");
|
|
18777
|
+
}
|
|
18778
|
+
sourceOriginalBranch = await getCurrentBranch();
|
|
18779
|
+
log.info(`Extracting changes from source: ${options.source}`);
|
|
18780
|
+
const defaultBranch = await getDefaultBranch();
|
|
18781
|
+
const compareTarget = options.compareMain ? defaultBranch : undefined;
|
|
18782
|
+
if (compareTarget) {
|
|
18783
|
+
log.info(`Comparing ${options.source} against ${compareTarget}...`);
|
|
18784
|
+
}
|
|
18785
|
+
let sourceFiles = await getChangedFilesBetween(options.source, compareTarget);
|
|
18786
|
+
if (sourceFiles.length === 0) {
|
|
18787
|
+
throw new Error(`No changed files found in ${options.source}`);
|
|
18788
|
+
}
|
|
18789
|
+
sourceFiles = filterByPathPatterns(sourceFiles, options.pathPattern);
|
|
18790
|
+
if (sourceFiles.length === 0) {
|
|
18791
|
+
throw new Error(options.pathPattern ? `No changed files found matching pattern: ${options.pathPattern}` : `No changed files found in ${options.source}`);
|
|
18792
|
+
}
|
|
18793
|
+
log.info(`Found ${sourceFiles.length} changed file${sourceFiles.length !== 1 ? "s" : ""} in source`);
|
|
18794
|
+
tempBranch = `cg-temp-${Date.now()}`;
|
|
18795
|
+
log.info(`Creating temporary branch "${tempBranch}" from "${defaultBranch}"...`);
|
|
18796
|
+
await checkout(defaultBranch);
|
|
18797
|
+
await createBranch(tempBranch);
|
|
18798
|
+
log.info("Extracting files from source...");
|
|
18799
|
+
await extractFilesFromRef(options.source, sourceFiles);
|
|
18800
|
+
await stageFiles(sourceFiles);
|
|
18801
|
+
log.info(`Files extracted and staged on temporary branch. Proceeding with multi-branch split...
|
|
18802
|
+
`);
|
|
18803
|
+
}
|
|
18804
|
+
if (!options.source && await hasUnstagedChanges()) {
|
|
18710
18805
|
const unstagedFiles = await getUnstagedFiles();
|
|
18711
18806
|
log.warn("Warning: Unstaged changes detected (these will be ignored):");
|
|
18712
18807
|
unstagedFiles.forEach((file) => log.warn(` - ${file}`));
|
|
@@ -18926,7 +19021,8 @@ Summary:`));
|
|
|
18926
19021
|
pathPattern: options.pathPattern,
|
|
18927
19022
|
exclusive: options.exclusive,
|
|
18928
19023
|
coOwned: options.coOwned,
|
|
18929
|
-
json: options.json
|
|
19024
|
+
json: options.json,
|
|
19025
|
+
prBody: options.prBody
|
|
18930
19026
|
});
|
|
18931
19027
|
results.push(result);
|
|
18932
19028
|
}
|
|
@@ -19042,6 +19138,23 @@ Manual recovery options:`);
|
|
|
19042
19138
|
}
|
|
19043
19139
|
}
|
|
19044
19140
|
process.exit(1);
|
|
19141
|
+
} finally {
|
|
19142
|
+
if (tempBranch) {
|
|
19143
|
+
try {
|
|
19144
|
+
if (sourceOriginalBranch) {
|
|
19145
|
+
const currentBranch = await getCurrentBranch();
|
|
19146
|
+
if (currentBranch !== sourceOriginalBranch) {
|
|
19147
|
+
log.info(`Returning to original branch "${sourceOriginalBranch}"...`);
|
|
19148
|
+
await checkout(sourceOriginalBranch);
|
|
19149
|
+
}
|
|
19150
|
+
}
|
|
19151
|
+
log.info(`Cleaning up temporary branch "${tempBranch}"...`);
|
|
19152
|
+
await deleteBranch(tempBranch, true);
|
|
19153
|
+
} catch (cleanupError) {
|
|
19154
|
+
log.warn(`Failed to clean up temporary branch "${tempBranch}": ${cleanupError}`);
|
|
19155
|
+
log.info(`You can manually delete it with: git branch -D ${tempBranch}`);
|
|
19156
|
+
}
|
|
19157
|
+
}
|
|
19045
19158
|
}
|
|
19046
19159
|
};
|
|
19047
19160
|
|
|
@@ -19235,7 +19348,7 @@ Next steps:`);
|
|
|
19235
19348
|
}
|
|
19236
19349
|
};
|
|
19237
19350
|
// package.json
|
|
19238
|
-
var version = "2.
|
|
19351
|
+
var version = "2.2.0";
|
|
19239
19352
|
|
|
19240
19353
|
// src/commands/version.ts
|
|
19241
19354
|
function getVersion() {
|
|
@@ -19297,7 +19410,7 @@ program2.command("list").description("Lists all git changed files by CODEOWNER")
|
|
|
19297
19410
|
pathPattern: pattern
|
|
19298
19411
|
});
|
|
19299
19412
|
});
|
|
19300
|
-
program2.command("branch").description("Create new branch with codeowner changes").argument("[pattern]", "Path pattern to filter files (micromatch syntax, comma-separated)").requiredOption("-i, --include <patterns>", "Code owner pattern to filter files").requiredOption("-b, --branch <branch>", "Branch name").requiredOption("-m, --message <message>", "Commit message").option("-n, --no-verify", "Skip lint-staged or any other ci checks").option("-p, --push", "Push branch to remote after commit").option("-r, --remote <remote>", "Remote name to push to", "origin").option("-u, --upstream <upstream>", "Upstream branch name (defaults to local branch name)").option("-f, --force", "Force push to remote").option("-k, --keep-branch-on-failure", "Keep the created branch even if operation fails").option("--append", "Add commits to existing branch instead of creating a new one").option("--pr", "Create a pull request after pushing (requires --push)").option("--draft-pr", "Create a draft pull request after pushing (requires --push)").option("-e, --exclusive", "Only include files where the owner is the sole owner (no co-owners)").option("-c, --co-owned", "Only include files with multiple owners (co-owned files)").option("--dry-run", "Preview the operation without making any changes").option("--json", "Output results as JSON (suppresses all other output)").action((pattern, options) => {
|
|
19413
|
+
program2.command("branch").description("Create new branch with codeowner changes").argument("[pattern]", "Path pattern to filter files (micromatch syntax, comma-separated)").requiredOption("-i, --include <patterns>", "Code owner pattern to filter files").requiredOption("-b, --branch <branch>", "Branch name").requiredOption("-m, --message <message>", "Commit message").option("-n, --no-verify", "Skip lint-staged or any other ci checks").option("-p, --push", "Push branch to remote after commit").option("-r, --remote <remote>", "Remote name to push to", "origin").option("-u, --upstream <upstream>", "Upstream branch name (defaults to local branch name)").option("-f, --force", "Force push to remote").option("-k, --keep-branch-on-failure", "Keep the created branch even if operation fails").option("--append", "Add commits to existing branch instead of creating a new one").option("--pr", "Create a pull request after pushing (requires --push)").option("--draft-pr", "Create a draft pull request after pushing (requires --push)").option("--pr-body <body>", "Custom PR body text (overrides repo PR template, requires --pr or --draft-pr)").option("-e, --exclusive", "Only include files where the owner is the sole owner (no co-owners)").option("-c, --co-owned", "Only include files with multiple owners (co-owned files)").option("--dry-run", "Preview the operation without making any changes").option("--json", "Output results as JSON (suppresses all other output)").option("-s, --source <source>", "Source branch or commit to extract changes from (creates a temp branch from the default branch)").option("--compare-main", "Compare source against main branch instead of detecting merge-base (use with --source)").action((pattern, options) => {
|
|
19301
19414
|
if (options.exclusive && options.coOwned) {
|
|
19302
19415
|
console.error("Error: Cannot use both --exclusive and --co-owned options");
|
|
19303
19416
|
process.exit(1);
|
|
@@ -19307,7 +19420,7 @@ program2.command("branch").description("Create new branch with codeowner changes
|
|
|
19307
19420
|
pathPattern: pattern
|
|
19308
19421
|
});
|
|
19309
19422
|
});
|
|
19310
|
-
program2.command("multi-branch").description("Create branches for all codeowners").argument("[pattern]", "Path pattern to filter files (micromatch syntax, comma-separated)").requiredOption("-b, --branch <branch>", "Base branch name (will be suffixed with codeowner name)").requiredOption("-m, --message <message>", "Base commit message (will be suffixed with codeowner name)").option("-n, --no-verify", "Skip lint-staged or any other ci checks").option("-p, --push", "Push branches to remote after commit").option("-r, --remote <remote>", "Remote name to push to", "origin").option("-u, --upstream <upstream>", "Upstream branch name pattern (defaults to local branch name)").option("-f, --force", "Force push to remote").option("-k, --keep-branch-on-failure", "Keep created branches even if operation fails").option("-d, --default-owner <defaultOwner>", "Default owner to use when no codeowners are found for changed files").option("--ignore <patterns>", "Comma-separated patterns to exclude codeowners (e.g., 'team-a,team-b')").option("--include <patterns>", "Comma-separated patterns to include codeowners (e.g., 'team-*,@org/*')").option("--append", "Add commits to existing branches instead of creating new ones").option("--pr", "Create pull requests after pushing (requires --push)").option("--draft-pr", "Create draft pull requests after pushing (requires --push)").option("-e, --exclusive", "Only include files where each owner is the sole owner (no co-owners)").option("-c, --co-owned", "Only include files with multiple owners (co-owned files)").option("--dry-run", "Preview the operation without making any changes").option("--json", "Output results as JSON (suppresses all other output)").action((pattern, options) => {
|
|
19423
|
+
program2.command("multi-branch").description("Create branches for all codeowners").argument("[pattern]", "Path pattern to filter files (micromatch syntax, comma-separated)").requiredOption("-b, --branch <branch>", "Base branch name (will be suffixed with codeowner name)").requiredOption("-m, --message <message>", "Base commit message (will be suffixed with codeowner name)").option("-n, --no-verify", "Skip lint-staged or any other ci checks").option("-p, --push", "Push branches to remote after commit").option("-r, --remote <remote>", "Remote name to push to", "origin").option("-u, --upstream <upstream>", "Upstream branch name pattern (defaults to local branch name)").option("-f, --force", "Force push to remote").option("-k, --keep-branch-on-failure", "Keep created branches even if operation fails").option("-d, --default-owner <defaultOwner>", "Default owner to use when no codeowners are found for changed files").option("--ignore <patterns>", "Comma-separated patterns to exclude codeowners (e.g., 'team-a,team-b')").option("--include <patterns>", "Comma-separated patterns to include codeowners (e.g., 'team-*,@org/*')").option("--append", "Add commits to existing branches instead of creating new ones").option("--pr", "Create pull requests after pushing (requires --push)").option("--draft-pr", "Create draft pull requests after pushing (requires --push)").option("--pr-body <body>", "Custom PR body text (overrides repo PR template, requires --pr or --draft-pr)").option("-e, --exclusive", "Only include files where each owner is the sole owner (no co-owners)").option("-c, --co-owned", "Only include files with multiple owners (co-owned files)").option("--dry-run", "Preview the operation without making any changes").option("--json", "Output results as JSON (suppresses all other output)").option("-s, --source <source>", "Source branch or commit to split (extracts changes onto a temp branch from the default branch)").option("--compare-main", "Compare source against main branch instead of detecting merge-base (use with --source)").action((pattern, options) => {
|
|
19311
19424
|
if (options.exclusive && options.coOwned) {
|
|
19312
19425
|
console.error("Error: Cannot use both --exclusive and --co-owned options");
|
|
19313
19426
|
process.exit(1);
|