概要
- ブランチをマージするとき、それぞれのマージでコミットがされているが、各コミットは互いに競合しない場合
- このようなときは、Gitがその内容を解析して、マージコミットを発行してマージされる
- この場合、マージ下でも作業が発生しているので、単なる早送り(fast-forward)にはならない
- このようなマージをno-fast-forwardと呼ぶ
準備
リポジトリーの準備
Git-ブランチ-基本操作-fast-fowardのリポジトリーを使う。イニシャルコミットの状態から始める。
1 2 3 4 5 6 7 8 |
[vagrant@localhost branch]$ git branch * main [vagrant@localhost branch]$ git log commit ad931b08026b6a1ba68350176ae892bcb115a23e (HEAD -> main, origin/main, origin/HEAD) Author: taustation <88479749+taustation@users.noreply.github.com> Date: Sun Aug 8 22:40:29 2021 +0900 Initial commit |
ブランチの作成
git branch
コマンドで、topic
ブランチを作る。
1 2 3 4 |
[vagrant@localhost branch]$ git branch topic [vagrant@localhost branch]$ git branch * main topic |
各ブランチでの変更作業
mainブランチとtopicブランチで交互にコミット
まずmain
ブランチでmain.txt
ファイルを新規作成してコミット。
1 2 3 4 5 6 7 8 |
[vagrant@localhost branch]$ vi main.txt [vagrant@localhost branch]$ cat main.txt mainブランチで新規作成 [vagrant@localhost branch]$ git add . [vagrant@localhost branch]$ git commit -m "main1" [main 814269c] main1 1 file changed, 1 insertion(+) create mode 100644 main.txt |
topic
ブランチに移動してtopic.txt
を新規作成、コミット。
1 2 3 4 5 6 7 8 9 10 |
[vagrant@localhost branch]$ git checkout topic Switched to branch 'topic' [vagrant@localhost branch]$ vi topic.txt [vagrant@localhost branch]$ cat topic.txt topicブランチで新規作成 [vagrant@localhost branch]$ git add . [vagrant@localhost branch]$ git commit -m "topic1" [topic d2b9bd5] topic1 1 file changed, 1 insertion(+) create mode 100644 topic.txt |
main
ブランチに移動してmain.txt
の内容を更新。
1 2 3 4 5 6 7 8 9 10 11 12 |
[vagrant@localhost branch]$ git checkout main Switched to branch 'main' Your branch is ahead of 'origin/main' by 1 commit. (use "git push" to publish your local commits) [vagrant@localhost branch]$ vi main.txt [vagrant@localhost branch]$ cat main.txt mainブランチで新規作成 mainブランチで追加 [vagrant@localhost branch]$ git add . [vagrant@localhost branch]$ git commit -m "main2" [main 3f4be82] main2 1 file changed, 1 insertion(+) |
topic
ブランチに移動してtopic.txt
の内容を更新。
1 2 3 4 5 6 7 8 9 10 11 12 |
[vagrant@localhost branch]$ git checkout topic Switched to branch 'topic' [vagrant@localhost branch]$ ls README.md topic.txt [vagrant@localhost branch]$ vi topic.txt [vagrant@localhost branch]$ cat topic.txt topicブランチで新規作成 topicブランチで追加 [vagrant@localhost branch]$ git add . [vagrant@localhost branch]$ git commit -m "topic2" [topic b7fe425] topic2 1 file changed, 1 insertion(+) |
状態確認
main
ブランチの状態は以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
[vagrant@localhost branch]$ git checkout main Switched to branch 'main' Your branch is ahead of 'origin/main' by 2 commits. (use "git push" to publish your local commits) [vagrant@localhost branch]$ ls README.md main.txt [vagrant@localhost branch]$ git log commit 3f4be82bdc9756e0c8afbfe036d5c27c84e94a01 (HEAD -> main) Author: taustation <taustation@gmail.com> Date: Tue Aug 10 16:57:47 2021 +0900 main2 commit 814269c6e048c460ec1e0057891de51b3ab3d229 Author: taustation <taustation@gmail.com> Date: Tue Aug 10 16:52:48 2021 +0900 main1 commit ad931b08026b6a1ba68350176ae892bcb115a23e (origin/main, origin/HEAD) Author: taustation <88479749+taustation@users.noreply.github.com> Date: Sun Aug 8 22:40:29 2021 +0900 Initial commit |
topic
ブランチの状態は以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
[vagrant@localhost branch]$ git checkout topic Switched to branch 'topic' [vagrant@localhost branch]$ ls README.md topic.txt [vagrant@localhost branch]$ git log commit b7fe425a7db7187e4b01e088aa7a6f062d4c628a (HEAD -> topic) Author: taustation <taustation@gmail.com> Date: Tue Aug 10 17:00:17 2021 +0900 topic2 commit d2b9bd51e9f03d0f9404627ba8ca9cbadec9f75a Author: taustation <taustation@gmail.com> Date: Tue Aug 10 16:55:07 2021 +0900 topic1 commit ad931b08026b6a1ba68350176ae892bcb115a23e (origin/main, origin/HEAD) Author: taustation <88479749+taustation@users.noreply.github.com> Date: Sun Aug 8 22:40:29 2021 +0900 Initial commit |
main
ブランチとtopic
ブランチのコミットは独立に行われていて、互いに影響していない。
1 2 3 4 5 |
initial commit main1 main2 <main> ○──────△─────────▽ HEAD <topic> ○───────────◇─────────□ HEAD initial commit topic1 topic2 |
マージ
main
ブランチでtopicブランチのコミットをマージ。
1 2 3 4 5 |
[vagrant@localhost branch]$ git checkout main Switched to branch 'main' Your branch is ahead of 'origin/main' by 2 commits. (use "git push" to publish your local commits) [vagrant@localhost branch]$ git merge topic |
git merge topic
実行直後にエディター画面になり、以下のように表示される。
末尾に「マージテスト」の1行を追加し、保存・終了(vi/vim
エディターの場合は:wq
)。
1 2 3 4 5 6 7 8 9 10 11 |
Merge branch 'topic' into main # Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit. マージテスト ~ ~ ~ ..... |
するとコマンドラインに戻り、main
ブランチから見て1つのファイル(topic.txt
)が更新(作成)され、2行挿入されていることが表示されている。
1 2 3 4 5 |
[vagrant@localhost branch]$ git merge topic Merge made by the 'recursive' strategy. topic.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 topic.txt |
マージの結果、2つのファイルとその内容が反映されている。
1 2 3 4 5 6 7 8 |
[vagrant@localhost branch]$ ls README.md main.txt topic.txt [vagrant@localhost branch]$ cat main.txt mainブランチで新規作成 mainブランチで追加 [vagrant@localhost branch]$ cat topic.txt topicブランチで新規作成 topicブランチで追加 |
ログを確認すると、時系列でmain
ブランチ、topic
ブランチでの各コミットが並び、最後にマージコミットも記録されている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
[vagrant@localhost branch]$ git log commit d1c4b54b444fde650b3ef84eec4dfb05123632f7 (HEAD -> main) Merge: 3f4be82 b7fe425 Author: taustation <taustation@gmail.com> Date: Tue Aug 10 17:07:47 2021 +0900 Merge branch 'topic' into main マージテスト commit b7fe425a7db7187e4b01e088aa7a6f062d4c628a (topic) Author: taustation <taustation@gmail.com> Date: Tue Aug 10 17:00:17 2021 +0900 topic2 commit 3f4be82bdc9756e0c8afbfe036d5c27c84e94a01 Author: taustation <taustation@gmail.com> Date: Tue Aug 10 16:57:47 2021 +0900 main2 commit d2b9bd51e9f03d0f9404627ba8ca9cbadec9f75a Author: taustation <taustation@gmail.com> Date: Tue Aug 10 16:55:07 2021 +0900 topic1 commit 814269c6e048c460ec1e0057891de51b3ab3d229 Author: taustation <taustation@gmail.com> Date: Tue Aug 10 16:52:48 2021 +0900 main1 commit ad931b08026b6a1ba68350176ae892bcb115a23e (origin/main, origin/HEAD) Author: taustation <88479749+taustation@users.noreply.github.com> Date: Sun Aug 8 22:40:29 2021 +0900 Initial commit |
ログ表示のオプションで、ブランチごとのコミットがわかるよう、以下のコマンドで表示させてみる。
git log --graph
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
[vagrant@localhost branch]$ git log --graph * commit d1c4b54b444fde650b3ef84eec4dfb05123632f7 (HEAD -> main) |\ Merge: 3f4be82 b7fe425 | | Author: taustation <taustation@gmail.com> | | Date: Tue Aug 10 17:07:47 2021 +0900 | | | | Merge branch 'topic' into main | | マージテスト | | | * commit b7fe425a7db7187e4b01e088aa7a6f062d4c628a (topic) | | Author: taustation <taustation@gmail.com> | | Date: Tue Aug 10 17:00:17 2021 +0900 | | | | topic2 | | | * commit d2b9bd51e9f03d0f9404627ba8ca9cbadec9f75a | | Author: taustation <taustation@gmail.com> | | Date: Tue Aug 10 16:55:07 2021 +0900 | | | | topic1 | | * | commit 3f4be82bdc9756e0c8afbfe036d5c27c84e94a01 | | Author: taustation <taustation@gmail.com> | | Date: Tue Aug 10 16:57:47 2021 +0900 | | | | main2 | | * | commit 814269c6e048c460ec1e0057891de51b3ab3d229 |/ Author: taustation <taustation@gmail.com> | Date: Tue Aug 10 16:52:48 2021 +0900 | | main1 | * commit ad931b08026b6a1ba68350176ae892bcb115a23e (origin/main, origin/HEAD) Author: taustation <88479749+taustation@users.noreply.github.com> Date: Sun Aug 8 22:40:29 2021 +0900 Initial commit |
なお、この段階でtopicブランチのコミット履歴はそのまま残っている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
[vagrant@localhost branch]$ git checkout topic Switched to branch 'topic' [vagrant@localhost branch]$ git log commit a0883af88d084ff981375679b5838b94e2981acd (HEAD -> topic) Author: taustation <taustation@gmail.com> Date: Tue Aug 10 21:37:07 2021 +0900 topic2 commit 20f90104d1bba9f89082e1bc7d8ebf516a8f21ee Author: taustation <taustation@gmail.com> Date: Tue Aug 10 21:35:41 2021 +0900 topic1 commit ad931b08026b6a1ba68350176ae892bcb115a23e (origin/main, origin/HEAD) Author: taustation <88479749+taustation@users.noreply.github.com> Date: Sun Aug 8 22:40:29 2021 +0900 Initial commit |
マージ後は以下のような状態。
1 2 3 4 5 6 7 |
initial commit main1 main2 merge <main> ○──────△・・・・・・・・・▽・・・・・・・・・※ HEAD \───◇───/ \───□───/ topic1 topic2 <topic> ○───────────◇─────────□ HEAD initial commit topic1 topic2 |
mainブランチでは一連のコミットが時系列順に並べられるが、main/topic各ブランチでのコミットは識別されている。また、topicブランチでのコミット履歴も別に残っている。
マージの巻き戻し
効かない例
競合が発生していないのでabortは効かない。
1 2 |
[vagrant@localhost branch]$ git merge --abort fatal: There is no merge to abort (MERGE_HEAD missing). |
もちろん、マージコミットの場所でも効かない。
1 2 |
[vagrant@localhost branch]$ git reset --hard HEAD HEAD is now at fc4584c Merge branch 'topic' into main |
失敗例
マージコミットの1つ手前のtopic
でリセットすると、topic
ブランチでのコミットだけが残ってしまった。
1 2 |
[vagrant@localhost branch]$ git reset --hard b7fe425a7db7187e4b01e088aa7a6f062d4c628a HEAD is now at b7fe425 topic2 |
main
ブランチでのログ。main
関係のコミットが消えてしまった。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[vagrant@localhost branch]$ git log commit b7fe425a7db7187e4b01e088aa7a6f062d4c628a (HEAD -> main, topic) Author: taustation <taustation@gmail.com> Date: Tue Aug 10 17:00:17 2021 +0900 topic2 commit d2b9bd51e9f03d0f9404627ba8ca9cbadec9f75a Author: taustation <taustation@gmail.com> Date: Tue Aug 10 16:55:07 2021 +0900 topic1 commit ad931b08026b6a1ba68350176ae892bcb115a23e (origin/main, origin/HEAD) Author: taustation <88479749+taustation@users.noreply.github.com> Date: Sun Aug 8 22:40:29 2021 +0900 |
topic
ブランチでのログ。こちらは変化なし。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
[vagrant@localhost branch]$ git log commit b7fe425a7db7187e4b01e088aa7a6f062d4c628a (HEAD -> topic, main) Author: taustation <taustation@gmail.com> Date: Tue Aug 10 17:00:17 2021 +0900 topic2 commit d2b9bd51e9f03d0f9404627ba8ca9cbadec9f75a Author: taustation <taustation@gmail.com> Date: Tue Aug 10 16:55:07 2021 +0900 topic1 commit ad931b08026b6a1ba68350176ae892bcb115a23e (origin/main, origin/HEAD) Author: taustation <88479749+taustation@users.noreply.github.com> Date: Sun Aug 8 22:40:29 2021 +0900 Initial commit |
正しい巻き戻し方
以下のいずれか。
reset --hard HEAD^
git reset --hard HEAD~
1 2 |
[vagrant@localhost branch]$ git reset --hard HEAD^ HEAD is now at 0eb46a5 main2 |
main
ブランチのログ。main
でのコミットだけが残っている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
[vagrant@localhost branch]$ git log commit 0eb46a51e6d8878c4aff29bffdf23b4581535155 (HEAD -> main) Author: taustation <taustation@gmail.com> Date: Tue Aug 10 21:36:29 2021 +0900 main2 commit 0f792c61583f14142124ed953d4c4174c6f95c0d Author: taustation <taustation@gmail.com> Date: Tue Aug 10 21:34:55 2021 +0900 main1 commit ad931b08026b6a1ba68350176ae892bcb115a23e (origin/main, origin/HEAD) Author: taustation <88479749+taustation@users.noreply.github.com> Date: Sun Aug 8 22:40:29 2021 +0900 Initial commit |
topic
ブランチのログ。topic
でのコミットのみ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
[vagrant@localhost branch]$ git checkout topic Switched to branch 'topic' [vagrant@localhost branch]$ git log commit a0883af88d084ff981375679b5838b94e2981acd (HEAD -> topic) Author: taustation <taustation@gmail.com> Date: Tue Aug 10 21:37:07 2021 +0900 topic2 commit 20f90104d1bba9f89082e1bc7d8ebf516a8f21ee Author: taustation <taustation@gmail.com> Date: Tue Aug 10 21:35:41 2021 +0900 topic1 commit ad931b08026b6a1ba68350176ae892bcb115a23e (origin/main, origin/HEAD) Author: taustation <88479749+taustation@users.noreply.github.com> Date: Sun Aug 8 22:40:29 2021 +0900 Initial commit |
マージ後のブランチ削除
再度マージする。
1 2 3 4 5 6 7 8 |
[vagrant@localhost branch]$ git merge topic Merge made by the 'recursive' strategy. topic.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 topic.txt [vagrant@localhost branch]$ topic.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 topic.txt |
ログ確認。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
[vagrant@localhost branch]$ git log --graph * commit aee123c7146676d548452ddfd8d9bcaa054ac6fc (HEAD -> main) |\ Merge: 0eb46a5 a0883af | | Author: taustation <taustation@gmail.com> | | Date: Tue Aug 10 21:56:38 2021 +0900 | | | | Merge branch 'topic' into main | | マージテスト | | | * commit a0883af88d084ff981375679b5838b94e2981acd (topic) | | Author: taustation <taustation@gmail.com> | | Date: Tue Aug 10 21:37:07 2021 +0900 | | | | topic2 | | | * commit 20f90104d1bba9f89082e1bc7d8ebf516a8f21ee | | Author: taustation <taustation@gmail.com> | | Date: Tue Aug 10 21:35:41 2021 +0900 | | | | topic1 | | * | commit 0eb46a51e6d8878c4aff29bffdf23b4581535155 | | Author: taustation <taustation@gmail.com> | | Date: Tue Aug 10 21:36:29 2021 +0900 | | | | main2 | | * | commit 0f792c61583f14142124ed953d4c4174c6f95c0d |/ Author: taustation <taustation@gmail.com> | Date: Tue Aug 10 21:34:55 2021 +0900 | | main1 | * commit ad931b08026b6a1ba68350176ae892bcb115a23e (origin/main, origin/HEAD) Author: taustation <88479749+taustation@users.noreply.github.com> Date: Sun Aug 8 22:40:29 2021 +0900 Initial commit |
topic
ブランチ削除。
1 2 3 4 |
[vagrant@localhost branch]$ git branch --delete topic Deleted branch topic (was a0883af). [vagrant@localhost branch]$ git branch * main |
main
ブランチのログにはno-fast-forward
マージの記録が残る。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
[vagrant@localhost branch]$ git log --graph * commit 211acd53b3035074d2166b5e043d57243eed3738 (HEAD -> main) |\ Merge: 0eb46a5 a0883af | | Author: taustation <taustation@gmail.com> | | Date: Tue Aug 10 22:18:28 2021 +0900 | | | | Merge branch 'topic' into main | | マージテスト | | | * commit a0883af88d084ff981375679b5838b94e2981acd | | Author: taustation <taustation@gmail.com> | | Date: Tue Aug 10 21:37:07 2021 +0900 | | | | topic2 | | | * commit 20f90104d1bba9f89082e1bc7d8ebf516a8f21ee | | Author: taustation <taustation@gmail.com> | | Date: Tue Aug 10 21:35:41 2021 +0900 | | | | topic1 | | * | commit 0eb46a51e6d8878c4aff29bffdf23b4581535155 | | Author: taustation <taustation@gmail.com> | | Date: Tue Aug 10 21:36:29 2021 +0900 | | | | main2 | | * | commit 0f792c61583f14142124ed953d4c4174c6f95c0d |/ Author: taustation <taustation@gmail.com> | Date: Tue Aug 10 21:34:55 2021 +0900 | | main1 | * commit ad931b08026b6a1ba68350176ae892bcb115a23e (origin/main, origin/HEAD) Author: taustation <88479749+taustation@users.noreply.github.com> Date: Sun Aug 8 22:40:29 2021 +0900 Initial commit |
fast-forwardマージは不可
main/topic
各ブランチでコミットがある状態では、fast-forwardでのマージを強制できない。
1 2 |
[vagrant@localhost branch]$ git merge topic --ff-only fatal: Not possible to fast-forward, aborting. |