Committing Changes
polyrepo commit — commit what npm audit fix, npm update or sync-deps left in a repo's working tree, the way that repo allows.
polyrepo commit [options]Many repos refuse commits straight to the default branch: a rule on the host demands a pull (merge) request first. A plain git commit and git push then fails at the very end, and the work sits on a local master that can never be pushed. commit looks at the rules before it commits and picks the route that will be accepted.
- Lists the repos that have uncommitted changes to
package.jsonor the lock files (--scope allwidens that to every tracked change) in a checkbox;--packagesskips the list. - Asks for the commit message (default
chore: update dependencies; with--yesand no--messagethe default is used). The message is also the title of a pull request. - For each selected repo, one at a time, it decides where the commit goes — see below — and, unless
--yes, asks to confirm that exact route first.
Where the commit goes
- On a feature branch (any branch that is not the default one) the commit simply goes there, and is pushed.
- On the default branch polyrepo reads the host's rules and chooses:
- Direct commits are allowed — it commits on the default branch and pushes.
- A pull/merge request is required, or the rules cannot be read — it creates a branch (
chore/<message>-<date>, or--branch), commits there, pushes it, opens a PR/MR into the default branch and goes back to the default branch, which stays exactly as it was. The PR/MR is never merged by this command: review it on the host.
- A direct push that the host refuses anyway (the rules are not always readable, and some hosts only say no at push time) is recovered automatically: the commit is moved to a branch, the local default branch is put back at
origin, and the PR/MR is opened. This only happens when the commit is the one thing the local default branch has ahead oforigin; otherwise nothing is moved, and the message says what to do by hand.
What counts as a rule
- GitHub — repository rulesets that require a pull request, status checks or restrict updates; classic branch protection with required reviews, status checks or push restrictions. Rulesets can be read with ordinary access; classic protection only with admin rights, so a protected branch whose rules are hidden from you counts as “unknown”, and unknown always takes the branch route.
- GitLab — the push access level of the protected branch compared with your own role in the project. “Only Maintainers may push” means a merge request for a Developer; “nobody” means a merge request for everyone.
Options
--message <text> (-m)
The commit message, and the title of the PR/MR. Default: chore: update dependencies.
--scope <manifest|all>
What is committed. manifest (the default) is package.json and the lock files (package-lock.json, npm-shrinkwrap.json, pnpm-lock.yaml, yarn.lock) of the package. all is every tracked change in the package folder; untracked files are never added.
--mode <auto|direct|branch>
The route on the default branch. auto (the default) lets the rules decide. direct commits and pushes straight to the default branch (and falls back to a branch if the push is refused). branch always uses a new branch.
--branch <name>
The name of the new branch. Default: chore/<message>-<date>, for example chore/npm-audit-fix-20261008.
--no-push
Only commit; push nothing and open nothing.
--no-pr
Push the new branch but do not open a PR/MR.
--stay
Stay on the new branch afterwards instead of going back to the default branch.
--dry-run
Print every step without committing, pushing or opening anything.
--packages <a,b,c>
Package list instead of the interactive checkbox.
--yes
Skip the confirmation and, without --message, use the default message.
Example output — a repo whose default branch requires pull requests:
[1/1] color-value-tools
package.json, package-lock.json → a new branch chore/npm-audit-fix-20261008 and a PR into master
✓ master does not take direct commits (a pull request is required (repository rules)).
✓ Using a new branch chore/npm-audit-fix-20261008 and a PR.
$ git checkout -b chore/npm-audit-fix-20261008
$ git add -- package.json package-lock.json
$ git commit -m chore: npm audit fix -- package.json package-lock.json
✓ Committed package.json, package-lock.json: chore: npm audit fix
$ git push -u origin chore/npm-audit-fix-20261008
✓ Pushed chore/npm-audit-fix-20261008 to origin.
✓ Opened PR #12: https://github.com/you/color-value-tools/pull/12
✓ Back on master.
Open for review:
color-value-tools: https://github.com/you/color-value-tools/pull/12Example:
polyrepo commit
# one package, no questions, the rules decide the route
polyrepo commit --packages color-value-tools --yes
# always through a branch, push it, but open the PR yourself
polyrepo commit --mode branch --no-pr
# see the plan first
polyrepo commit --dry-runAfter the PR/MR is merged on the host, polyrepo switch-default brings the local default branch up to date.
Problems and exit codes
- Nothing to commit (no changes in
package.jsonor the lock files): reported, exit code0. Use--scope allif the changes are elsewhere. - A failed
git add,commit,checkoutorpushis reported, and the process exits with1once the remaining packages have been tried. A commit made before a failed push is left on its local branch. - An unknown
--scopeor--modevalue: exit code2. - The same flow is behind Commit… in the web interface, which also shows the rules before you choose.