もりはやメモφ(・ω・ )

インフラなエンジニアからSREへ

AWS CodeCommitで不要なブランチを一気に削除する

プライベートなGitLabからCodeCommitへ移設したとあるリポジトリについて、大量のブランチがあって今すぐ消したい!!となったので簡単なシェル芸で対応したのでメモ。

課題: 直面したブランチ多すぎ問題

例えばこんな感じだった。

  • 謎のポリシーでブランチを消さない文化で育ってしまったリポジトリ
  • ブランチ確認のページ数がたくさん
  • CodeCommitのGUIでは、ブランチ削除は1つずつしかできない <-たくさんやるには超大変

f:id:morihaya:20200817224106p:plain

大量にあるブランチに対して一つずつ確認画面でぽちぽちやるのは辛すぎる f:id:morihaya:20200817224515p:plain

対策: AWS CLIと簡単なシェル芸

結論としてはこう。

# 対象のリポジトリ名を設定
REPOSITORY=morihaya-test

# ループで回す
for BRANCH in $(aws codecommit list-branches --repository-name ${REPOSITORY} | jq .branches[] -r | grep -vE "master|<消したくないブランチ>")
do
  aws codecommit delete-branch --repository-name ${REPOSITORY} --branch-name ${BRANCH}
done

雑な解説

以下でブランチ一覧を取得。

aws codecommit list-branches --repository-name ${REPOSITORY}

jqに渡してJSONからただの文字列の一覧に皮むき。-r でクォーテーションを外したのはただの癖。

 | jq .branches[] -r 

以下は削除したくないブランチを除外するためのgrep。masterブランチは守られているので実は除外不要。

| grep -vE "master|<消したくないブランチ>"

実際に削除を行うのはこのコマンド。

aws codecommit delete-branch --repository-name ${REPOSITORY} --branch-name ${BRANCH}

余談

余談1

実はmasterブランチも勢いで消してしまいかけたのですが、Default Branchは以下のエラーで守られているので安心でした。

An error occurred (DefaultBranchCannotBeDeletedException) when calling the DeleteBranch operation: The current default branch refs/heads/master cannot be deleted

余談2

作業自体は会社のリポジトリでしたがさすがにスクショはまずかったので、テスト用のリポジトリを作成してブランチを増やしました。 コマンドは対策と似たようなシェル芸です。

# 対象のリポジトリ名を設定
REPOSITORY=morihaya-test

# 複製するCommitのIDを指定する
COMMITID=XXXXXXXXXXX

# ループで回す
for NO in $(seq 1 50)
do
  aws codecommit create-branch --repository-name ${REPOSITORY} --commit-id ${COMMITID} --branch-name test-${NO}
done

余談3

削除した時はメッセージがでるが、作成した時はなにもでないらしいです。 aws-cliのバージョンは2.0.40で確認。

bash-3.2$ aws --version
aws-cli/2.0.40 Python/3.8.5 Darwin/19.6.0 source/x86_64

削除する時は以下のようなメッセージがでる。

{
    "deletedBranch": {
        "branchName": "test-5",
        "commitId": "XXXXXXXXXXXXXXXXXXXX"
    }
}

まとめ

作業時間短縮のための雑なCLIは正義だと思っているし、ちょっとしたシェル芸は身を助けますね。