Rename your default branch on GitHub easily. By default it renames master
to main
, but is configurable using the --new
and --old
flags.
If provided with an --org
argument, it will run on all repositories within that organisation. Alternatively, you can provide a --repo
argument to edit a single repo.
For each repo, this tool will:
- Create a new branch at the same commit SHA as the old one
- Update all open pull requests to point at the new branch
- Update the default branch for the repo
- Delete the old branch
- Update known URL patterns in source files
- Update any branch protections for
$old
to$new
. (This does not work with patterns, it has to be an exact match)
npm install -g github-default-branch
git clone https://github.com/mheap/github-default-branch.git
cd github-default-branch
npm ci
Create a personal access token with the repo
scope. This is the value for <token>
in the examples.
If you don't want your token to be stored in your shell history, you can set
GITHUB_TOKEN
in the environment and that will be read instead
# Rename master to main
github-default-branch --pat <token> --repo user/repo
# Rename dev to develop
github-default-branch --pat <token> --repo user/repo --old dev --new develop
# Rename all repos owned by an org
github-default-branch --pat <token> --org my-org-name
# Rename all repos owned by a user
github-default-branch --pat <token> --user my-user
Run with the --verbose
flag to see debug information
Flag | Description | Default |
---|---|---|
--pat | GitHub API Token | N/A |
--repo | The repo to update (format: user/repo) | N/A |
--user | Update all repos owned by the provided user (example: my-user) | N/A |
--org | Update all repos in the provided org (example: my-org-name) | N/A |
--team | Update all repos in the provided team (example: my-team-name), only usable in combination with org parameter | N/A |
--keep-old | Keep the old branch rather than deleting it | false |
--dry-run | Output log messages only. Do not make any changes | false |
--list-repos-only | List repos that would be affected, then exit | false |
--skip-forks | Skips forked repositories | false |
--skip-update-branch-protection | Skip updating branch protections | false |
--old | The name of the branch to rename | master |
--new | The new branch name | main |
--confirm | Run without prompting for confirmation | false |
Part of this script checks for the existence of files and updates their contents. Replacements are the mechanism for these updates.
Each .js file in the src/replacements folder is given a chance to run during the content updating step of the script. Each file in src/replacements is expected to export a function, that function receives all of the options that are available to the outmost script.
If there is nothing to replace, then the script moves on to the next replacement.
Add a file to src/replacements with a .js extension
Like this:
module.exports = function ({
owner, // string - repo owner
repo, // string - repo name
old, // string - old branch name
target, // string - new branch name
octokit, // Octokit - oktokit instance
verbose, // boolean - verbose flag
isDryRun, // boolean - dry run flag
}) {
// code goes here
return {
path: "<path to file in repo>",
replacements: [
{
from: "<from pattern>",
to: "<to pattern>",
},
{
from: "<from pattern>",
to: "<to pattern>",
},
],
};
};
The file with the path in your repo will have any line matching from
be swapped out with to
The replacement system gives you octokit, that's great! Unfortunately replacement functions do not currently support asynchronous calls, that's bad.