変更を失わずに Git コミットを元に戻す方法

GitBeginner
オンラインで実践に進む

Introduction

Git は、開発者がコードベースを効果的に管理できる強力なバージョン管理システムです。一般的なタスクとして、変更の取り消しがあります。git reset のようなコマンドはコミット履歴を変更できますが、git revert は、特に共同プロジェクトにおいて、コミットを取り消すための、より安全で非破壊的な方法を提供します。この実験では、git revert を使用してコミットを取り消す方法と、そのオプションを使用して変更を保持し、さらに変更を加える方法を説明します。

Inspecting the Commit History

変更を加える前に、プロジェクトの現在の状態を理解することが不可欠です。実験環境は、story.txt という名前のファイルといくつかのコミットを含む Git リポジトリで事前に設定されています。コミット履歴を調べてみましょう。

まず、git log コマンドに --oneline オプションを付けて、コミット履歴をコンパクトに表示します。このコマンドは、各コミットを 1 行でリスト表示し、コミットハッシュとコミットメッセージを示します。

git log --oneline

以下のような出力が表示されるはずです。コミットハッシュは異なる場合があります。

c7a3e69 (HEAD -> master) Add a second, unwanted line
a9b2d5f Add the first line to the story
f3e1c8a Initial commit: Add story.txt

このログは 3 つのコミットを示しています。一番上の最新のコミットには、「Add a second, unwanted line」というメッセージが付いています。このコミットがエラーを導入し、それを元に戻す必要があると仮定しましょう。

また、ファイル story.txt の現在の内容も表示してみましょう。

cat story.txt

出力は以下のようになります。

Once upon a time, in a land of code.
The hero of our story was a brave developer.
Suddenly, a wild bug appeared!

私たちの目標は、最新のコミットで追加された最後の行、「Suddenly, a wild bug appeared!」を削除することです。

安全な取り消しのための git revert の使用

git revert コマンドは、以前のコミットの変更を取り消す新しいコミットを作成するために使用されます。これはプロジェクトの履歴を変更しないため、変更を取り消すための安全な方法です。

まず、取り消したいコミットのコミットハッシュをコピーします。前のステップの出力から、これは「Add a second, unwanted line」というメッセージが付いたコミットです。

次に、そのハッシュを指定して git revert コマンドを実行します。

<your-commit-hash> は、ターミナルから取得した実際のハッシュに置き換えてください。

git revert <your-commit-hash>

このコマンドを実行すると、Git はデフォルトのテキストエディタ(nano)を開き、この新しいリバートコミットのコミットメッセージを編集できるようにします。デフォルトのメッセージで通常は十分です。

nano で保存して終了するには:

  1. Ctrl+O(Write Out)を押し、次に Enter を押してファイル名を確認します。
  2. Ctrl+X を押して終了します。

次に、コミット履歴を再度確認してみましょう。

git log --oneline

一番上に新しいコミットが表示されます。

e0d5f1b (HEAD -> master) Revert "Add a second, unwanted line"
c7a3e69 Add a second, unwanted line
a9b2d5f Add the first line to the story
f3e1c8a Initial commit: Add story.txt

元の「不要な」コミットは履歴に残っていますが、新しい「Revert」コミットが追加されていることに注意してください。この新しいコミットは、不要なコミットによって行われた変更を元に戻します。

最後に、story.txt の内容を確認して、変更が元に戻されたことを確認しましょう。

cat story.txt

出力は以下のようになるはずです。

Once upon a time, in a land of code.
The hero of our story was a brave developer.

不要な行は正常に削除されました。

--no-commit を使用して変更を保持したまま元に戻す

コミットの変更を取り消したいが、それを変更するために作業ディレクトリに保持したい場合があります。例えば、コミット全体を破棄するのではなく、コミット内の間違いを修正したい場合などです。--no-commit(または -n)オプションは、この目的に最適です。

まず、別の方法を試せるように、最後のリバート前の状態にリポジトリをリセットしましょう。これには git reset を使用します。このコマンドは HEAD ポインタを移動し、--hard は作業ディレクトリのファイルをそれに合わせて更新します。

git reset --hard HEAD~1

このコマンドは、先ほど行った「Revert」コミットを削除します。git log --oneline を実行して確認できます。

次に、「unwanted」コミットを再度リバートしますが、今回は --no-commit オプションを使用します。「Add a second, unwanted line」コミットのハッシュを使用することを忘れないでください。

<your-commit-hash> は、ターミナルから取得した実際のハッシュに置き換えてください。

git revert --no-commit <your-commit-hash>

今回はエディタは起動しません。リバートの準備はできましたが、コミットされていません。リポジトリのステータスを確認しましょう。

git status

出力は story.txt がコミットのためにステージングされていることを示します。

On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   story.txt

リバートされたコミットからの変更が、ステージングエリアに入りました。これで変更を加えることができます。不要な行をより良いものに置き換えましょう。nanostory.txt を開きます。

nano story.txt

ファイルは、ステップ 2 のリバート後の状態のようになります。ファイルの末尾に、新しくより良い行を追加します。

And they lived happily ever after.

nano で保存して終了します(Ctrl+OEnterCtrl+X)。

次に、変更をステージングエリアに追加し、新しい説明的なメッセージでコミットします。

git add story.txt
git commit -m "Replace unwanted line with a proper conclusion"

最後に、ログとファイルの内容を確認して結果を見てみましょう。

git log --oneline
cat story.txt

ログには新しいコミットが表示され、story.txt には修正された内容が含まれています。コミットの変更を保持・修正しながら、コミットを正常にリバートしました。

まとめ

この実験では、作業を失うことなく安全に Git コミットを元に戻す方法を学びました。git log でコミット履歴を検査し、以前の変更を元に戻す新しいコミットを作成するために標準的な git revert を実行し、さらに git revert --no-commit オプションを使用して変更を作業ステージングエリアに元に戻し、新しいコミットを作成する前にそれらを変更できるようにする方法を実践しました。これらのテクニックは、特にチーム環境において、プロジェクトの履歴をクリーンかつ安全に管理するために不可欠です。