2つのブランチの変更を統合し、マージコミットを作成するコマンドです。
git merge は、2つのブランチの変更を1つに統合するコマンドです。 たとえば feature ブランチで新機能を開発したあと、その変更を main ブランチに取り込むときに使います。
マージを実行すると、Git は自動的に「どこで枝分かれしたか(マージベース)」を見つけ、 両方のブランチの変更を比較して統合します。上のツールでは C2 が分岐点で、C4(main の変更)と F2(feature の変更)を統合して緑色の M(マージコミット)を作っています。
マージの最大の特徴は非破壊的なこと。既存のコミットは一切変更されず、新しいマージコミットが追加されるだけです。 間違えても git reset ですぐに元に戻せるため、初心者でも安全に使えます。
git merge [ブランチ名]main に新コミットがなければ自動的に ff になるgit merge [ブランチ名]両方にコミットがあると自動的に 3-way になるgit merge --squash [ブランチ名]ステージングに追加されるだけなので、その後 git commit が必要git merge --no-ff [ブランチ名]git merge [ブランチ名]feature ブランチを現在のブランチにマージする(最も基本的な使い方)git merge --no-ff [ブランチ名]fast-forward できる場合でもマージコミットを強制的に作成するgit merge --squash [ブランチ名]feature の変更をステージングに追加するだけ(コミットは自分で行う)。履歴が1コミットにまとまるgit merge --abortコンフリクト発生中のマージを中止し、マージ前の状態に完全に戻すgit merge --continueコンフリクトを解決した後、マージを続行してマージコミットを作成するgit merge --no-commit [ブランチ名]マージは実行するがコミットはしない。マージ結果を確認してから手動でコミットしたいときに使う同じファイルの同じ行を両方のブランチが変更していると、Git は自動統合できずコンフリクトが発生します。 上のツールでは異なる関数を変更しているためコンフリクトは起きませんが、実際の開発ではよく遭遇します。
function greet(name) {<<<<<<< HEAD (main)
return "Hi, " + name;
=======
return "Hello, " + name + "!";
>>>>>>> feature
}
<<<<<<< HEADここから「現在のブランチ(main)の変更」が始まる=======区切り線。ここから「取り込もうとしているブランチの変更」が始まる>>>>>>> feature「feature ブランチの変更」がここで終わる| Merge | Rebase | |
|---|---|---|
| 履歴 | 分岐が残る(ダイヤモンド形) | 一直線になる |
| 既存コミット | 変更しない(安全) | ハッシュが変わる(注意) |
| コンフリクト | 1回で解決 | コミットごとに発生する可能性 |
| 取り消し | git revert -m 1 で簡単 | git reflog で探す必要あり |
| 共有ブランチ | 安全に使える | 使ってはいけない |
# マージコミットを取り消す(push 前) git reset --hard HEAD~1 # すでに push した場合(履歴を書き換えずに打ち消す) git revert -m 1 HEAD
# マージ前の状態に戻す git reset --hard HEAD~1 # 正しいブランチに切り替えてやり直す git checkout main git merge [ブランチ名]
# マージを中止(元の状態に完全に戻る) git merge --abort # コンフリクト時に相手の変更を丸ごと採用したい場合 git checkout --theirs <file> git add <file>

git rebase でコミットがどう付け替えられるかをステップアニメーションで可視化します

fetchとpullの違いをグラフの変化で並べて比較

fetch/pull/pushのデータフローとremote tracking branchを可視化

Fast-forward が可能な場合でもマージコミットを作成して、ブランチの合流履歴を明示的に残す git merge --no-ff の仕組みを可視化

軽量タグとアノテートタグの違いをオブジェクト構造で可視化

作業中の変更をスタックに退避する仕組みを可視化