Gitリポジトリを以前のコミットに戻すにはどうすればよいですか?


7630

現在の状態から特定のコミットで作成されたスナップショットに戻すにはどうすればよいですか?

実行するとgit log、次の出力が得られます。

$ git log
commit a867b4af366350be2e7c21b8de9cc6504678a61b`
Author: Me <me@me.com>
Date:   Thu Nov 4 18:59:41 2010 -0400

blah blah blah...

commit 25eee4caef46ae64aa08e8ab3f988bc917ee1ce4
Author: Me <me@me.com>
Date:   Thu Nov 4 05:13:39 2010 -0400

more blah blah blah...

commit 0766c053c0ea2035e90f504928f8df3c9363b8bd
Author: Me <me@me.com>
Date:   Thu Nov 4 00:55:06 2010 -0400

And yet more blah blah...

commit 0d1d7fc32e5a947fbd92ee598033d85bfc445a50
Author: Me <me@me.com>
Date:   Wed Nov 3 23:56:08 2010 -0400

Yep, more blah blah.

11月3日からコミット、つまりcommitに戻すにはどうすればよい0d1d7fcですか?



116
ここだ非常に明確かつ徹底的なポストストレートのGithubから、gitので物事を取り消しについては。
のび太

3
関連:パブリックリポジトリでの古いGitコミットへのロールバック。その質問は、リポジトリが公開されているという制約を追加することに注意してください。

58
私はgitが大好きですが、信じられないほど単純なものに35の答えがあるという事実は、gitの大きな問題を露呈しています。それともドキュメントですか?
マフィンマン

2
言葉を元に戻すために言葉使用する際の「罠」という言葉はここで扱われてさえいないリセットを口語的に意味するのでしょうか?6594はこれまでのところ賛成投票であり、この方法での編集ではなく、違いを強調しますか?ここで「ファイルを保存する」という表現を「コミットする」という表現で参照することは、もっと混乱しないでしょう...
RomainValeri

回答:


9731

これは、「元に戻す」という意味に大きく依存します。

一時的に別のコミットに切り替える

一時的にそれに戻りたい場合は、だましてから現在の場所に戻ってください。必要なのは、目的のコミットをチェックアウトすることだけです。

# This will detach your HEAD, that is, leave you with no branch checked out:
git checkout 0d1d7fc32

または、そこにいる間にコミットしたい場合は、先に進んで、そこにいる間に新しいブランチを作成します。

git checkout -b old-state 0d1d7fc32

元の場所に戻るには、元のブランチをチェックしてください。(変更を加えた場合は、いつものようにブランチを切り替えるときに、それらを適切に処理する必要があります。リセットして破棄することができます。スタッシュ、チェックアウト、スタッシュポップを使用して、ブランチを持ち帰ることができます。コミットできます。そこにブランチが必要な場合は、ブランチにそれらを追加します。)

未公開のコミットを完全削除

一方、それ以降に行ったすべてのことを本当に取り除きたい場合は、2つの可能性があります。1つは、これらのコミットを公開していない場合は、単にリセットするだけです。

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts, if you've modified things which were
# changed since the commit you reset to.

失敗した場合、すでにローカルの変更は破棄されていますが、再度リセットすることにより、少なくとも以前の状態に戻すことができます。

公開されたコミットを新しいコミットで取り消す

一方、作品を公開している場合は、ブランチをリセットする必要はないでしょう。これは、履歴を効果的に書き換えるためです。その場合、実際にコミットを元に戻すことができます。Gitでは、リバートには非常に特定の意味があります。リバースパッチでコミットを作成してキャンセルします。このようにして、履歴を書き換えることはありません。

# This will create three separate revert commits:
git revert a867b4af 25eee4ca 0766c053

# It also takes ranges. This will revert the last two commits:
git revert HEAD~2..HEAD

#Similarly, you can revert a range of commits using commit hashes:
git revert a867b4af..0766c053 

# Reverting a merge commit
git revert -m 1 <merge_commit_sha>

# To get just one, you could use `rebase -i` to squash them afterwards
# Or, you could do it manually (be sure to do this at top level of the repo)
# get your index and work tree into the desired state, without changing HEAD:
git checkout 0d1d7fc32 .

# Then commit. Be sure and write a good message describing what you just did
git commit

git-revertmanページには、実際にその説明では、このの多くをカバーしています。別の便利なリンクは、git-revertについて説明しているこのgit-scm.comセクションです。

結局、元に戻したくない場合は、元に戻す(ここで説明)か、元に戻す前にリセットすることができます(前のセクションを参照)。

この場合、この回答が役立つこともあります
。HEADを以前の場所に戻す方法は?(戸外ヘッド)


118
ロッドさんのコメント@git revert HEAD~3戻すための最良のワットとして3コミットは午前重要な大会です。
新しいアレクサンドリア

19
整数を書いてもらえますか?例:git reset --hard 0d1d7fc32e5a947fbd92ee598033d85bfc445a50
Spoeken

16
@MathiasMadsenStavはい、もちろん、完全なSHA1でコミットを指定できます。解答を読みやすくするために短縮ハッシュを使用しました。また、入力する場合はハッシュを使用する傾向があります。コピーして貼り付ける場合は、必ず完全なハッシュを使用してください。コミットに名前を付ける方法の詳細については、man git rev-parseでのリビジョンの指定を参照してください。
Cascabel

59
使用できます。git revert --no-commit hash1 hash2 ...この後、1つのコミットですべての復帰をコミットしますgit commit -m "Message"
Mirko Akov

6
この文脈での「公開」とはどういう意味ですか?
Howiecamp 2014

1852

ここにはたくさんの複雑で危険な答えがありますが、実際には簡単です:

git revert --no-commit 0766c053..HEAD
git commit

これは、すべてをHEADからコミットハッシュに戻します。つまり、すべてのコミットがウォークバックされたかのように、作業ツリーにそのコミット状態を再作成します。その後、現在のツリーをコミットできます。これにより、「元に戻した」コミットと基本的に同等の新しいコミットが作成されます。

(この--no-commitフラグを使用すると、gitはすべてのコミットを一度に元に戻すことができます。それ以外の場合は、範囲内のコミットごとにメッセージの入力を求められ、不要な新しいコミットで履歴が散らかります。)

これは、以前の状態にロールバックする安全で簡単な方法です。履歴は破棄されないため、すでに公開されているコミットに使用できます。


23
(1つの大きなコミットですべてを元に戻す代わりに)個別のコミットが本当に必要な場合--no-edit--no-commit、の代わりにを渡すことができるため、元に戻すたびにコミットメッセージを編集する必要はありません。

88
0766c053..HEADの間のコミットの1つがマージである場合、(-mが指定されていない場合に)ポップアップするエラーが発生します。これは、これらの遭遇を助けるかもしれない:stackoverflow.com/questions/5970889/...
timhc22

7
コミットする前に差分を確認するには、を使用してくださいgit diff --cached
John Erck、2015年

21
$ git revert --no-commit 53742ae..HEADリターンfatal: empty commit set passed
Alex G

10
@AlexGこれは、戻りたいハッシュの前にハッシュを入力する必要があるためです。私の場合、ハッシュは次のようになりました:(81bcc9e HEAD{0}; e475924 HEAD{1}, ...からgit reflog)、私はで行った操作を元に戻したかった81bcc9eので、やらなければなりませんgit revert e475924..HEAD
でした

1611

不正コーダー?

自分で作業して、それを機能させたいだけですか?以下のこれらの指示に従ってください。彼らは私や他の多くの人々のために何年にもわたって確実に働いてきました。

他の人と協力していますか?Gitは複雑です。何か発疹が出る前に、この回答の下のコメントを読んでください。

作業コピーを最新のコミットに戻す

変更を無視して、以前のコミットに戻すには:

git reset --hard HEAD

HEADは現在のブランチの最後のコミットです

作業コピーを古いコミットに戻す

最新のコミットより古いコミットに戻すには:

# Resets index to former commit; replace '56e05fced' with your commit code
git reset 56e05fced 

# Moves pointer back to previous HEAD
git reset --soft HEAD@{1}

git commit -m "Revert to 56e05fced"

# Updates working copy to reflect the new commit
git reset --hard

クレジットは同様のスタックオーバーフローの質問に行きます。GitでSHAハッシュによるコミットに戻しますか?


33
私はそれをしましたが、それからコミットしてリモートリポジトリにプッシュすることができませんでした。特定の古いコミットをHEADにしたい...
Lennon

7
これは、元に戻したいコミットがすでにプッシュされていることを意味します。これは、コードをチェックアウトして作業した人に多くの問題を引き起こす可能性があります。彼らはあなたの上にあなたのコミットをスムーズに適用することができないので。そのような場合、git revertを実行してください。リポジトリを使用しているのがあなただけの場合。git push -fを実行します(ただし、その前によく考えてください)
vinothkr

6
また、ソフトリセットソリューションの場合、最初に混合リセットを実行し、最後にハードリセットを実行する代わりに、次のように実際にハードリセットを実行できることも指摘しておきますgit reset --hard 56e05fc; git reset --soft HEAD@{1}; git commit

5
gitの作成者である@nuton linusは、複雑すぎると非難しました。彼は「ショックを受けた」gitがその複雑さのために非常に人気になったと記録に残しています
boulder_ruby

5
@boulder_rubyあなたは、Linus Torvaldsがgitの作成者であることを意味していると思います。しかし、Linus Paulingはおそらくgitが複雑であることに同意するでしょう。
Suncat2000 2018

215

私とおそらく他の人にとって最良のオプションは、Gitリセットオプションです。

git reset --hard <commidId> && git clean -f

これは私にとって最良の選択肢でした!シンプルで、速く、効果的です!


**注:**コメントで述べたように、古いコミットのコピーを持っている他の人とブランチを共有している場合は、これを行わないでください

また、コメントから、「ボールジー」な方法を少なくしたい場合は、

git clean -i

37
必須の警告:古いコミットのコピーを持っている他のユーザーとブランチを共有している場合は、これを行わないでください。このようなハードリセットを使用すると、新しいリセットされたブランチと作業を再同期する必要があるためです。ハードリセットで作業を失うことなくコミットを安全に元に戻す方法を詳細に説明するソリューションについては、この回答を参照してください

7
@Cupcakeの警告の2つめです...結果に非常に注意してください。ただし、これらのコミットを履歴から永久に消去することが本当に必要な場合は、このreset + cleanメソッドがそれを実行し、変更されたブランチをすべてのリモートに強制的にプッシュする必要があることに注意してください。
ashnazg 2014年

5
git clean -f DANGER DANGER
Tisch 2015

2
これにより、ローカルコピーの先頭が目的のコミットに設定されます。しかし、リモートの背後にあるため、変更をプッシュできません。そして、リモートからプルすると、リモートブランチで最後にコミットされた場所に戻ります。プッシュされたローカルコピーの両方で(どこからでも)いくつかのコミットを完全に消去するにはどうすればよいですか?
Ade

2
@Ade .. git push -fフラグを使用することもできますが、注意してください。リモートを上書きします。
ポグリンディス2017年

176

答える前に、背景を追加し、これHEADが何であるかを説明しましょう。

First of all what is HEAD?

HEAD現在のブランチの現在のコミット(最新)への参照です。常に1つしか存在できませんHEAD(を除くgit worktree)。

の内容HEADはに格納され.git/HEAD、現在のコミットの40バイトのSHA-1が含まれています。


detached HEAD

最新のコミットを行っていない場合、つまりHEAD、履歴内の以前のコミットを指している場合は、と呼ばれdetached HEADます。

ここに画像の説明を入力してください

コマンドラインでは次のようになります- HEADは現在のブランチの先端を指していないため、ブランチ名の代わりにSHA-1 :

ここに画像の説明を入力してください


切り離されたヘッドから回復する方法に関するいくつかのオプション:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

これにより、目的のコミットを指す新しいブランチがチェックアウトされます。このコマンドは、特定のコミットにチェックアウトします。

この時点で、ブランチを作成し、この時点から作業を開始できます。

# Checkout a given commit.
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# Create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

いつでも使用できreflogます。git reflog更新された変更が表示さHEADれ、目的のreflogエントリをチェックアウトすると、HEADこのコミットに戻ります。

HEADが変更されるたびに、新しいエントリが reflog

git reflog
git checkout HEAD@{...}

これにより、目的のコミットに戻ります

ここに画像の説明を入力してください


git reset HEAD --hard <commit_id>

頭を「動かして」希望のコミットに戻します。

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts, if you've modified things which were
# changed since the commit you reset to.
  • 注:(Git 2.7以降)も使用できgit rebase --no-autostashます。

このスキーマは、どのコマンドが何を実行するかを示しています。ご覧のとおり、をreset && checkout変更しHEADます。

ここに画像の説明を入力してください


6
への優れたヒントgit reflog、それがまさに私が必要としていたことです
smac89

4
痛い!これはすべて非常に複雑に見えます...プロセスに一歩戻るだけの簡単なコマンドはありませんか?プロジェクトのバージョン1.1からバージョン1.0に戻したいですか?gitのstepback_one_commitか何か....:私のようなものを期待したい
Kokodoko

あります:git reset HEAD^
CodeWizard

3
@Kokodokoはい、それは恐ろしく複雑です...そして、始めたばかりの人々に対して専門家がほとんど考慮していないことの完璧な例です。ここで私の答えを参照してください。また、その中で推奨している本も参照してください。Gitは、直感的に取得できるものではありません。そして、CodeWizardがそうしなかったのは間違いありません。
マイクげっ歯類

145

「コミット解除」し、最後のコミットメッセージを消去し、変更したファイルをステージングに戻すには、次のコマンドを使用します。

git reset --soft HEAD~1
  • --soft コミットされていないファイルは、反対の作業ファイルとして保持する必要があることを示します --hardを破棄するのではます。
  • HEAD~1最後のコミットです。3つのコミットをロールバックする場合は、を使用できますHEAD~3。特定のリビジョン番号にロールバックする場合は、SHAハッシュを使用して行うこともできます。

これは、間違ったものをコミットし、最後のコミットを元に戻したい場合に非常に便利なコマンドです。

出典:http : //nakkaya.com/2009/09/24/git-delete-last-commit/


3
これは柔らかく穏やかです:作業をプッシュしていなくてもリスクなし
nilsM

124

これは、次の2つのコマンドで実行できます。

git reset --hard [previous Commit SHA id here]
git push origin [branch Name] -f

以前のGitコミットが削除されます。

変更を保持したい場合は、次のものも使用できます。

git reset --soft [previous Commit SHA id here]

次に、変更を保存します。


2
この投稿に到達するまで、この投稿で1ダースの答えを試してみましたが、他のすべてのものは、私のgit設定でプッシュしようとするとエラーが発生し続けました。この答えはうまくいきました。ありがとう!
Gene Bo

私にとっての詳細の1つは、差分を失ったことでした。コミットで機能しなかった動作を確認するために、この差分を保持したかったのです。次回はこのデータを保存してから、このリセットコマンドを発行します
Gene Bo

1
これは私が悪いマージを元に戻す唯一の方法でした。その場合、リバートは機能しませんでした。ありがとう!
Dave Cole

ベストアンサー。おかげで
イムランPollob

ベストアンサー、ありがとうございます。
user1394

114

私はGitでローカルの変更を元に戻すために多くの方法を試しましたが、最新のコミット状態に戻したいだけの場合、これが最もうまくいくようです。

git add . && git checkout master -f

簡単な説明:

  • コミットは作成されませんgit revert
  • それはあなたのようにあなたの頭を切り離しませんgit checkout <commithashcode>
  • ブランチの最後のコミット以降、ローカルの変更をすべて上書きし、追加されたファイルをすべて削除します。
  • これはブランチ名でのみ機能するため、この方法でブランチの最新のコミットにのみ戻すことができます。

上記の結果を得るには、はるかに便利で簡単な方法を見つけました。

git add . && git reset --hard HEAD

HEADは現在のブランチでの最新のコミットを指します。

これはboulder_rubyが提案したものと同じコードコードですが、前回のコミット以降に作成されたすべての新しいファイルを消去git add .するgit reset --hard HEADように前 に追加しました。


83

OK、 Gitで以前のコミットに戻るのはとても簡単です...

変更を維持せずに元に戻します。

git reset --hard <commit>

変更を保存して元に戻します。

git reset --soft <commit>

説明:使用git resetすると、特定の状態にリセットできます。上記のように、コミットハッシュで使用するのが一般的です。

あなたは違いが二つのフラグを使用している参照としてではなく--soft--hard、デフォルトでgit reset使用する--softフラグを、それは常にフラグを使用してよいでしょう、私は各フラグを説明します。


- 柔らかい

説明されているデフォルトのフラグは、それを提供する必要はなく、作業ツリーを変更しませんが、コミットの準備ができているすべての変更されたファイルを追加するため、ファイルへの変更がステージングされないコミットステータスに戻ります。


- ハード

このフラグには注意してください。作業ツリーと追跡されたファイルへのすべての変更がリセットされ、すべてがなくなります!


また、Gitを使用する実際の生活で発生する可能性のある以下の画像も作成しました。

Gitをコミットにリセット


のデフォルトはでgit resetありgit reset --mixed、ではありませんgit reset --soft。確認してください--mixed、--soft、および--hard gitのリセットの違いは何?そして平易な英語で、「git reset」は何をしますか?
ファビオはモニカを

70

あなたがマスターとそのそれぞれのブランチについて話していると仮定します(とは言っても、これはあなたが関心を持っているあらゆる作業ブランチである可能性があります):

# Reset local master branch to November 3rd commit ID
git reset --hard 0d1d7fc32e5a947fbd92ee598033d85bfc445a50

# Reset remote master branch to November 3rd commit ID
git push -f origin 0d1d7fc32e5a947fbd92ee598033d85bfc445a50:master

ブログ投稿で回答を見つけました(現在は存在しません)

これは、リモートへの変更のリセットと強制であるため、チームの他のメンバーがすでにgit pullしている場合は、問題が発生することに注意してください。あなたは変更履歴を破棄しています。これは、人々が最初にgitを使用する重要な理由です。

リセットよりも、リバート(他の回答を参照)を使用する方が適切です。あなたが一人のチームなら、それはおそらく問題ではありません。


6
この回答は他の無数の回答とどう違うのですか?
Matsmath 2016年

それは残念です。私はブロガーにメールしました-うまくいけば彼はまだそれを持っています!
markreyes


2
プッシュ構文は、これを修正する方法に関する他のほとんどの提案から欠落しています。うまくいきました。
jpa57 2017年

61

というテキストファイルに次のコミットがあるとします~/commits-to-revert.txt(私は以前git log --pretty=onelineはそれらを取得していました)

fe60adeba6436ed8f4cc5f5c0b20df7ac9d93219
0c27ecfdab3cbb08a448659aa61764ad80533a1b
f85007f35a23a7f29fa14b3b47c8b2ef3803d542
e9ec660ba9c06317888f901e3a5ad833d4963283
6a80768d44ccc2107ce410c4e28c7147b382cd8f
9cf6c21f5adfac3732c76c1194bbe6a330fb83e3
fff2336bf8690fbfb2b4890a96549dc58bf548a5
1f7082f3f52880cb49bc37c40531fc478823b4f5
e9b317d36a9d1db88bd34831a32de327244df36a
f6ea0e7208cf22fba17952fb162a01afb26de806
137a681351037a2204f088a8d8f0db6e1f9179ca

それぞれを元に戻すBashシェルスクリプトを作成します。

#!/bin/bash
cd /path/to/working/copy
for i in `cat ~/commits-to-revert.txt`
do
    git revert $i --no-commit
done

これにより、ファイルやディレクトリの作成、削除など、すべてが以前の状態に戻り、ブランチにコミットされ、履歴が保持されますが、同じファイル構造に戻ります。GitにAがない理由git revert --to <hash>は私を超えています。


41
git revert HEAD~3最後の3つのコミットを削除するためにa を実行できます
Rod

25
@ロッド-いいえ、そうではありません。このコマンドは、HEADの3番目の祖父母であるコミットを元に戻します(最後の3つのコミットではありません)。
kflorence 2012

1
@kflorence情報ありがとうございます。うまくいくでしょうgit revert -n master~3..master~1か?(kernel.org/pub/software/scm/git/docs/git-revert.htmlから見られる)
Rod

3
@ロッド-それは正しいように聞こえますが、確かに醜い構文ですよね?私は常に、「元に戻したい」コミットをチェックアウトしてから、より直感的にコミットすることに気づきました。
kflorence 2012年

7
これを行うには、次のようなスクリプトを使用するよりもはるかに簡単な方法があります。Gitの新しい(またはすべての)バージョンでコミット範囲を受け入れるgit revert --no-commit <start>..<end>ため、を使用するだけgit revertです。範囲の開始は復帰に含まれないことに注意してください。

58

Jefromiのソリューションの追加の代替手段

ジェフロミのソリューションは間違いなく最高のものであり、あなたは間違いなくそれらを使うべきです。ただし、完全を期すために、コミットを元に戻すために使用できる他の代替ソリューションも示したかったのです(以前のコミットでの変更を元に戻す新しいコミットを作成するという意味でgit revert)。

明確にするために、これらの選択肢はコミットを元に戻すための最良の方法ではありませんJefromiのソリューションがありますが、私はちょうどあなたにも同じことを達成するために、これらの他の方法を使用することができることを指摘したいですgit revert

代替1:ハードリセットとソフトリセット

これは、GitでSHAハッシュによるコミット戻すためのCharles Baileyのソリューションのわずかに変更されたバージョンですか?

# Reset the index to the desired commit
git reset --hard <commit>

# Move the branch pointer back to the previous HEAD
git reset --soft HEAD@{1}

# Commit the changes
git commit -m "Revert to <commit>"

これは基本的に、ソフトリセットにより、前のコミットの状態がインデックス/ステージング領域にステージングされたままになり、コミットできるという事実を利用して機能します。

代替方法2:現在のツリーを削除して新しいツリーで置き換える

このソリューションは、古いコミットチェックアウトして新しいコミットにするための svickのソリューションに由来します。

git rm -r .
git checkout <commit> .
git commit

代替#1と同様に、これ<commit>は現在の作業コピーの状態を再現します。以降に追加されたファイルは削除されないため、git rm最初に行う必要がありgit checkoutます<commit>


オルタナティブ1についての簡単な質問:こうすることで、コミットの間に負けませんか?
Bogac、2014

2
@Bogac-ドットはファイルパス(この場合は現在のディレクトリ)を示すため、作業コピーのルートから実行していると想定しています。
Tom

警告は答えの中で数回繰り返されますが、@ Cascabelの(@Jefromiの)リンクされたソリューションのようなものと比較して、誰かこれらが最良の方法でない理由を追加できgit revert HEAD~2..HEADます。問題は発生していません。
ジョシュアゴールドバーグ

55

以下は、以前のコミットに戻る(そしてそれをコミットされていない状態にして、好きなように実行する)ためのはるかに簡単な方法です。

git reset HEAD~1

したがって、コミットIDなどは必要ありません。


機能しません
でし

1
@malhalこれは、コミットされていない変更があったためです。それらを隠しておく/リセットすると、そのエラーなしで機能します。
Paul Walczewski、2017年

39

特に古いコミットを元に戻してステージングするためのコマンド(コアGitの一部ではありませんが、git-extrasパッケージに含まれています)があります。

git back

マニュアルページによると、それ自体としても使用できます

# Remove the latest three commits
git back 3

38

最善の方法は:

git reset --hard <commidId> && git push --force

これにより、ブランチが特定のコミットにリセットされ、ローカルにあるのと同じコミットでリモートサーバーがアップロードされます(これにより、その特定のコミット後にコマンドが完全に制限されます)。

--forceフラグを選択すると、選択したコミットの後に続くすべてのコミットが、それらを回復するオプションなしに削除されることに注意してください。


3
魅力のように働いた!
Gaurav Gupta

私はあなたの答えはすでに例のために与えられていない新たな情報提供方法を確認するために失敗するので、私はdownvoted stackoverflow.com/a/37145089/1723886stackoverflow.com/a/27438379/1723886またはstackoverflow.com/a/48756719/1723886を。実際、ほとんどのコミットはすでにgit reset --hardについて言及しており、さらに多くのコミットは--forceまたは-fを使用してプッシュすることについて言及しています。
Alex Telon

明確でシンプルな1つのコマンドで作業を行います。私の答えが気に入らない場合は、自由に反対投票できます。
david.t_92

1
将来的に検討するもう1つのオプションは、以前の回答の編集を提案するか、たとえば「これは&&を使用して1行で行うこともできます」というコメントを追加することです。そうすれば、誰もが1つの場所で改善された答えを見ることができます。
Alex Telon

36

すべての変更後、これらのすべてのコマンドをプッシュするとき、以下を使用する必要がある場合があります。

git push -f ...

そして、それだけではありませんgit push


15
必須の警告:古いコミットのコピーを持っている他の人とブランチを共有している場合は、これを行わないでください。このような強制プッシュを使用すると、作業を再同期する必要があるためです。強制プッシュで作業を失うことなくコミットを安全に戻す方法を詳細に説明するソリューションについては、この回答を参照してください

3
時々これはあなたが望むものです。例:複数のコミットをコミットして、間違ったブランチ(ブランチA)にプッシュしました。ブランチBをチェリーピックした後、これらのコミットをブランチAから削除します。ブランチAとBがマージされたときに後で元に戻すので、元に戻したくありません。私は誰もが分岐Aに開発されていない知っているので、分岐B. Iでそれらを保持しながら、ブランチからこれらのコミットを削除し、Aは力押しが続くブランチのリセット--hard <commitId>を行うと、これで逃げることができます
ダグR

ありがとう!リモートブランチをローカルブランチに一致させる方法を理解できませんでした。強制プッシュを実行する必要がありました。
Mido

32

これらすべての初期ステップを自分で完了し、Gitリポジトリにプッシュバックできます。

  1. git pull --allコマンドを使用して、Bitbucketから最新バージョンのリポジトリを取得します。

  2. -n 4端末からGit logコマンドを実行します。の後の-n数値により、ローカル履歴の最新のコミットから始まるログのコミット数が決まります。

    $ git log -n 4
    
  3. リポジトリーの履歴の先頭をリセットします。git reset --hard HEAD~Nここで、Nは、先頭に戻すコミットの数です。次の例では、ヘッドは1つのコミットからリポジトリ履歴の最後のコミットに戻されます。

  4. を使用git push --forceしてGitリポジトリに変更をプッシュし、強制的に変更をプッシュします。

Gitリポジトリを以前のコミットにしたい場合:

git pull --all
git reset --hard HEAD~1
git push --force


28

必要なコミットを選択し、確認してください

git show HEAD
git show HEAD~1
git show HEAD~2 

必要なコミットを取得するまで。HEADがそれを指すようにするには、次のようにします。

git reset --hard HEAD~1

またはgit reset --hard HEAD~2何か。


7
必須の警告:古いコミットのコピーを持っている他のユーザーとブランチを共有している場合は、これを行わないでください。このようなハードリセットを使用すると、新しいリセットされたブランチと作業を再同期する必要があるためです。ハードリセットで作業を失うことなくコミットを安全に元に戻す方法を詳細に説明するソリューションについては、この回答を参照してください

2
また、明確にgit show HEADするために、を使用するのと同じgit log HEAD -1です。

25

状況が緊急であり、プロジェクトが「my project」などのディレクトリの下にあると想定して、質問者が迅速かつ汚い方法で質問したことを実行したい場合:


クイックアンドダーティー:状況によっては、クイックアンドダーティーは実際には非常に良い場合があります。ここでの私の解決策は、作業ディレクトリにあるファイルを、.git /ディレクトリの下に潜むgitリポジトリの深さから引き出された/抽出されたファイルで不可逆的に置き換えないことです。たくさんの。悲惨な状況であると思われるものを回復するために、このようなディープシーダイビングを行う必要はありません十分な専門知識なしに回復しようとすると、致命的となる場合があります。


  1. ディレクトリ全体をコピーして、「my project-copy」のように別の名前を付けます。gitリポジトリ(「repo」)ファイルが「my project」ディレクトリ(デフォルトの場所、「。git」というディレクトリ)にあるとすると、作業ファイルとリポジトリファイルの両方がコピーされます。

  2. これを「my project」ディレクトリで行います。

    .../my project $ git reset --hard [first-4-letters&numbers-of-commit's-SHA]
    

これにより、「私のプロジェクト」の下のリポジトリの状態が、コミットしたときの状態に戻ります(「コミット」とは、作業ファイルのスナップショットを意味します)。それ以降のすべてのコミットは「my project」の下で永久に失われますが、... /。gitの下のファイルを含め、それらすべてのファイルをコピーしたためそれらは「my project-copy」の下のリポジトリに引き続き存在します。 /。

次に、システムに2つのバージョンがあります...以前のコミットから対象のファイルなどを調べたり、コピーしたり、変更したりできます。復元されたコミットがどこにも行かなくなってから新しい作業を決定した場合は、「my project-copy」の下のファイルを完全に破棄できます...

この取得したコミットがディレクトリの名前を再度変更するため、実際に作業を破棄せずにプロジェクトの状態を続行したい場合の明白なこと:取得したコミットを含むプロジェクトを削除し(または一時的な名前を付けて)、 " my project-ディレクトリを「my project」にコピーします。次に、ここで他の回答のいくつかを理解してみてください。おそらく、すぐに別のコミットを実行してください。

Gitは素晴らしい作品ですが、誰も「その場でそれを手に入れる」ことはできません。あまりに頻繁に説明しようとする人は、他のVCS [バージョン管理システム]の事前知識を想定し、あまりにも深く掘り下げます早すぎて、「チェックアウト」に互換性のある用語を使用するなど、他の犯罪を犯します。

自分のストレスを大幅に軽減するには、傷跡から学びます。Gitに関する本をほとんど読む必要があります。「Gitによるバージョン管理」をお勧めします。遅らせるのではなく、早くしてください。その場合、Gitの複雑さの多くは分岐とその後の再マージに起因することに注意してください。どの本でもこれらの部分をスキップできます。あなたの質問から、人々が科学であなたを盲目にする必要がある理由はありません

特に、たとえば、これが絶望的な状況であり、Gitの初心者である場合はなおさらです。

PS:もう1つの考え:Gitリポジトリを作業ファイルのあるディレクトリ以外のディレクトリに保存するのは(今のところ)非常に簡単です。これは、上記の迅速でダーティーなソリューションを使用してGitリポジトリ全体をコピーする必要がないことを意味します。フライヤーの回答は--separate-git-dir こちらご覧ください。ただし、注意が必要です。コピーしない「個別ディレクトリ」リポジトリがあり、ハードリセットを実行すると、リセットコミット後のすべてのバージョンは、絶対に必要な場合を除いて、永久に失われます。リポジトリを定期的に、できれば他の場所の中でもクラウド(Googleドライブなど)にバックアップします。

この「クラウドへのバックアップ」についての次のステップは、GitHubまたは(私の考えではより良い)GitLabで(もちろん無料で)アカウントを開くことです。その後、git pushコマンドを定期的に実行して、Cloudリポジトリを「適切に」最新にすることができます。しかし、繰り返しになりますが、これについて話すのは早すぎるかもしれません。


23

これは、最近のコミットに直接リセットするもう1つの方法です

git stash
git stash clear

最後のコミット以降に行ったすべての変更を直接消去します。

PS:少し問題があります。最近保存したstashの変更もすべて削除されます。ほとんどの場合、どちらを選択してもかまいません。


注:インデックスに追加されていない新しいファイルは隠されません。それらを追加するか、手動で削除してください。
andreyro 16

なぜああ、なぜ隠しておくのか?これは非解決策であることに加えて、実際には有害です。質問の最初の文を読むと、スタッシュソリューションがすぐに無効になります(これは、最後のコミットにリセットする場合にのみ役立ちます)。
RomainValeri

22

偶発的な変更からコーダーのディレクトリを完全にクリーンアップするために、以下を使用しました。

git add -A .
git reset --hard HEAD

ただ、git reset --hard HEAD修正を取り除くだろうが、それは「新しい」ファイルを取り除くことはありません。彼らの場合、彼らは誤って重要なフォルダをどこかにランダムにドラッグし、それらのファイルはすべてGitによって新規として扱われてreset --hardいたため、修正しませんでした。git add -A .事前に実行することで、すべてをgitで明示的に追跡し、リセットによって消去されます。


21

以前のコミットからHEADへの変更を保持し、以前のコミットに移動するには、次のようにします。

git reset <SHA>

以前のコミットからHEADへの変更が不要で、すべての変更を破棄する場合は、次のようにします。

git reset --hard <SHA>


18

Revertは、コミットをロールバックするコマンドです。

git revert <commit1> <commit2> 

サンプル:

git revert 2h3h23233

以下のようにHEADからの距離をとることができます。ここで1は「最後のコミットを元に戻す」と言います。

git revert HEAD~1..HEAD

そして次に git push


14

目的のコミットにリセットしてみてください-

git reset <COMMIT_ID>

(COMMIT_IDの使用を確認するにはgit log

これにより、変更されたすべてのファイルが追加されていない状態にリセットされます。

これで、checkout追加されていないすべてのファイルを

git checkout .

チェックgit logして変更を確認するために。

更新

リポジトリに1つしかコミットしていない場合は、

git update-ref -d HEAD


13

コミットはリモートでプッシュされるため、コミットを削除する必要があります。あなたのブランチが開発中であり、それがオリジンにプッシュされていると仮定しましょう。

まず、オリジンからデベロップを削除する必要があります:

git push origin :develop (note the colon)

次に、開発を希望のステータスにする必要があります。コミットハッシュがEFGHIJKであると仮定します。

git reset --hard EFGHIJK

最後に、もう一度開発をプッシュします。

git push origin develop

13

注意!ユーザーが誤ったコミットを誤って行った場合、このコマンドはコミット履歴を失う可能性があります。あなたが少し安全であるよりも、あなたがミスをした場合に備えて、常にあなたのgitのいくつかの余分なバックアップを常に持っています。:)

私にも同様の問題があり、以前のコミットに戻したいと思っていました。私の場合、私は新しいコミットを維持することに興味がなかったので、Hard

これは私がそれをした方法です:

git reset --hard CommitId && git clean -f

これによりローカルリポジトリが元に戻り、ここで使用git push -fするとリモートリポジトリが更新されます。

git push -f

13

GitKrakenあなたはこれを行うことができます。

  1. リセットするコミットを右クリックして、次を選択します:このコミットにリセット/ハード

    ここに画像の説明を入力してください

  2. もう一度コミットを右クリックして、次を選択します:現在のブランチ名/プッシュ

    ここに画像の説明を入力してください

  3. Force Pushをクリックします。

    ここに画像の説明を入力してください

Obs。:ハードリセット後のコミット履歴はすべて失われ、このアクションは元に戻せないため、注意する必要があります。あなたは自分が何をしているかを確認する必要があります。


11

最後のコミットのエラーを修正したい場合は、git commit --amendコマンドを使用することをお勧めします。最後のコミットが参照によってポイントされていない場合、最後のコミットと同じ親でコミットを作成するので、これでうまくいきます。最後のコミットへの参照がない場合、それは単に破棄され、このコミットが最後のコミットになります。これは、コミットを元に戻さずにコミットを修正する良い方法です。ただし、独自の制限があります。

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