@kyanny's blog

My thoughts, my life. Views/opinions are my own.

Git でコミットの親子関係を master からの相対距離で調べる方法

あるいは、ある二つのコミットが、

  1. どちらも master ブランチに含まれているか
  2. どちらのコミットのほうが先に master ブランチにマージされたか

を調べる方法。

git name-rev --refs master を使った。

$ git log --oneline -1
5d42715 Merge pull request #1048 from quipper/awesome-branch
$ bundle show schema
/Users/kyanny/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/bundler/gems/schema-45569067e8bb

$ git log --oneline -1
ab2f0fe Merge pull request #1129 from quipper/yet-another-awesome-branch
$ git name-rev --refs master 5077d26194181521de8a1ccc0f02782416795452 # A
5077d26194181521de8a1ccc0f02782416795452 master~5^2
$ git name-rev --refs master 38883c52ad5c1657b89963e48c505c9f9f92574e # B
38883c52ad5c1657b89963e48c505c9f9f92574e master~5 # C
$ git name-rev --refs master 45569067e8bb
45569067e8bb master~1

解説

ある Rails アプリが schema という別の gem に依存しており、 schema 側の変更を取り込むために任意のタイミングで bundle update している。

自分が取り込みたい変更は 5077d26194181521de8a1ccc0f02782416795452 のコミット(以下 A)で、 schema リポジトリではすでに master にマージされている。38883c52ad5c1657b89963e48c505c9f9f92574e がマージコミット(以下 B)。

ところが別の作業で schema のリビジョンが更新されており、現在 Rails プロジェクトの master HEAD では schema の 45569067e8bb を使っている(以下 C)。

ここで、 A も C も master に含まれていることはわかっているが、どっちが先祖にあたるのかを知りたい。

図で示すと、↓が期待する歴史

---A---C---master

↓のようになっていると、 A はまだ Rails アプリ側には取り込まれていないということなので、困る。

---C---A---master

これを、 git show でタイムスタンプを調べたりするのではなく、もっと明らかな形で確かめたかった(タイムスタンプは前後することがあってあてにならないし、 GitHub Issues 等でテキストベースでやり取りしているとき結果をコピペして説明しづらい)

そこで冒頭の一連のコマンドを使った。 --refs master をつけないと remotes/origin/ultra-super-awesome-branch~3^2 のような結果が出てきてしまい、わかりづらかった。

冒頭のコマンドの実行結果でいうと、

  • A のマージコミットが B なので ---A---B---master が常に成り立つ
  • A は master~5^2 なので master からみて少なくとも 5 つ前のコミットにあたる
  • C は master~1 なので master からみて 1 つ前のコミットにあたる

以上から、 ---A---B---C---master が成り立ち、コミット A は無事 Rails アプリに取り込まれていることがわかった。

参考