'git reset --hard HEAD'を使用して前のコミットに戻すにはどうすればよいですか?

2012年03月02日に質問されました。  ·  閲覧回数 3.2M回  ·  ソース

Brian McDonough picture
2012年03月02日

Gitはアプリケーションに加えた変更を追跡し、変更をコミットするまでそれらを保持することを知っていますが、ここで電話を切ります。

以前のコミットに戻したい場合は、次を使用します。

git reset --hard HEAD

そしてGitは戻ります:

HEAD is now at 820f417 micro

次に、ハードドライブ上のファイルを以前のコミットに戻すにはどうすればよいですか?

私の次のステップは次のとおりです。

git add .
git commit -m "revert"

しかし、私のハードドライブ上のファイルはどれも変更されていません...

私は何を正しく/間違っていますか?

回答

Mark Longair picture
2012年03月02日
1162

まず、 git reset --hardは、コミットされていないすべての変更を破棄するため、潜在的に危険なコマンドであることに常に注意する必要があります。 安全のため、 git statusの出力がクリーン(つまり、空)であることを常に確認してから使用する必要があります。

最初にあなたは次のように言います:

したがって、Gitはアプリケーションに加えた変更を追跡し、変更をコミットするまでそれらを保持することを知っていますが、ここでハングアップします。

それは正しくありません。 Gitは、ファイルをステージングするとき( git add )またはコミットを作成するときにのみファイルの状態を記録します。 プロジェクトファイルを特定の状態にするコミットを作成すると、それらは非常に安全ですが、それまでは、Gitは実際にはファイルへの「変更を追跡」していません。 (たとえば、ファイルの新しいバージョンをステージングするためにgit addを実行した場合でも、ステージング領域でそのファイルの以前にステージングされたバージョンが上書きされます。)

あなたの質問では、次に次のことを尋ねます。

以前のコミットに戻したい場合は、次を使用します:git reset --hard HEADそしてgitは戻ります:HEADは現在820f417microにあります

次に、ハードドライブ上のファイルを以前のコミットに戻すにはどうすればよいですか?

git reset --hard <SOME-COMMIT> 、Gitは次のようになります。

  • 現在のブランチ(通常はmaster )を<SOME-COMMIT>を指すように戻します。
  • 次に、作業ツリー内のファイルとインデックス(「ステージング領域」)を<SOME-COMMIT>コミットされたバージョンと同じにします。

HEAD現在のブランチ(または現在のコミット)を指しているため、 git reset --hard HEADが行うことは、コミットされていない変更を破棄することだけです。

したがって、戻りたい適切なコミットがf414f31ます。 ( git logまたは任意の履歴ブラウザを介して見つけることができます。)次に、実行したい内容に応じて、いくつかの異なるオプションがあります。

  • 代わりに、現在のブランチを変更して、古いコミットを指すようにします。 git reset --hard f414f31それを行うことができます。 ただし、これはブランチの履歴を書き換えているため、このブランチを誰かと共有している場合は避ける必要があります。 また、 f414f31後に行ったコミットは、 masterブランチの履歴に含まれなくなります。
  • f414f31とまったく同じプロジェクトの状態を表す新しいコミットを作成しますが、それを履歴に追加するだけなので、履歴が失われることはありません。 この回答で提案されている手順を使用してこれを行うことができます-次のようなものです:

    git reset --hard f414f31
    git reset --soft [email protected]{1}
    git commit -m "Reverting to the state of the project at f414f31"
    
uday picture
2012年03月02日
242

警告: git clean -fは追跡されていないファイルを削除します。つまり、ファイルはリポジトリに保存されていないため、完全に削除されます。


これを試して、 git clean -fを参照してください。

git reset --hardは追跡されていないファイルを削除しませんが、 git-cleanは追跡されたルートディレクトリからGit追跡されていないファイルを削除します。

または、@ Paul Bettsが言ったように、これを行うこともできます(ただし、無視されたファイルもすべて削除されることに注意してください)。

  • git clean -df
  • git clean -xdf注意!