気分転換といえばGit。ということでGitを触ってた。
僕がGitでよくやる操作があって、それは複数のコマンドを叩いてるんだけど、簡単にできるものが用意されてるだろうなぁとずっと思っていて、やっと調べることにした。自分用メモ。
トラッキングせずにブランチを作りたい
リモートブランチをトラッキングするのは、あまり好きではないので、切り離してブランチを作りたくて、こうしてた↓
git switch -d origin/<リモートブランチ名>
でDETACHED HEADの状態にするgit switch -c <ローカルブランチ名>
でカレントコミットから作成するとリモートブランチをトラッキングしない
手元に fastify のリポジトリがあったので、このリポジトリで試すことにする。
❯ git switch -d origin/next Previous HEAD position was 4415c2fb chore: add github sponsor (#5293) HEAD is now at c30992b5 feat: align fastify.hasRoute to fmw.hasRoute (#5102) ❯ git switch -c sample Switched to a new branch 'sample' ❯ git branch -vv main 4415c2fb [origin/main] chore: add github sponsor (#5293) * sample c30992b5 feat: align fastify.hasRoute to fmw.hasRoute (#5102)
こんなふうにして、トラッキングしないローカルブランチを作ってた。
もしくはこうしてた。
git switch -c <ローカルブランチ名> -d origin/<リモートブランチ名>
でトラッキングした状態になるgit branch --unset-upstream
でトラッキングを外す
さっきのブランチを消しておく(これ以降もやってるけどもう書かない)
❯ git switch main && git branch -D sample Switched to branch 'main' Your branch is up to date with 'origin/main'. Deleted branch sample (was c30992b5).
リモートブランチからローカルブランチを作る。
❯ git switch -c sample origin/next branch 'sample' set up to track 'origin/next'. Switched to a new branch 'sample' ❯ git branch -vv main 4415c2fb [origin/main] chore: add github sponsor (#5293) * sample c30992b5 [origin/next] feat: align fastify.hasRoute to fmw.hasRoute (#5102)
↑この時点では origin/next
をトラッキングしてる。
❯ git branch --unset-upstream ❯ git branch -vv main 4415c2fb [origin/main] chore: add github sponsor (#5293) * sample c30992b5 feat: align fastify.hasRoute to fmw.hasRoute (#5102)
これでトラッキングが外れた。
調べた
--no-track
オプションがあった。もっとはやくに調べるべきだったよね。それはそう。
https://git-scm.com/docs/git-switch#Documentation/git-switch.txt---no-track
--no-track
を使ってみよう。
❯ git switch --no-track -c sample origin/next Switched to a new branch 'sample' ❯ git branch -vv main 4415c2fb [origin/main] chore: add github sponsor (#5293) * sample c30992b5 feat: align fastify.hasRoute to fmw.hasRoute (#5102)
便利!エイリアスを登録した。いまさらだけど switch
自体も登録した。
❯ git config --global alias.sw switch ❯ git config --global alias.swn 'switch --no-track' ❯ git config --list | grep 'alias\.sw' alias.sw=switch alias.swn=switch --no-track
こんな感じで使える。便利!
❯ git swn -c sample origin/next Switched to a new branch 'sample' ❯ git branch -vv main 4415c2fb [origin/main] chore: add github sponsor (#5293) * sample c30992b5 feat: align fastify.hasRoute to fmw.hasRoute (#5102)
よし。これでいこ。
ついでに git branch
のエイリアスも作っといた。スイッチせずにブランチを作りたいとき用。
❯ git config --global alias.br branch ❯ git config --global alias.brn 'branch --no-track' ❯ git config --list | grep 'alias\.br' alias.br=branch alias.brn=branch --no-track
よし。
と書きながら思ったんだけど、ブランチを指定するんじゃなくてコミットを指定したら最初からトラッキングされないね。
❯ git switch -c sample c30992b5 Switched to a new branch 'sample' ❯ git branch -vv main 4415c2fb [origin/main] chore: add github sponsor (#5293) * sample c30992b5 feat: align fastify.hasRoute to fmw.hasRoute (#5102)
まぁ、ブランチからできたら便利なので、--no-track
使っていこう。
カレントブランチのポインタを移動させたい
カレントブランチの名前をそのままにして、別のコミットを指すように移動したいなってときも結構あって、こうしてた。
git switch -d <移動先のコミット>
で移動先のコミットにDETACHED HEAD状態で移動するgit branch -D <ローカルブランチ>
でローカルブランチを削除git switch -c <ローカルブランチ>
でローカルブランチを作成
# 準備。このsampleブランチが別のコミットを指すようにしたい ❯ git swn -c sample origin/next Switched to a new branch 'sample' # 移動先のコミットに移動(コミットハッシュは適当に選んだ) ❯ git sw -d 79042e60 HEAD is now at 79042e60 fix: ensure `onListen` hooks are called when they should be (#5273) # ローカルブランチを削除 ❯ git br -D sample Deleted branch sample (was c30992b5). # ローカルブランチを作成 ❯ git sw -c sample Switched to a new branch 'sample' ❯ git br -vv main 4415c2fb [origin/main] chore: add github sponsor (#5293) * sample 79042e60 fix: ensure `onListen` hooks are called when they should be (#5273)
どうしてこんな面倒なことを、これまで調べようとしなかったのか。
調べた
git reset --hard
でできるのかー。
❯ git swn -c sample origin/next Switched to a new branch 'sample' ❯ git reset --hard 79042e60 HEAD is now at 79042e60 fix: ensure `onListen` hooks are called when they should be (#5273) ❯ git br -vv main 4415c2fb [origin/main] chore: add github sponsor (#5293) * sample 79042e60 fix: ensure `onListen` hooks are called when they should be (#5273)
うーん。でも、git reset --hard
って作業がふっとぶ可能性があって苦手なんだよなぁ。まだコミットしてない変更があったら止まってほしいな・・・。と思ってたら、git switch
に -C
オプションがあった。force createかー。見てみよっと。
https://git-scm.com/docs/git-switch#Documentation/git-switch.txt--Cltnew-branchgt
❯ git swn -c sample origin/next Switched to a new branch 'sample' ❯ git sw -C sample 79042e60 Reset branch 'sample' ❯ git br -vv main 4415c2fb [origin/main] chore: add github sponsor (#5293) * sample 79042e60 fix: ensure `onListen` hooks are called when they should be (#5273)
ふむふむ。いい動き。カレントブランチでも問題なく移動できてる。
で、肝心の、コミットしていない変更がある場合はどうなるんだろう?
❯ git swn -c sample origin/next Switched to a new branch 'sample' ❯ echo "sample" >> README.md ❯ git status On branch sample Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: README.md no changes added to commit (use "git add" and/or "git commit -a")
これで README.md
に変更がある状態になった。移動してみよう。
❯ git sw -C sample 79042e60
error: Your local changes to the following files would be overwritten by checkout:
README.md
Please commit your changes or stash them before you switch branches.
Aborting
わー。止まってくれたー。やったー!
まとめ
自分の環境だと、こうなった。
- トラッキングせずにブランチを作りたい →
git swn -c <ローカルブランチ名> <リモートブランチ名>
- カレントブランチのポインタを移動させたい →
git sw -C <ローカルブランチ名> <移動先>
結論 → git switch
はいいぞ。