Gitの学びメモ

技術

CI調整に取り組むので、Gitの公式ドキュメントを改めて読み直して知識の埋め直しを行っていたが、「これは知らなかった」「ちゃんと理解できていなかった」と感じたコマンドや概念が色々あったのでそのメモを整理する。


git merge-base

git merge-base は、2つのブランチの共通の祖先となるコミットを取得するコマンドだ。

たとえば、ブランチ testA から派生した testC があるとする。

* 549c7b9 (testC) commit 9
| * 5d5212d (HEAD -> testA) commit 8
|/
*   79d2054 Merge branch 'testB' into testA

この場合、testAtestC の merge-base は 79d2054 になる。以下のコマンドで確認できる。

git merge-base testA testC
# 79d20546e40c58169a3bdf30afb127ff00dbc87e

Range Notation(範囲指定の記法)

two-dots notation(..

git log main..feature

main..feature は「feature から辿れるが、main からは辿れないコミット」を意味する。つまり、main にはなくて feature だけが持っているコミット差分を出す。

three-dots notation(...

git log main...feature

main...feature は「どちらかから辿れるが、両方から辿れるものは除く」を意味する。つまり、お互いが自分だけに持っているコミット差分を出す。

Range Notation を使うときの注意

range notation で書くとき、前の引数が古いコミット、後ろの引数が新しいコミット だ。これは git loggit diff ともに共通する。

git log main..feature
git diff main..feature
git diff main:Makefile feature:Makefile

git tag

タグでコミットを参照できる。

git show latest

git log

タグを起点にしたログ

「タグ latest 以降に Makefile に変更を加えているコミット」を絞り込みたいときは以下のようにする。

git log latest.. Makefile

他にもよく使うパターンをまとめる。

git log v2.5..v2.6            # v2.5 から v2.6 の間のコミット
git log v2.5..                # v2.5 以降のコミット
git log --since="2 weeks ago" # 過去2週間のコミット
git log v2.5.. Makefile       # v2.5 以降で Makefile に変更があるコミット

git diff

コミットハッシュやタグを使って、特定ファイルの差分を取ることもできる。

git diff v2.5:Makefile HEAD:Makefile.in

Parent Commit の参照

^~ の違い

git show HEAD^1  # HEAD の 1つ目の親(HEAD^ と同じ)
git show HEAD^2  # HEAD の 2つ目の親(マージされてきた側の親)

ここで混同しやすいのが HEAD^^HEAD^2 の違いだ。

  • HEAD^^ → HEADの2つ前のコミット(祖父コミット)
  • HEAD^2 → マージコミットの親のうち、マージされてきた方の親コミット

~ を使った例も合わせて。

git show HEAD^   # HEAD の親
git show HEAD^^  # HEAD の祖父
git show HEAD~4  # HEAD から4世代前

"object database" と "index file"

最後に、Gitの内部概念について触れておく。

  • object database: ファイル・ディレクトリ・コミットをストアするための、プロジェクトの履歴管理に特化したシステム。Gitの根幹をなす仕組みだ。
  • index file: ディレクトリツリーの状態や、次のコミットに使う情報をキャッシュしておくファイル。いわゆる「ステージングエリア」の実体にあたる。

こちらの2つの概念はtutorial 2 の方で、まだ読めていないので、引き続き読む。


以上、日頃あまり意識せずに使っていたGitの機能を改めて整理した。特に range notation のドット数の違いや、^~ の使い分けは混同しやすいので、手を動かして確認しておくと理解が定着しやすい。


参考