Close

Resetting, checking out & reverting


The git reset, git checkout, and git revert commands are some of the most useful tools in your Git toolbox. They all let you undo some kind of change in your repository, and the first two commands can be used to manipulate either commits or individual files.

これらはよく似ているため、特定の開発シナリオでどのコマンドを使用すべきかが非常に混同しやすいといえます。この記事では、git resetgit checkout、および git revert の最も一般的な設定を比較します。これにより、皆さんが自信を持ってこれらのコマンドを自在に使用し、リポジトリを移動できるようになることを願っています。

Git の 3 つの領域

It helps to think about each command in terms of their effect on the three state management mechanisms of a Git repository: the working directory, the staged snapshot, and the commit history. These components are sometimes known as "The three trees" of Git. We explore the three trees in depth on the git reset page. Keep these mechanisms in mind as you read through this article.

チェックアウトとは、HEAD ref ポインターを指定されたコミットに移動する操作です。この操作を説明するために、以下のサンプルをご覧ください。

HEAD ref ポインターを指定したコミットに移動する
データベース
関連資料

Git リポジトリ全体を移動する方法

Bitbucket ロゴ
ソリューションを見る

Bitbucket Cloud での Git の使用方法についてのチュートリアルです。

この例は、main ブランチの連続するコミットを表しています。現在、HEAD ref と main ブランチ ref はコミット d を指しています。今度は git checkout b を実行してみましょう

Sequence of commits on the main branch

これは、「コミット履歴」領域への更新です。git checkout コマンドは、コミットまたはファイル レベルのスコープで使用できます。ファイル レベルのチェックアウトでは、ファイルの内容が特定のコミットの内容に変更されます。

Revert とは、指定されたコミットの逆の操作を行い新しいコミットを作成する操作です。git revert はコミット レベルのスコープでのみ実行でき、ファイル レベルの機能はありません。

リセットとは、指定したコミットを取り上げ、"3 つの領域" をリセットして、指定したコミットのリポジトリの状態に合わせる操作です。リセットは、3 つの領域に対応する 3 つの異なるモードで起動できます。

チェックアウトとリセットは、通常、ローカルまたはプライベートの「取り消し」を行うために使用されます。リモートの共有リポジトリにプッシュする際に競合を引き起こす可能性があるリポジトリの履歴を変更します。元に戻す操作は、新しい履歴を作成してリモートで共有し、リモートのチーム メンバーが依存している履歴を上書きしないため、「パブリックな取り消し」を行うための安全な操作と見なされています。

Git reset vs revert vs checkout reference


以下の表は、これらのすべてのコマンドに関する最も一般的な使用例をまとめたものです。Git の経験を積む間に少なくともこれらの一部は必然的に使用することになるので、このリファレンスを手近に置くようにしてください。

コマンド

スコープ

一般的な使用例

Git のリセット

スコープ

コミットレベル

一般的な使用例

Discard commits in a private branch or throw away uncommitted changes

Git のリセット

スコープ

ファイルレベル

一般的な使用例

ファイルのステージ取り消し

Git checkout

スコープ

コミットレベル

一般的な使用例

ブランチの切り替えまたは古いスナップショットの検査

Git checkout

スコープ

ファイルレベル

一般的な使用例

作業ディレクトリ内の変更の破棄

Git revert

スコープ

コミットレベル

一般的な使用例

パブリックブランチ内のコミットの取り消し

Git revert

スコープ

ファイルレベル

一般的な使用例

(N/A)

Commit level operations


スコープは、git resetgit checkout に渡すパラメーターによって決まります。ファイル パスをパラメーターとして含めない場合、コミット全体に作用します。このセクションでは、それについて説明します。git revert にはファイル レベルの機能はありません。

Reset a specific commit

コミット レベルでは、リセットはブランチの先端を別のコミットに移動する方法です。これは、現在のブランチからコミットを削除するために使用できます。たとえば、次のコマンドは Hotfix ブランチを 2 つのコミット分後方に移動します。

git checkout hotfix git reset HEAD~2

Hotfix の最後にあった 2 つのコミットは、中ぶらりんの状態 (孤立したコミット) になりました。つまり、これらは Git が次回ガーベッジ コレクションを実行するときに削除されます。言い換えると、これらのコミットを破棄すると宣言していることになります。これは、次のように視覚化できます。

hotfix ブランチを HEAD~2 にリセットする

この git reset の使用法は、他の誰とも共有していない変更を元に戻す簡単な方法です。フィーチャーで作業を開始して、「しまった、何をやっているんだ。最初からやり直しだ」と思ったときに、頼りになるコマンドです。

現在のブランチを移動することに加えて、次のフラグのいずれかを git reset に渡してステージ済みスナップショットおよび作業ディレクトリ (またはそのいずれか) を変更することもできます。

  • --soft – ステージ済みスナップショットおよび作業ディレクトリは両方ともまったく変更されません。
  • —mixed — ステージ済みスナップショットは、指定したコミットに一致するように更新されますが、作業ディレクトリには影響しません。これが既定のオプションです。
  • --hard – ステージ済みスナップショットおよび作業ディレクトリは両方とも指定されたコミットに一致するように更新されます。

It’s easier to think of these modes as defining the scope of a git reset operation. For further detailed information visit the git reset page.

古いコミットをチェックアウトする

git checkout コマンドは、リポジトリの状態をプロジェクト履歴の特定の時点に更新するために使用されます。ブランチ名を指定して渡すと、ブランチ間を切り替えられます。

git checkout hotfix

内部的には、上記のコマンドは HEAD を別のブランチに移動し、それに合わせて作業ディレクトリを更新するだけです。これはローカルの変更を上書きする可能性があるので、チェックアウト操作中に失われる作業ディレクトリ内の変更を強制的にコミットするか、スタッシュするよう求められます。git reset と違って、git checkout はブランチを移動させません。

Moving HEAD from main to hotfix

ブランチの代わりにコミット参照を渡すことで、任意のコミットをチェックアウトすることもできます。これは、ブランチをチェックアウトするのとまったく同じです。HEAD 参照を指定されたコミットに移動します。たとえば、次のコマンドは現在のコミットの祖父母をチェックアウトします。

git checkout HEAD~2
`HEAD` を任意のコミットに移動する

これは、古いバージョンのプロジェクトをすばやく調べるのに便利です。ただし、現在の HEAD への分岐参照がないため、分離した HEAD 状態になります。これは、別のブランチに切り替えた後にコミットに戻る方法がないため、新しいコミットの追加を開始すると危険です。このため、分離した HEAD にコミットを追加する前に、必ず新しいブランチを作成する必要があります。

Undo public commits with revert

Revert を行うと、新しいコミットが作成されてコミットが取り消されます。これは、コミット履歴が書き換わらないため、変更を元に戻す安全な方法です。たとえば、次のコマンドは、最後から 2 番目のコミットに含まれる変更を特定し、それらの変更を元に戻す新しいコミットを作成し、新しいコミットを既存のプロジェクトに追加します。

git checkout hotfix git revert HEAD~2

これは、次のように視覚化できます。

2 番目のコミットを最後のコミットに戻す

これを既存のコミット履歴を変更する git reset と対比してください。このため、git revert はパブリック ブランチに対する変更を元に戻すために使用し、git reset はプライベート ブランチに対する変更を元に戻すことだけに使用を制限すべきです。

git revertコミットされた変更を元に戻すためのツールで、git reset HEADコミットされていない変更を元に戻すためのツールと考えることもできます。

git checkout と同様に、git revert も作業ディレクトリ内のファイルを上書きする可能性があります。このため、ユーザーは、操作中に失われる変更をコミットまたはスタッシュするように求められます。

File-level operations


git reset および git checkout コマンドも、オプションのファイル パスをパラメーターとして受け入れます。これにより、これらのコマンドの挙動が劇的に変わります。操作がスナップショット全体に及ぶのではなく、1 つのファイルに限定されます。

Git reset a specific file

ファイル パスを指定して呼び出されると、git reset はステージ済みスナップショットを更新して、指定したコミットのバージョンと一致させます。たとえば、次のコマンドは、最後から 2 番目のコミットの foo.py のバージョンをフェッチし、次のコミットのためにステージングします。

git reset HEAD~2 foo.py

git reset のコミットレベル バージョンと同様に、これは任意のコミットよりも HEAD で使用されるほうが一般的です。git reset HEAD foo.py を実行すると foo.py のステージングが解除されます。このファイルに含まれる変更は、作業ディレクトリにそのまま残ります。

ファイルをコミット履歴からステージ済みスナップショットに移動する

ステージ済みスナップショットは常に更新され、作業ディレクトリは決して更新されないため、--soft--mixed、および、--hard フラグはファイル レベル バージョンの git reset には影響しません。

Git checkout file

ファイルのチェックアウトは、ファイル パスを指定して git reset を使用する場合と似ていますが、ステージング エリアではなく作業ディレクトリが更新される点が異なります。このコマンドのコミット レベル バージョンとは異なり、HEAD 参照は移動しないため、ブランチは切り替わりません。

ファイルをコミット履歴から作業ディレクトリに移動する

たとえば、次のコマンドは作業ディレクトリの foo.py を最後から 2 番目のコミットからのバージョンと一致させます。

git checkout HEAD~2 foo.py

git checkout のコミット レベルの呼び出しと同様に、これはプロジェクトの古いバージョンを調べるために使用できますが、スコープは指定されたファイルに限定されます。

チェックアウトしたファイルをステージングしてコミットすると、そのファイルの古いバージョンに「戻す」効果があります。これは、ファイルに対する後続の変更内容をすべて削除することになるため注意が必要です。これに対して、git revert コマンドは指定されたコミットによって生じた変更のみを元に戻します。

git reset と同様に、これは通常 HEAD をコミット リファレンスとして使用します。たとえば、git checkout HEAD foo.py には、foo.py に対するステージングされていない変更を破棄する効果があります。これは git reset HEAD --hard と似た動作ですが、指定されたファイルに対してのみ動作します。

要約


You should now have all the tools you could ever need to undo changes in a Git repository. The git reset, git checkout, and git revert commands can be confusing, but when you think about their effects on the working directory, staged snapshot, and commit history, it should be easier to discern which command fits the development task at hand.


この記事を共有する
次のトピック

おすすめコンテンツ

次のリソースをブックマークして、DevOps チームのタイプに関する詳細や、アトラシアンの DevOps についての継続的な更新をご覧ください。

一面のツールを使ってコラボレーションしている人たち

Bitbucket ブログ

DevOps のイラスト

DevOps ラーニング パス

Demo Den アトラシアン・エキスパートによる機能デモ

Bitbucket Cloud が、Atlassian Open DevOps とどのように連携するか

DevOps ニュースレター購読

Thank you for signing up