お問い合わせ

【Git入門】実務で役立つGit操作とは?stash・rebase・squash merge・revertを図解

前回の「Git基本操作編」では、ファイルを変更してからチームに共有するまでの流れと、リモートの最新状態を取り込む流れを学びました。本記事では、基本操作から一歩進んで、実務で役立つGitの操作を解説します。作業途中の変更を一時的に退避したいときや、作業ブランチを最新の main に合わせたいときなど、操作が役立つ場面と仕組みを図で確認していきましょう。

シリーズの全体像

このGit学習シリーズは、全部で4つの章に分かれています。

  1. 基礎編:Gitの考え方
  2. 基本操作編:毎日使う操作
  3. 実践・応用編:実務で使う操作
  4. コンフリクト編:競合への対応

第1章ではGitの考え方を、第2章では毎日使う基本操作を学びました。本記事では、第3章の「実践・応用編」として、基本操作から一歩進んだ操作を学びます。

こんなときに役立つGit操作

この章で扱う操作を、役立つ場面とともに確認しておきましょう。

  1. 作業途中で別の対応をしたい:スタッシュ
  2. 作業ブランチを最新の main に合わせたい:リベース
  3. 細かいコミットをまとめて取り込みたい:スカッシュマージ
  4. 共有済みの変更を安全に取り消したい:リバート
  5. 特定の変更だけを別のブランチに取り込みたい:チェリーピック

まずは、それぞれの名前と役立つ場面を結び付けておきましょう。

1. スタッシュが役立つ場面

作業ブランチで開発を進めていて、手元にまだコミットしたくない変更があるとします。そこへ突然、本番で発生したバグをすぐに直してほしいという依頼が入りました。

別のブランチへ切り替えて対応したいものの、現在の変更は作業途中のため、まだコミットしたくありません。このような場面で役立つのがスタッシュです。

2. stashで作業途中の変更を一時退避する

スタッシュは、次の3つの手順で使います。

  1. 退避する
    stash で作業途中の変更を一時的に保存します。これにより、現在の変更を残したまま別の作業へ切り替えられます。
  2. 別の作業を行う
    switch で別のブランチへ切り替え、急ぎの作業を行います。
  3. 復元する
    元のブランチに戻ったら、stash pop で退避しておいた変更を復元します。

stash で退避、switch で切り替え、stash pop で復元」という流れを覚えておきましょう。

3. リベースが役立つ場面

自分が作業ブランチで開発を進めている間に、ほかのメンバーの変更が取り込まれ、main ブランチに新しいコミット履歴③が追加されたとします。

一方、自分の作業ブランチは、まだ古いコミット履歴①を起点にしています。このままでも作業は続けられますが、main との差が広がると、あとで統合するときに変更が重なりやすくなります。そこで使うのがリベースです。

4. rebaseでブランチの起点を付け替える

リベースは、作業ブランチの起点を最新の main へ付け替える操作です。rebase を行うと、最新のコミット履歴③を新しい起点として、その上に自分の変更であるコミット履歴②が積み直されます。

マージが2つのブランチを合流させる操作であるのに対し、リベースは起点を付け替えて履歴を一直線に整理する操作です。

ただし、リベースは履歴を書き換えます。すでにリモートへプッシュして共有しているブランチで行うと、ほかのメンバーの履歴と食い違うことがあります。共有済みのブランチで使う場合は注意が必要です。

5. スカッシュマージが役立つ場面

開発を進めていると、「とりあえず保存」や「誤字修正」といった細かいコミットが積み重なることがあります。

このまま main ブランチへマージすると、それらの細かいコミットも履歴として残ります。あとから履歴を見返したときに、作業の流れを追いづらくなることがあります。このような場面で使えるのがスカッシュマージです。

6. squashでコミットをまとめて統合する

スカッシュマージは、複数のコミットを1つにまとめて、main ブランチへ統合する操作です。

図では、作業ブランチに積まれたコミット履歴②、③、④を、1つのコミット履歴⑤にまとめて main ブランチへ取り込んでいます。

通常のマージでは細かいコミットがそのまま残りますが、スカッシュマージでは、作業のまとまりごとに履歴を整理できます。

7. リバートが役立つ場面

開発では、すでにコミットした変更に問題が見つかり、特定のコミットによる変更だけを取り消したいことがあります。

図では、main ブランチに積み重なった履歴のうち、コミット履歴②の変更だけを取り消そうとしています。このような場面で使うのがリバートです。

8. revertで打ち消しコミットを追加する

リバートでは、revert を使います。過去の履歴を削除するのではなく、問題のあったコミット履歴②を打ち消す新しいコミット履歴④を追加します。

そのため、コミット履歴②自体は残ります。どの変更を取り消したのかを、あとから確認できます。

9. revertとresetの違い

revert と混同しやすい操作が reset です。それぞれの違いを整理しておきましょう。

  • revert
    履歴を残したまま、変更を打ち消す新しいコミットを追加します。過去の履歴は消えないため、チームに共有済みの履歴でも使いやすい操作です。
  • reset
    ブランチの参照位置を指定した時点まで戻します。履歴が消えたように見えるため、共有済みの履歴で使うと、ほかのメンバーとの履歴が食い違うことがあります。

共有済みの履歴を取り消すときは、revert を使うと覚えておきましょう。

10. cherry-pickで特定のコミットだけを取り込む

作業ブランチAの変更をすべてではなく、特定のコミットだけ別のブランチへ取り込みたいことがあります。このような場面で使えるのが cherry-pick です。

図では、作業ブランチAに積まれたコミットのうち、コミット履歴②だけを選び、作業ブランチBへ取り込んでいます。さくらんぼを一粒だけ摘み取るように、必要なコミットだけを選ぶことから、チェリーピックと呼ばれています。

使う頻度はそれほど高くありませんが、「この修正だけを取り込みたい」という場面で役立ちます。まずは、名前と役割を覚えておきましょう。

まとめ

本記事で学んだポイントは、次の4つです。

  1. stash:作業途中の変更を一時退避する
    退避、別の作業、復元の3つの手順で使います。
  2. rebase:ブランチの起点を最新の main へ付け替える
    履歴を整理できますが、共有済みのブランチでは注意が必要です。
  3. squash merge:複数のコミットをまとめて統合する
    main の履歴を、作業のまとまりごとに整理できます。
  4. revert:打ち消しコミットを追加して変更を取り消す
    共有済みの履歴では、reset より安全に変更を取り消せます。

それぞれの操作を丸暗記するのではなく、「どのような場面で使うのか」と結び付けて覚えておきましょう。