カルボナーラ街道

計測と観察

dotfiles盆栽記7: デフォルトブランチ名を知らない状態でgit switchする

一年ぶりの盆栽。

github.com

実行環境

$git --version
git version 2.45.1

モチベーション

普段、デフォルトブランチ名が異なるリポジトリ間を行き来している。git switchする時にデフォルトブランチ名を思い出す必要があって非効率。エイリアスを作成しよう。

リモートからデフォルトブランチを取得して切り替え

$git switch $(git remote show origin | grep "HEAD" | cut -d" " -f5)

まぁいけるが、リモートに取得しに行っているので明らかに遅い。

$time sh -c 'git switch $(git remote show origin | grep "HEAD" | cut -d" " -f5) > /dev/null 2>&1'
sh -c   0.06s user 0.03s system 4% cpu 2.120 total

ローカルでデフォルトブランチを取得して切り替え

先の実行結果では最新の状態を取得できるが、そうそうデフォルトブランチは変わらんでしょう。ローカルでどうにかできないか。

検討が付かず、"git how to get default branch" とかで検索すると、git symbolic-ref が使われているのがやたら出てきた。使ったことがないのでドキュメントを読む。

git-scm.com

git-symbolic-ref - Read, modify and delete symbolic refs

symbolic refsの読取や変更、削除ができる。...symbolic refsとは?ありがたいことに公式の日本語ドキュメントに言及があった。

git-scm.com

symbolic-ref と呼ばれる、編集を安全に行うためのコマンドが存在します。 このコマンドを使ってHEADの値を読み取ることができます。

なるほど。HEADを読めるならいける。

$git symbolic-ref refs/remotes/origin/HEAD
refs/remotes/origin/{デフォルトブランチ}

いけた。後は加工してswitchさせれば良い。

$git switch test3
Switched to branch 'test3'

$git switch $(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@')
Switched to branch 'develop'
Your branch is up to date with 'origin/develop'.

$git branch | grep "*"
* develop

無事デフォルトブランチを知らなくてもデフォルトブランチにgit switchできた。副産物として、sedの区切り文字はスラッシュじゃなくてもOKということを知った。今回のようにpattern部分にスラッシュが入るとsedの区切り文字と区別がつかなくなって、エスケープシーケンスすると見づらくなるので置き換えられるのは便利。今回は@を使ったが、# でもいけた。

肝心の実行時間は通信をしていないのでやはり早い。

$time sh -c 'git switch $(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@') > /dev/null 2>&1'
sh -c   0.01s user 0.01s system 82% cpu 0.026 total