シェルでGithubリポジトリのmasterブランチの名前をmainブランチに変更する
はじめに
随分前のことですが、新規に作成される Github リポジトリのデフォルトブランチ名が master
から main
に変更となりました。
ところが既存の Github リポジトリは当然 master
というブランチ名のままです。
機会があれば昨今の風潮にのって一括修正しようかなぁ、と思っていましたが、ブログネタについでにシェルでブランチ名の変更を行ってみました。
大量に Github リポジトリを持っている組織などでも利用できるのではないでしょうか。
検証環境
$ uname -moi
x86_64 MacBookPro16,1 Darwin
$ bash -version | head -n 1
GNU bash, version 5.1.8(1)-release (x86_64-apple-darwin20.3.0)
$ git --version
git version 2.31.1
$ gh --version
gh version 1.10.2 (2021-05-19)
https://github.com/cli/cli/releases/tag/v1.10.2
今回利用するツール
今回は以下のツールを利用します。
git
: Gitgh
: GitHub CLI
作成したシェルスクリプト
コマンドを 1 つ 1 つ解説していこうかと思いましたが、作ってしまってそれをお見せしたほうが良いかと思いました。
作成したシェルスクリプトを掲載します。
master2main.sh
#!/usr/bin/env bash
# おまじない
set -o errexit
set -o nounset
# スクリプトを実行しているディレクトリが.git管理されていることが前提
[[ -d ./.git ]] || {
echo "[ERROR] Gitのワークディレクトリでスクリプトを実行してください。" >&2
exit 100
}
echo "=== START ==="
REPO=$(git remote get-url origin | grep -o '[^/:]\+/[^/:]\+$' | sed 's/\.git$//')
# upstreamリポジトリかどうかは適宜変更してください
REMOTE=origin
# まずはGitのリモートリポジトリの最新master情報を取得
git fetch "${REMOTE}" master
# masterブランチからmainブランチを分岐させる
git checkout -b main "${REMOTE}/master" \
--no-track
# mainブランチをリモートにプッシュ
git push -u "${REMOTE}" main
# リポジトリのHEADをmainブランチに切り替え
git remote set-head "${REMOTE}" main
# Github上のデフォルトブランチをmainブランチに切り替え
gh api -XPATCH "repos/${REPO}" -f default_branch=main >/dev/null
# Github上の全プルリクのbaseもmainブランチに切り替え
for NUM in $(
gh pr list -B master -L999 \
| cut -f 1
); do
gh api -XPATCH "repos/${REPO}/pulls/${NUM}" -f base=main >/dev/null
done
# Githのリモートリポジトリからmasterブランチを削除
git push \
--delete origin master
# ローカルのmasterブランチは必要があれば消してください
# git branch -D master
# 確認のためにGithubリポジトリのWebページを開くこともできます
# gh repo view --web
echo "=== FINISH ==="
使い方
使い方は簡単です。
master
ブランチを持っている Github ワークディレクトリ ( git clone
したディレクトリのこと。 .git
ディレクトリがあるはずですね。 ) で、スクリプトを実行するだけです。
$ pwd
/tmp/genzouw/my-repo
# シェルスクリプトはどこに置かれていても構いません
$ ~/bin/master2main.sh
=== START ===
From ssh://github.com/genzouw/my-repo
* branch master -> FETCH_HEAD
Switched to a new branch 'main'
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
remote:
remote: Create a pull request for 'main' on GitHub by visiting:
remote: https://github.com/genzouw/my-repo/pull/new/main
remote:
To ssh://github.com/genzouw/my-repo.git
* [new branch] main -> main
Branch 'main' set up to track remote branch 'main' from 'origin'.
To ssh://github.com/genzouw/my-repo.git
- [deleted] master
=== FINISH ===
# リポジトリがどうなったかを確認(ローカルのmasterブランチは一応残しています)
$ git branch -a
* main
master
remotes/origin/HEAD -> origin/main
remotes/origin/main
複数の Github リポジトリを一括更新する
対象となる Git ワークディレクトリの一覧があれば、ループで回して一括更新できるはずです。
dirs=(
dir_a
dir_b
dir_c
)
for dir in ${dirs[@]}; do
cd "${dir}"
~/bin/master2main.sh
done
main
ブランチへのリネーム後にメンバが実施する作業
以下のコマンドを実行し、 リモートリポジトリの main
ブランチ、master
ブランチへの修正をワークディレクトリに反映します。
$ git fetch --all --tags --prune
Fetching origin
From ssh://github.com/genzouw/sqlite
* [new branch] main -> origin/main
$ git branch -a
warning: ignoring broken ref refs/remotes/origin/HEAD
* master
remotes/origin/main
# 不要であればワークディレクトリ
$ git switch main
Branch 'main' set up to track remote branch 'main' from 'origin'.
Switched to a new branch 'main'
$ git branch -D master
Deleted branch master (was xxxxxxx).
せっかくなので Gist に公開しました
こちらはコメントが英語なので、苦手な方はエントリのコードを参照ください。
ひとこと
実際、これだけでは済まないですよね。
修正が必要だろうと思いつくものを上げると
- CI/CD パイプライン周り
- GitHub Actions
- Cloud Build
- CircleCI
- AWS や GCP の検証環境(もしブランチ名に依存していれば)
- Docker Hub
- Ansible Galaxy
- Slack 連携
1 リポジトリずつ、段階的に実施となるでしょう。
ディスカッション
コメント一覧
まだ、コメントがありません