パブリックリポジトリでの古いGitコミットへのロールバック


802

gitで特定のコミットにロールバックするにはどうすればよいですかですか?

誰かが私に与えることができる最良の答えgit revertは、希望するコミットに到達するまでX回使用することでした。

それで、20コミット前のコミットに戻したいとしましょう。20回実行する必要があります。

これを行う簡単な方法はありますか?

このリポジトリは公開されているため、リセットを使用できません。


1
git revert <commit>が機能しませんか?
miku

8
私の質問で述べたように、20コミット前の状態に戻したい場合、これは本当に役に立ちません。
David

7
この質問は非常によく、ここで回答されているstackoverflow.com/questions/4114095/...
user7610

4
「ロールバック」の意味が明確ではありません。作業コピーを特定のリビジョンに一時的に切り替えたいという意味ですか?または、リポジトリの履歴を特定のリビジョンに永久に戻したいですか?

1
回答を受け入れ、必要に応じて他の回答に投票してください。
Nabil Kadimi 2014

回答:


1194

これを試して:

git checkout [revision] .

[revision]コミットハッシュはどこですか(例:)12345678901234567890123456789012345678ab

.最後に、非常に重要なことを忘れないでください。これにより、ツリー全体に変更が適用されます。このコマンドはgitプロジェクトのルートで実行する必要があります。サブディレクトリにいる場合、このコマンドは現在のディレクトリのファイルのみを変更します。次にコミットすると、あなたは元気になるはずです。

これを元に戻すことができます

git reset --hard 

作業ディレクトリとステージング領域からすべての変更が削除されます。


7
@AlexReisner現在のディレクトリにあるエンドポイントのピリオドは、必ずしもgitプロジェクト全体ではありませんが、正しいですか?プロジェクト全体に変更を適用する場合、現在gitプロジェクトルートにいない場合、代わりに「git add:/」のように「:/」を使用しますか?
MSpreij 2013

10
注:それ以降にプロジェクトに新しいファイルを追加した場合、これらのファイルは削除されません。したがって、(プラットフォームによっては)ビルドに進むときに、まだエラーが発生する可能性があります。新しいファイルを削除すれば準備完了です。
TheWestIsThe ... 2013

6
@MSpreij gitプロジェクトのルートでこのコマンドを実行する必要があります。サブディレクトリにいる場合、このコマンドは現在のディレクトリのファイルのみを変更します。
volatilevar

3
プロジェクトを別のディレクトリに複製してgit checkout [revision]を使用できる場合に最適です。特定のリビジョンに戻り、他のディレクトリにある同じプロジェクトと比較します。多くの時間を節約できます。
Donato

4
ダムニット、私は "。"を忘れた。リポジトリにどのようなダメージを与えましたか?
フクロウ

196

特定のコミットにロールバックするには:

git reset --hard commit_sha

10個のコミットをロールバックするには:

git reset --hard HEAD~10

履歴を書き換えたくない場合は、次の投稿のように「git revert」を使用できます

Gitリポジトリを以前のコミットに戻す方法は?


4
このアプローチと「git checkout [リビジョン]」の違いのみです。後者はリビジョンを保持するということです。
deeshank 2014

53
OPが「このリポジトリは公開されているため、リセットを使用できない」と明記されているため、この答えは間違っています。
Yarin

4
repoがパブリックの場合、強制プッシュ(git push -f)を使用せずにパブリックリポジトリでコミットをロールバックする方法はないと思います。ロールバック前に変更をプルした人​​に影響を与えるからです。したがって、リセットはパブリックリポジトリのローカルサンドボックスでも使用できます。
ナガキラン

4
これが分離したHEADを回避するのは素晴らしいことです!まさに私が探していたもの。
サイバーモンク

1
私の場合、これはうまくいき、回帰などをテストした後、「git pull」を使用して頭に戻って早送りします。
ピーターQuiring

86

さて、質問は、「ロールバック」とはどういう意味ですか?reset公開されていないためにコミットできず、コミット履歴をそのままにしたい場合は、作業コピーに特定のコミットを反映させたいだけですか?使用git checkoutとコミットハッシュ。

編集:コメントで指摘したようにgit checkout、ブランチを指定せずに使用すると、「ブランチなし」の状態になります。git checkout <commit> -b <branchname>ブランチgit checkout <commit> .へのチェックアウト、または現在のブランチへのチェックアウトに使用します。


これにより、「現在、どのブランチにもありません」という奇妙な状態になりませんか?ロールバックを完了するために変更をどのようにコミットしますか?
Alex Reisner、2010年

さて、私は単に使用を提案していますgit checkout-彼は彼が望むどんなブランチ(現在または新しい)に自由にチェックアウトできます。あいまいにならないように回答を更新します。
Ben

2
私はこれを試しましたが、これが適切な方法ではないと思います。これはその最後のコミットになかったファイルを削除しません。
David

3
作業ディレクトリにいて、マスターにとどまってgit resetいる場合は、それらのファイルを削除する必要があります。これは、実行したくないということです。別のブランチで実行してみてください:git checkout <commit> -b <branchname>そのブランチに停滞しているファイルはありません。
Ben

2
使用の問題checkoutは、以前のコミットで追加されたファイルが削除されないことです。

42

元のポスターは次のように述べています:

誰かが私に与えることができる最良の答えgit revertは、希望するコミットに達するまでX回使用することでした。

それで、20コミット前のコミットに戻したいとしましょう。20回実行する必要があります。

これを行う簡単な方法はありますか?

このリポジトリは公開されているため、リセットを使用できません。

git revertX回使用する必要はありません。git revertは引数としてコミット範囲を受け入れることができるため、コミット範囲を元に戻すには一度だけ使用する必要があります。たとえば、最後の20件のコミットを元に戻す場合は、次のようにします。

git revert --no-edit HEAD~20..

コミット範囲HEAD~20..はの略でHEAD~20..HEAD、「HEADコミットの20 番目の親から開始し、それ以降のすべてのコミットをHEADまで戻す」ことを意味します。

それらはマージコミットではないと想定して、最後の20のコミットを元に戻します。マージコミットがある場合、それらをすべて1つのコマンドで元に戻すことはできません。それらを個別に元に戻す必要があります

git revert -m 1 <merge-commit>

範囲をgit revert使用してgitバージョン1.9.0 を使用してテストしたことにも注意してください。古いバージョンのgitを使用しているgit revert場合、で範囲を使用しても機能しない場合があります。

この場合、git revertが優先されgit checkoutます。

と言うこの回答とはgit checkout異なり、git revert は実際には、元に戻すコミットのいずれかに追加されたファイルをすべて削除することに注意してください。これにより、一連のリビジョンを元に戻す正しい方法になります。

ドキュメンテーション


:これにより、変更が元に戻された新しいコミット作成されます。OPの質問に最適です。しかし、それがあなたが望むものであることを確認してください。(上記にリンクされているgit-revertドキュメントの例は優れています。)代わりに以前のコミットを調査したい場合(つまり、どのコミットに戻すかを選択する前に)、他の回答に記載されているチェックアウトオプションを使用します。削除されたファイルについて作られました。
SherylHohman

@SherylHohman以前のコミットに戻しても、新しいコミットは作成されません。ここであなたが何を意味しているのか想像できません。

27

ステップ1:コミットのリストを取得する:

git log

次の例のようなリストが表示されます。

[Comp:Folder User$ git log
commit 54b11d42e12dc6e9f070a8b5095a4492216d5320
Author: author <author@gmail.com>
Date:   Fri Jul 8 23:42:22 2016 +0300

This is last commit message

commit fd6cb176297acca4dbc69d15d6b7f78a2463482f
Author: author <author@gmail.com>
Date:   Fri Jun 24 20:20:24 2016 +0300

This is previous commit message

commit ab0de062136da650ffc27cfb57febac8efb84b8d
Author: author <author@gmail.com>
Date:   Thu Jun 23 00:41:55 2016 +0300

This is previous previous commit message
...

手順2:必要なコミットハッシュをコピーして、チェックアウト用に貼り付けます。

git checkout fd6cb176297acca4dbc69d15d6b7f78a2463482f

それで全部です。


11
git read-tree -um @ $commit_to_revert_to

それを行います。「git checkout」ですが、HEADは更新されません。

あなたは同じ効果を達成することができます

git checkout $commit_to_revert_to
git reset --soft @{1}

便利なコマンドを一緒に文字列化したい場合。

これらにより、ワークツリーとインデックスが望ましい状態になり、git commit終了するだけで済みます。


これは魅力のように機能した唯一の簡単なアプローチです!ヘッドからチェックアウトしてこのコマンドを実行すると、導入した追加ファイルが正常に削除され、すべての変更が元に戻りました。優秀な。
kamranicus

6

HEADデタッチモードが必要ですか?

DETACHED HEADを使用して特定のコミットまでX時間をロールバックしたい場合(つまり、何も台無しにできないことを意味する場合)、必ず以下を使用します。

(Xを元に戻したいコミットの数に置き換えます)

git checkout HEAD~X

IEで1つのコミットに戻る:

git checkout HEAD~1

1
私は...信じられない...の部分を削除します...それは個人的なようです、そしてまた誰かが上のコメントにそれを言及しました、そして彼の答えでも@ケンの中で。
meJustAndrew

@meJustAndrewそれは、人々を混乱させるSOの非常に多くの答えであり、それは非常に迷惑です。
カールモリソン

なんてシンプルで簡単な答えでしょう。
Ammad

2

あなたがプロジェクトに取り組み、1日ほど仕事をしたとしましょう。1つの機能でまだエラーが発生していることに気付きました。ただし、エラーの原因となった変更はわかりません。したがって、以前の作業コミットを釣り上げる必要があります。特定のコミットに戻すには:

git checkout 8a0fe5191b7dfc6a81833bfb61220d7204e6b0a9 .

さて、コミットが機能するように。エラーはもうありません。問題を特定しました。これで最新のコミットに戻ることができます:

git checkout 792d9294f652d753514dc2033a04d742decb82a5 .

エラーが発生する前に特定のファイルをチェックアウトします(私の場合、Gemfile.lockの例を使用します)。

git checkout 8a0fe5191b7dfc6a81833bfb61220d7204e6b0a9 -- /projects/myproject/Gemfile.lock

そして、これは、後で発生するエラーに気付くことなく、コミットで作成したエラーを処理する1つの方法です。


2

各コミットに関連するコミットIDは、GitHub / BitBucket / Gitlabのコミットセクションで確認できます。非常に単純ですが、コミットIDが5889575だとすると、コードのこの部分に戻りたい場合は、次のように入力するだけです。

git checkout 5889575 .

これにより、コードのその時点に移動します。


1

何が変わったのかはわかりませんが、オプションがないと特定のコミットをチェックアウトできません --detach。私のために働いた完全なコマンドは: git checkout --detach [commit hash]

デタッチされた状態から戻るには、ローカルブランチをチェックアウトする必要がありました。 git checkout master


チェックアウトmasterすることで、デタッチしたままの問題を解決しますが、実行中git reset --hardまたは機能git checkout -- .しましたが、デタッチのままでした
DarkCygnus

0

これはそのための例です

    cd /yourprojects/project-acme 


    git checkout efc11170c78 .
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.