😎

中級Git操作

2024/05/01に公開

今回の記事の内容はGitHub共同創業者のScott Chacon氏の「Pro Git」と同氏の今年の「So You Think You Know Git」(Gitがわかっているとでも思っているか?)発表をベースにしている。

コンフィグ

ここでコンフィグにてデフォルトとして指定して損がないオプションをいくつか紹介します。

git rerere

git rerereは"reuse recorded resolution"(記録ずみ解決方法を再利用)の略語になっている。
名の通りマージコンフリクトがどう解消されたかを記録し、次に同じようなコンフリクトが発生した際、同様の解決方法を自動的に適用するためのコマンドです。
また、基本的にデフォルトにしてもときに差し支えないため、ぜひgit config --global rerere.enabled trueを実行してみてください。

git maintenance

あとはgit maintenance startを実行すれば、レポジトリデータを追加するコマンド(git addgit fetchなど)が最適化できます。
厳密にいえば、このコマンドは裏で一時間ごとリモートをフェッチするcronジョブを用意します。

Gitエイリアス

Bashやzshでgitのエイリアスを指定する他、git config --global alias.<alias> <command>も使える。動作は普通のエイリアスとほぼ一緒だが、ビックリマークをコマンドの前に入れるとスクリプトを実行することができます。たとえば:

  • git config --global alias.staash 'stash --all'を指定すれば、git staashでコマンドが実行します
  • git config --global alias.bb !my-script.shを指定すれば、git bbでスクリプトが実行します

ブランチ

git branch -aでローカルとリモートのブランチを一括表示できる。リモートブランチ(つまりローカルにダウンロードしていないブランチ)は赤色になります。

だが、ブランチ一覧が縦方向に伸びるとスクロールせずに表示できる情報は必要以上に限られています。この不便をなくすにはgit config --global column.ui autoで一覧を表状に変更します。

また、git branchを使う際、現在担当している課題と過去の課題を指しているブランチを区別したほうが便利なのではないでしょうか。このオプションはgit config --global branch.sort -committerdateで設定できます。

これでremotes/origin/HEAD/main/revert-12938などのブランチが作業ブランチのlatestにない変更を持っていることが一目でわかります。

基本操作

  • git stash --all
    無視中、もしくは登録していないファイルもスタッシュする。

  • git switch
    ブランチ切り替え専用のコマンド。git checkout と違ってコミットに移動させることはできない。

  • git restore
    ファイルの変更を取り消す。git reset と違って現コミット以前のコミットにワーキングディレクトリを戻すことはできない。

    git checkout / switch / restore / reset の関係を表す図:
    git restore/reset/switch/checkoutの関係

  • git push --force-with-lease vs --force
    git push --force を使うと他人の変更を上書きする恐れがあるため、--force-with-lease はまず上書きされるコミットのハッシュが記録したほうと同じか確認する。異なっていれば他人のコミットのため、上書きを中止する。
    要は、もう --force を使う理由はない。

ログ表示

  • git blame -L と git log -L
    いずれもファイル全体ではなく、特定の「段落」を表示する。blame の場合、段落を最後に変更した人の名前を表示する。log の場合、指定した範囲のコードが変更されたコミットの差分を表示する。
  • git blame -w -C -C -C
    別のファイルからコードをコピペすることはよくありますが、その際、git blame はあくまで真犯人のコードをコピペした人に濡れ衣を着せる。
    そうならないように、-C を追加しましょう:
    • 一回指定すると、同じコミットで編集されたファイルからのコピペを検知する
    • 二回指定すると、当ファイルを作成したコミットにおける他ファイルからのコピペを検知する
    • 三回指定すると、すべてのコミットにおけるいかなるコピペを検知する(少々時間かかる)
  • git log -S <regex> -p
    • -p はパッチの内容を表示する
    • -S を使えば、<regex> に当たる変更しか表示されない。git log の出力を絞るいい方法
    • git grep という手もあるが、削除された行は表示されない
  • git diff --word-diff
    • 変更された単語を細かく表示する
      単語ごとの git diff
  • git log --oneline --graph --all
    • 綺麗かつ包括的なコミットグラフを端末に表示する
      コミットグラフの例
GitHubで編集を提案

Discussion