.gitconfigを晒す
2020-12-14
azblob://2022/11/11/eyecatch/2020-12-14-share-gitconfig-000.png

はじめに

この記事はFIXER 2nd Advent Calendar 2020 (https://adventar.org/calendars/5752) 14日目の記事です。

TL;DR

最初にばーんと、.gitconfig の共有できそうな部分を晒します。git仙人なら、これだけでハハーンってなってくれるはず... 詳しい解説は、次の章から記載しています

[alias]
    pu = "!f(){ git push origin `git rev-parse --abbrev-ref HEAD` ${1}; git pr; }; f"
    ch = !git checkout
    addi = !git add -i
    dev = "!f(){ git ch develop; git pl; }; f"
    new = "!f(){ git ch -b feature/${1};};f"
    dev-rebase = "!f(){ git fetch origin develop; git rebase origin/develop;};f"
    co = "!f(){ git commit -m \"$(cat ~/.gitemoji | fzf | sed \"s/ - :.*//g\")${1}\";};f"
    cd = "!f(){ git ch $(git branch | sed \"s/* /  /g\" | fzf); };f"
    save = !git stash save
    load = "!f() { git stash apply --index $(git stash list | fzf | sed 's/stash@{//g' | sed \"s/}.*//g\"); }; f"
    pr = "!f() { echo PR Url: $(git remote show -n origin | grep \"Push  URL\" | sed \"s/.*URL: git@//g\" | sed \"s/\\.git//g\" | sed \"s/:/\\//\")/compare/develop...$(git rev-parse --abbrev-ref HEAD); }; f"
    pm = "!f() { b=`git rev-parse --abbrev-ref HEAD`; git dev; git branch -D $b; git pull; git ch $b;}; f"
    pl = !git pull --prune
    lg = !git log --all --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative
    amend = !git commit --amend
    re-continue = !git rebase --continue
    re-abort = !git rebase --abort
[merge]
    tool = vscode
[mergetool]
    prompt = false
    keepBackup = false
[mergetool "vscode"]
    cmd = '/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code' \"$MERGED\"
    trustExitCode = false

.gitconfigについて

こんにちは、20期入社の佐藤です。今回は、仕事で常に使うgitをもっと便利にするための自分の設定を晒すことにしました!

その前にgitconfigについてですね。gitconfig自体はユーザー固有の設定を保存しておくためのファイルで、.gitconfigの名前で保存されています。(グローバルなものはホームディレクトリ直下にあるかと)

で、この設定ファイルには、gitコマンド専用のエイリアスを設定することができ、これを利用することで、環境にクリーンに、かつ速度効率をあげることのできる自作コマンドとショートカットを作ることができます!(上のやつ、最後の方にそうではないやつもありますが、それはおまけ要素として最後に紹介します)

(ちなみに、構文等は解説しませんので、自分も作ってみたい!と思った方は、gitconfig alias 構文で検索して見てください)

Alias紹介

TL;DRで貼った.gitconfigのエイリアスを一個づつ紹介していこうと思います!([alias]と書かれたセクションです)

1. git pu

pu = "!f(){ git push origin `git rev-parse --abbrev-ref HEAD` ${1}; git pr; }; f`"

これは、git pushコマンドの短縮ですね。git rev-parse --abbrev-ref HEADはカレントブランチの名前を持ってくるコマンドで、ここのoriginを指定してpushしています。

${1} は git pu の後ろにある入力をつける部分です。(主に -f オプションをもらうのにつけてる)

git prコマンドに関しては、後述します。(端的に言うと、Pull RequestのURLを生成してくれるやつです)

2. git ch

ch = !git checkout

これはみたまんま、git checkoutコマンドの短縮です。人によっては、git coだったりで、個人差がめちゃくちゃ出てくるコマンドな気がします。

3. git addi

addi = !git add -i

gitのaddコマンドに対話式のCLIが標準でついてるのはご存知でしょうか?これは、それを呼び出すコマンドです。(一部だけ、addしたい、とかそう言う時に便利です。...えっ?VSCodeのsource control?知らない子ですね...)

4. git dev

dev = "!f(){ git ch develop; git pl; }; f"

弊社では、gitでfeatureブランチを採用しているのですが、そうすると一番行き来するのが、featureブランチとdevelopブランチです。それを短縮したコマンドですね。git plについては後述しますが、git pull --pruneをするコマンドですね。(developブランチに戻ったら pull するフローですね)

5. git new

new = "!f(){ git ch -b feature/${1};};f"

弊社では、gitでfeatureブランチ(以下略)。なので、featureブランチを作るのが、まず何よりはじめにやることです。このエイリアスでは git new hogehogeと打つと feature/hogehoge ブランチを作成して移動してくれます。

6. git dev-rebase

dev-rebase = "!f(){ git fetch origin develop; git rebase origin/develop;};f"

古いブランチになってくると、リベースをしてブランチを最新にしたいケースって多々あると思います。 その処理を1コマンドでぱっとやりたいなと思って登録したエイリアスです。originのdevelopブランチを最新にしてからリベースするコマンドです。

7. git co

(必須: fzf *1、.gitemoji *2)

co = "!f(){ git commit -m \"$(cat ~/.gitemoji | fzf | sed \"s/ - :.*//g\")${1}\";};f"

これは、コミット文字の先頭に絵文字を対話式に選択して実行するコマンドです。git co コミットメッセージ みたいな感じで使い、cliで絵文字を選ぶと、先頭にくっつけてからコミットしてくれます

コマンドを打って
fzfのcliで文字を入力すると
入力した文字で絞り込まれる!後は選べば絵文字がつくよ

...が、絵文字が一個しか入れられない、Enterを誤爆プッシュした時に勝手にコミットされちゃう等、正直最近このコマンドどうなん?って感じになってきてるので、この神コマンドを導入した方がおすすめです。

(*1 fzf: 入力のリストを受け取って、検索と直感的選択操作を提供するツールですがとても便利です。似たようなツールだと pecoとかも有名です。)

(*2 ホームディレクトリ直下に.gitemoji という絵文字と説明を 👽 - :alien: - Updating code due to external API changes. みたいな感じでまとめたリストファイルを作らないといけません。めんどくさいですね...)

8. git cd

(必須: fzf)

cd = "!f(){ git ch $(git branch | sed \"s/* /  /g\" | fzf); };f"

これもfzf使うやつですね!ブランチ名の一覧を出して、検索しながら移動先のブランチを決められるコマンドです。

9. git save

save = !git stash save

みたまんま、git stash saveを縮めたコマンドです。(git stash saveは今の作業状態を一時待避してくれるコマンドです、待避したのを戻すコマンドは後述します)

10. git load

(必須: fzf)

load = "!f() { git stash apply --index $(git stash list | fzf | 
sed 's/stash@{//g' | sed \"s/}.*//g\"); }; f"

git stash saveで待避した作業状態をfzfでいい感じに選んで、作業状態を戻すコマンドです。

11. git pr

pr = "!f() { echo PR Url: $(git remote show -n origin | grep \"Push  URL\" | 
sed \"s/.*URL: git@//g\" | sed \"s/\\.git//g\" | 
sed \"s/:/\\//\")/compare/develop...$(git rev-parse --abbrev-ref HEAD); }; f"

カレントブランチとリモートリポジトリの情報から、PullRequestのURLを生成して、コンソール上に出力してくれるエイリアスです。意識はしてませんが、一番便利に感じてるコマンドです。(かつ、一番全員の環境で動くかは怪しいコマンドでもありますが...)

前述の push コマンドに組み込んであるので、 git pu => URLが出力される => URLを command + click で一発でPR作成画面に => ストレスフリー!

12. git pm

pm = "!f() { b=`git rev-parse --abbrev-ref HEAD`; git dev; git branch -D $b; 
git pull; git ch $b;}; f"

それなりに使うんですが、これでいいのか怪しいコマンドです。remote環境でリベース(or マージ)されたブランチを最新にする時に、自分でマージせずに、最新のブランチに更新するコマンドです。

(内部的には、メインブランチにもどる => 最新にするブランチを削除 => メインブランチと最新にするブランチを更新 => 最新になったブランチに移動 をしてます)

13. git pl

pl = !git pull --prune

git pullを縮めたコマンドです。--pruneオプションは、リモートリポジトリ上で削除されたブランチ、ローカルリポジトリにも削除を反映してくれるやつです。ドライブの容量に不安のある方は是非。

14. git lg

lg = !git log --all --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset 
%s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative

はい。これは他の人にお勧めされたやつをそのまま、導入したやつです。こんな感じで、グラフィカルにコミットログを出力してくれます。





git lg の出力15. git amend
amend = !git commit --amend

直前のコミットメッセージを編集する amend オプションをまとめたエイリアスですね。次いきましょう
16. git re-continue
re-continue = !git rebase --continue

リベース中のコンフリを解消した後に、打つ git rebase --continue を短くしたやつですね。次いきましょう
17. git re-abort
re-abort = !git rebase --abort

リベースを取りやめたい時の git rebase --abort コマンドをみじかくしたやつですね。
おまけのmergetool
ここまでがエイリアス紹介でした!いや、疲れましたね...
さて、コーヒーブレイクに tl;dr にあった [merge] について解説して終わりにしましょう!
コンフリを解消するのに、下みたいなのをエディターで直していく必要があると思うんですが、VSCodeでやるとすんごいストレスフリーです。
<<<<<<< HEAD
# 作業ブランチでの変更内容
・・・
=======
# develop(マージしたブランチ)での変更内容
・・・
>>>>>>> develop

そこで、思うわけです。このプロジェクトVSCodeで開発してるけど、コンフリクトだけVSCodeで直したいよな〜、と。そこで、この設定を組み込みます。
[merge]
    tool = vscode
[mergetool]
    prompt = false
    keepBackup = false
[mergetool "vscode"]
    cmd = '${VSCodeの実行ファイルパス}' \"$MERGED\"
    trustExitCode = false

この設定を .gitconfig に追加して、コンフリが起こったローカルリポジトリで git mergetool のコマンドを押すと...?
そのリポジトリのコンフリ解消画面になったVSCodeが呼び出されるんですね。いいですね。ストレスフリーですね。
おわり