gitの「マージできない😧」に効くalias


タイトルは大げさでした。
「マージできない」問題を一発で解決するようなものではありません。

はじめに

このaliasは何処かで拾ったもので完全にn番煎じですが、これを使うようにしてから落ち着いてマージ作業が行えるようになりました。
ちょいちょいカスタマイズして現在の見た目に落ち着いていますので、使い所も含めて紹介します。

設定方法・使い方

~/.gitconfig
[alias]
    tree = log --graph --all --date=short --format=\"%x09%C(cyan)[%cd]%Creset %C(cyan bold)%<(20)%an%Creset%C(yellow)%h%Creset %C(magenta reverse)%d%Creset %s\"

使い方はgit treeと実行するだけです(表示内容はgoogletestのリポジトリから拝借させていただきました)。

GUIなツールでは良くある表示ですが、HEAD以外のブランチも含めて俯瞰(ふかん)しているのが特徴です。

使い時・使い所

git mergegit rebaseでCONFLICTしてパニックになる前に使いましょう。

手順としては一手間増えるのですが、git初心者にオススメするのは、

git pullではなくgit fetchを使う

ことです。

git pullというのは「git fetchgit mergeを同時に実行」するコマンドです。
git mergeは2つのブランチを合流させるコマンドで、これが(git pullにおいて)CONFLICTを生む原因です。

では、git fetchとは何でしょうか?
git fetchはローカルリポジトリをリモートリポジトリと同期するコマンドです。同期すると言ってもワーク領域は書き換えません。git branch -aなどで目にすることがあると思いますが、remotes/origin/mainなどの.gitディレクトリの中で管理されている領域を書き換えるだけです。

つまり、git fetchワーク領域への副作用が無いので気兼ねなく実行出来るのです。

利用シーン

  1. 2人が同時にmainブランチの同じファイル・同じ箇所に修正をする。
  2. 1人目が先にリモートリポジトリにpush。
  3. 2人目がリモートリポジトリにpushするが失敗、「git pullで変更を統合しろ(英語)」的なメッセージが出てくる。

ここで愚直にgit pullすると当然CONFLICTします。そこでgit fetchgit treeの出番になります。

$ git fetch
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 263 bytes | 13.00 KiB/s, done.
From github.com:utkamioka/example-git-tree
   8519b35..f387f46  main       -> origin/main
$ git tree
*       [2020-11-29] Yutaka Kamioka      89fcafc  (HEAD -> main) update readme second
| *     [2020-11-29] Yutaka Kamioka      f387f46  (origin/main, origin/HEAD) update readme first
|/
*       [2020-11-29] Yutaka Kamioka      8519b35  first commit

リモートリポジトリoriginのmainブランチ(f387f46)は、現在の作業場所(HEAD=89fcafc)の派生元(8519b35)から枝分かれしていることから、既にコミットが進んでいることがわかります。
この状態で、git diff origin/maingit diff f387f46とかでも可)で合流したいブランチとの差分を求めることができます。

$ git diff origin/main --name-only
README.md
$ git diff origin/main
(省略)

こうして、合流先ブランチと差分があること、そして差分があるファイル名やその位置を、マージ実施前に知ることができ、"CONFLICT"の文字列に慌てることなく、マージ作業に取り掛かることが出来ます。

終わりに

残念ですが、現時点ではマージそのものを簡単にする道具はありません。

マージは、プログラムコードから意図を読み取り、それを活かしつつ、別の意図をコードとして追加する、高次でクリエイティブな活動ですが、現在のAIにはそれを可能にする読解力は有りません。

しかし、マージを楽にする手法や手段は存在します。

プログラムコードを単機能でコンパクトな関数に分割し分かりやすい名前を与える、テストしやすいコードにした上で、しっかりとテストコードを記述し、機械的に検証できる環境を用意する、、、などです。
いわゆる「良いコード」はマージを楽にするコードと言えます。

gitのaliasを紹介するだけの小ネタのつもりでしたが、無駄に長くなってしまいました。😅