変更点のやり直し

コミットや変更を元に戻す

このセクションでは、Git の「元に戻す」戦略とコマンドについて説明します。まず重要なことは、Git には、ワープロアプリケーションに備わっているような従来型の「元に戻す」システムがないということです。Git での操作は、従来の「元に戻す」という考え方に当てはめないことをお勧めします。また、Git には話し合いで活用すべき、独自の「元に戻す」操作用語があります。この用語には、リセット、打ち消し、チェックアウト、クリーンアップなどがあります。

Git をタイムライン管理ユーティリティとして考えると、面白いかもしれません。コミットは、プロジェクト履歴のタイムラインに沿った、ある時点または関心のあるポイントのスナップショットです。さらに、ブランチを使えば複数のタイムラインを管理できます。Git で「元に戻す」場合、通常は過去の状態か、間違いが起こらなかった別のタイムラインに移動します。

このチュートリアルでは、ソフトウェア開発プロジェクトの過去のバージョンに関する操作を行う際に必要になるすべてのスキルを学習します。最初に、過去のコミットを調べる方法を示し、次に公開リポジトリに公開済みのコミットの打ち消しとローカルマシーン上での未公開のコミットの取り消しの違いを説明します。

間違えた場所を探す:古いコミットを確認する

git log --oneline
e2f9a78fe Replaced FlyControls with OrbitControls
d35ce0178 Editor: Shortcuts panel Safari support.
9dbe8d0cf Editor: Sidebar.Controls to Sidebar.Settings.Shortcuts. Clean up.
05c5288fc Merge pull request #12612 from TyLindberg/editor-controls-panel
0d8b6e74b Merge pull request #12805 from harto/patch-1
23b20c22e Merge pull request #12801 from gam0022/improve-raymarching-example-v2
fe78029f1 Fix typo in documentation
7ce43c448 Merge pull request #12794 from WestLangley/dev-x
17452bb93 Merge pull request #12778 from OndrejSpanel/unitTestFixes
b5c1b5c70 Merge pull request #12799 from dhritzkiv/patch-21
1b48ff4d2 Updated builds.
88adbcdf6 WebVRManager: Clean up.
2720fbb08 Merge pull request #12803 from dmarcos/parentPoseObject
9ed629301 Check parent of poseObject instead of camera
219f3eb13 Update GLTFLoader.js
15f13bb3c Update GLTFLoader.js
6d9c22a3b Update uniforms only when onWindowResize
881b25b58 Update ProjectionMatrix on change aspect
Git チュートリアル: 過去のコミットのチェックアウト

過去のバージョンの閲覧

この例では、常識外れの開発を実験的に開始したものの、それを保存しておくべきか否かについて判断ができないものと仮定します。そしてこの判断の参考とするため、実験的開発を開始する前のプロジェクトの状態を確認するとします。最初に、確認するバージョンのIDを知る必要があります。

git log --oneline

次のようなプロジェクト履歴が表示されたとします:

b7119f2 Continue doing crazy things
872fa7e Try something crazy
a1e8fb5 Make some important changes to hello.txt
435b61d Create hello.txt
9773e52 Initial import

ここで、git checkout コマンドを使用して、コミットメッセージが「Make some import changes to hello.txt」であるコミットの内容を確認します。

git checkout a1e8fb5

このコマンドを実行すると、作業ディレクトリはコミット a1e8fb5 と全く同じ状態になります。この状態で、プロジェクトの現在の状態に影響を与えることなく、ファイルの閲覧、プロジェクトのコンパイル、テストラン、さらにはファイルの編集さえも可能となります。この状態で行われた操作はリポジトリには一切保存されません。開発を続けるには、プロジェクトの「現在の」状態に戻る必要があります。

git checkout main

コミットしたスナップショットを元に戻す

コミットを「元に戻す」には、いくつかの異なる技術戦略があります。以下のサンプルでは、次のようなコミット履歴があると仮定します。

git log --oneline
872fa7e Try something crazy
a1e8fb5 Make some important changes to hello.txt
435b61d Create hello.txt
9773e52 Initial import

コミット 872fa7e Try something crazy の取り消しに焦点を当てます。少しおかしなことが起きるかもしれません。

git checkout を使用してコミットを元に戻す方法

git revert を使用して、パブリックのコミットを元に戻す方法

元のコミット履歴のサンプルに戻ったと仮定しましょう。872fa7e コミットを含む履歴。今回は打ち消す「元に戻す」を試してみましょう。git revert HEAD を実行すると、Git は最後のコミットの逆で新しいコミットを作成します。これにより、現在のブランチ履歴に新しいコミットが追加され、次のようになります。

git log --oneline
e2f9a78 Revert "Try something crazy"
872fa7e Try something crazy
a1e8fb5 Make some important changes to hello.txt
435b61d Create hello.txt
9773e52 Initial import

この時点で、872fa7e コミットを再び「元に戻し」た形になります。872fa7e は履歴内にまだ存在するのですが、新しい e2f9a78872fa7e による変更を打ち消すような全く逆のコミットになります。前述のチェックアウトによる方法とは異なり、同じブランチを使い続けることができます。この解決策は満足のいくものであり、共有パブリックリポジトリで作業するときの理想的な「元に戻す」ための方法です。ただし、選別された最小限の Git 履歴を保持する必要がある場合、この方法は適さない場合があります。

git reset を使用してコミットを元に戻す方法

git log --oneline
a1e8fb5 Make some important changes to hello.txt
435b61d Create hello.txt
9773e52 Initial import

ログ出力から、コミット e2f9a78872fa7e がコミット履歴からなくなったことがわかります。ここで、「crazy」なコミットは一切なかったかのように新しいコミットを作成し、作業を続けることができます。変更を元に戻すこの方法には、履歴をクリーンアップする効果があります。ローカルの変更に対してはリセットの実行が優れていますが、共有リモートリポジトリで作業している場合はより複雑になります。共有リモートリポジトリにコミット 872fa7e をプッシュしている場合、履歴をリセットしたブランチの git push を実行すると、Git がこれを検知してエラーにします。足りないコミットがあるため、プッシュしようとしているブランチは最新ではないと、Git は判断します。このような場合は、git revert を使用して元に戻すことをお勧めします。

直前のコミットを元に戻す

コミットされていない変更を元に戻す

作業ディレクトリ

ステージングインデックス

パブリックな変更の取り消し

リモートリポジトリを使ってチームで作業する場合、変更を元に戻すときにはさらに考慮が必要です。通常、git reset は「ローカル」で元に戻す方法と見なすべきです。プライベートブランチへの変更を元に戻す場合は、リセットの使用をお勧めします。リセットでは、他の開発者が作業している可能性がある他のブランチからコミットの取り消しを切り離すことができます。共有ブランチでリセットを実行した後、git push を使ってそのブランチをリモートでプッシュすると、問題が生じます。この場合、足りないコミットがあるため、プッシュしようとしているブランチはリモートブランチより古いとして、Git はプッシュをブロックします。

共有履歴を元に戻す方法としては、git revert をお勧めします。打ち消しは共有履歴からコミットを削除することは一切ないため、リセットよりも安全です。打ち消しは元に戻すコミットを保持したまま、削除するコミットを逆向きにする新しいコミットを作成します。離れた場所にいる開発者がブランチをプルして、やり直すコミットを元に戻した新しい打ち消しコミットを受け取れるため、この方法は共有リモート コラボレーションにより安全な選択肢です。

概要