git logのRevisionを指定するとき、指定した範囲よりも前のRevisionからBranchを切っていて、そのBranchをMergeしたのが指定した範囲内だった場合にどう動くのだろうか?と思ったので調べてみた。
サンプルとして適当なリポジトリを作成した。コミットツリーは以下のようになっている。
* 5a04c30 Merge branch 'release/v0.2.0' (HEAD, master) |\ | * fc78c4c add release_0.2.0.txt (release/v0.2.0) | * 0172707 Merge branch 'release/v0.1.0' into develop (develop) | |\ | * \ f278bcf Merge branch 'feature/func21' into develop | |\ \ | | * | 10f9fa6 add func21.txt (feature/func21) | * | | fe556d4 Merge branch 'feature/func12' into develop | |\ \ \ | | |/ / | |/| | | | * | ee7ffeb modify func12.txt (feature/func12) | | * | 3a1bbcd modify func12.txt | | * | 1e68c15 add func12.txt * | | | 40a4a56 Merge branch 'release/v0.1.0' |\ \ \ \ | | |_|/ | |/| | | * | | a74118d release v0.1.0 (release/v0.1.0) | |/ / | * | 4f26e7d Merge branch 'feature/func11' into develop | |\ \ | | * | 335ceba modify func11.txt (feature/func11) | * | | df346c9 Merge branch 'feature/func13' into develop | |\ \ \ | | * | | ca391a4 add func13.txt (feature/func13) | * | | | c8fd460 Merge branch 'feature/func11' into develop | |\ \ \ \ | | |/ / / | |/| / / | | |/ / | | * | 0836fd6 add func11.txt | | |/ | * | 00f05c1 modify funtions.txt | |/ | * 2ec9d3d add functions.txt |/ * 0b696bf Update base.txt * b22f709 First Commit
少し長々としているが、想定状況はこんな感じ。
- RepositoryはGit flowのルールで運用している。
- 以前にv0.1.0をリリースしており、現在はv0.2.0をリリースしたばかり。
v0.2.0で開発したCommit一覧を取得したいけれど、v0.2.0にはv0.1.0時代からの修正(v0.1.0時点からのBranch)であるfeature/func12をMergeしている。このとき、feature/func12のCommitは一覧にあらわれるか否か?
$ git log --oneline release/v0.1.0..release/v0.2.0 fc78c4c add release_0.2.0.txt 0172707 Merge branch 'release/v0.1.0' into develop f278bcf Merge branch 'feature/func21' into develop fe556d4 Merge branch 'feature/func12' into develop ee7ffeb modify func12.txt 10f9fa6 add func21.txt 3a1bbcd modify func12.txt 1e68c15 add func12.txt
「 ですよねー」という結果になりましたが、もちろん現れます。
git log a..bとしたとき、aからbまでのCommit一覧なので、bに含まれていてaに含まれていないCommitを表示します。
feature/func11は途中で一度mergeしているので、もう少しわかりやすい例としてこれを使います。
$ git log --oneline c8fd460..4f26e7d 4f26e7d Merge branch 'feature/func11' into develop df346c9 Merge branch 'feature/func13' into develop 335ceba modify func11.txt ca391a4 add func13.txt $ git log --oneline 00f05c1..4f26e7d 4f26e7d Merge branch 'feature/func11' into develop df346c9 Merge branch 'feature/func13' into develop 335ceba modify func11.txt c8fd460 Merge branch 'feature/func11' into develop ca391a4 add func13.txt 0836fd6 add func11.txt
c8fd460は「0836fd6 add func11.txt」を知っているので一覧に表示されませんが、c8fd460の1つ前である00f05c1は0836fd6を知らないので一覧に表示されます。
git diffでも同様です。v0.1.0で修正したファイルの一覧が欲しい場合やv0.2.0での修正ファイル一覧が欲しい場合は以下のようになります。
$ git diff 2ec9d3d..release/v0.1.0 --name-status A func11.txt A func13.txt M functions.txt A release_0.1.0.txt $ git diff release/v0.1.0..release/v0.2.0 --name-status A func12.txt A func21.txt A release_0.2.0.txt
これだけ長々と書いてあれなのですが、この仕様についてGitドキュメントのgitrevisionのページににしっかり書いていますね。
<rev1>..<rev2>
Include commits that are reachable from <rev2> but exclude those that are reachable from <rev1>. When either <rev1> or <rev2> is omitted, it defaults to HEAD.
では。