リモートを特定のコミットにリセットする


709

コミット後に行われたすべての変更を破棄したい<commit-hash>。だから私はしました:

git reset --hard <commit-hash>

リモコンでも同じようにしたいと思います。これどうやってするの?その後<commit-hash>、いくつかのコミット(およびプッシュ)を実行しましたが、それらすべてを破棄したいだけです。何かがひどく間違っていただけであり、私はそれがすでにあるより悪化させたくありません。;(

私は基本的に私の巻き戻したいorigin/masterとし<commit-hash>


3
あなたorigin/masterが他のユーザーに引っ張られたり押し付けられたりしていませんか?パブリック(つまり、非ローカル)リポジトリの変更履歴は、常に回避したいものです。
vindia

回答:


1252

ブランチがmasterこことリモートの両方で呼び出され、リモートが呼び出されると仮定すると、origin次のことができます。

 git reset --hard <commit-hash>
 git push -f origin master

ただし、他の誰かがリモートリポジトリで作業していて、変更をプルした場合は、これを行わないでください。その場合は、不要なコミットを元に戻し、通常どおりにプッシュすることをお勧めします。

更新:プッシュした変更を他の人がプルしたことを以下で説明しました。そのため、それらの変更をすべて元に戻す新しいコミットを作成することをお勧めしますJakubNarębskiからのこの回答にはこれを行うためのオプションについての素晴らしい説明があります。どの方法が最も便利かは、元に戻したいコミットの数と、どの方法が最も理にかなっているかに依存します。

あなたの質問から、あなたがすでにgit reset --hardあなたのmasterブランチをリセットするために使用したことが明らかであるので、あなたはgit reset --hard ORIG_HEADあなたのブランチを以前の場所に戻すためにを使用することから始める必要があるかもしれません。(いつものようにgit reset --hard、それgit statusがクリーンであること、正しいブランチにいること、そしてgit reflog明らかに失われたコミットを回復するツールとして認識していることを確認してください。)またORIG_HEAD、で正しいコミットを指していることを確認する必要がありgit show ORIG_HEADます。

トラブルシューティング:

![リモート拒否] a60f7d85->マスター(事前受信フックは拒否されました)」のようなメッセージが表示された場合

次に、特定のブランチのブランチ履歴の書き換えを許可する必要があります。たとえば、BitBucketでは、「ブランチ履歴の書き換えは許可されていません」と述べています。Allow rewriting branch historyあなたがチェックしなければならないという名前のチェックボックスがあります。


21
危険な危険:このリセットは、対応する(追跡)ブランチが現在チェックアウトされており、保持したいコミットされていない変更がないこと前提としています。git update-ref代わりに使用してくださいreset --hard。作業ツリー/チェックアウトされたブランチがなくても同じことができるようになります
sehe

3
そうですか。他のユーザーによってプッシュされて変更されました。だから私は使うべきrevert ですが、過去4回のコミットを元に戻したいので、そうするべきですgit revert comit1; git push; git revert comit2; git push; ...か、それとも単にgit revert commit4; git push
nacho4d

1
@ nacho4d:元に戻すたびにプッシュする必要はありません-JakubNarębskiからのこの回答で何をすべきかについての良い説明があります。各コミットを元に戻す必要があります。これを行うgit revert commit4だけで、で導入された変更のみを元に戻す新しいコミットが作成されcommit4ます。しかし、私がリンクした回答が指摘しているように、これらを1つのコミットにまとめることができます。
Mark Longair、2011

1
@マークすでに実行しましたgit reset --hardが、ローカルを削除し、もう一度オリジンからプルしたので、これを行うことができます。git revert ...今の疑問は、各コミットを元に戻してプッシュ(1つずつ)する必要があるのか​​、それとも最初のコミットを元に戻すのか、正しいコミットのみ?
nacho4d 2011

1
@sehe:完全なref名を使用する必要があるため、使用するのは難しいので、人々.gitが作成するつもりのないrefでディレクトリを散らかすのは簡単です。でも安全チェックはしないって言ったら間違いでした。「配管」と「磁器」コマンドへの分類は、gitのmanページで確認できます
Mark Longair、2011

123

ローカルの変更を失ってもかまわない場合は、他の回答を使用してください。この方法では、間違ったコミットハッシュを選択した場合でも、リモートが破壊される可能性があります。

リモートマッチをローカルリポジトリのどこかにあるコミットにしたい場合:

  1. ではない任意のリセットを行います。
  2. git logリモートにしたいコミットを見つけるために使用します。git log -p変更を確認するかgit log --graph --all --oneline --decorate、コンパクトなツリーを表示します。
  3. コミットのハッシュまたはそのタグ、またはチップの場合はそのブランチの名前をコピーします。
  4. 次のようなコマンドを実行します。

    git push --force <remote> <commit-ish>:<the remote branch>
    

    例えば

    git push --force origin 606fdfaa33af1844c86f4267a136d4666e576cdc:master
    

    または

    git push --force staging v2.4.0b2:releases
    

git go手順2のように、履歴の表示に便利なエイリアス()を使用します。これは次のように追加できます。

    git config --global alias.go 'log --graph --all --decorate --oneline'`

3
グラフは非常に良いヒントでした。最後のn回のコミットのみを取得するために-5を追加しただけで、それ以外は巨大なツリーでした。また、リセットを回避することは、まさに私が探していたものです。すばらしい
AlexanderD

@AlexanderDシェルではなくGitにエイリアスを追加して、どこでも機能するようにすることもできます。Gitはコマンド全体からこれらのエイリアスとタブ補完を理解できるため、引数を追加できます。git config --global alias.graph 'log --graph --all --decorate --oneline'面倒が少なく、制限することもできます。例:git graph -5
Walf

これは完璧です。私はいつも地元を台無しにしています。これは、ステージングを誤ってライブにプッシュした後に必要なものでした:(ありがとう!
ジェイク

1
Windowsでは、と入力qしてgitログを終了します。2分、私は二度と戻りません。
dst3p

1
@ dst3pそれはすべてのプラットフォームにあります。通常less、ページャープログラムはqそれを終了する通常の方法です。Git Bashは* nix端末のようなものです。
ウォルフ


13

GitLabでは、これを行う前にブランチを無保護に設定する必要がある場合があります。これは、[リポジトリ]> [設定]> [リポジトリ]> [保護されたブランチ]で実行できます。その後、マークの答えからの方法が機能します。

git reset --hard <commit-hash>
git push -f origin master

10

以前のバージョンのファイルが必要な場合は、git checkoutを使用することをお勧めします。

git checkout <commit-hash>

これを行うと、元の時間に戻ります。プロジェクトの現在の状態には影響しません。メインラインgit checkout mainlineにアクセスできます

ただし、引数にファイルを追加すると、そのファイルは前回から現在のプロジェクト時間に戻されます。つまり、現在のプロジェクトが変更され、コミットする必要があります。

git checkout <commit-hash> -- file_name
git add .
git commit -m 'file brought from previous time'
git push

これの利点は、履歴を削除せず、特定のコード変更を元に戻すこともありません(git revert)

詳細はこちらhttps://www.atlassian.com/git/tutorials/undoing-changes#git-checkout


これは優れた答えです。これは機能し、期間があり、非常に安全です。あなたがそれを台無しにした場合、戻るのは簡単です。
ボブは

8

以前の回答に対する私の2セント:もし

git push --force <remote> <the-hash>:<the remote branch>

それでも機能しない場合は、<your-remote-repo>.git/configファイルの受信セクションを編集できます。

[receive]
  #denyNonFastforwards = true
  denyNonFastforwards = false

ほとんどの回答はgithubやbitbucketなどのリモートサービスを想定しているように思われるため、非早送りプッシュを許可するようにリモートを構成する方法を知っていると役立ちます。
strongbutgood

2

ブランチが開発用でも本番用でもない場合、これを達成する最も簡単な方法は、ローカルで特定のコミットにリセットし、そこから新しいブランチを作成することです。以下を使用できます。

git checkout 000000

(000000は行きたいコミットIDです)問題のあるブランチで、新しいブランチを作成します:

git remote add [name_of_your_remote]

次に、新しいPRを作成できます。すべて正常に機能します。


1

1つのことを行い、コミットのSHA番号を取得します。87c9808など

  1. あなた自身を動かしてください、それは指定されたコミットへの頭です(git reset --hard 89cef43 //ここにあなたの番号をメンションしてください)
  2. 次に、ランダムファイルを変更して、gitがローカルにコミットしてからリモートでコミットするように要求するようにします。つまり、ここで必要な作業は次のとおりです。変更を適用した後git commit -a -m "trial commit"
  3. git push origin masterによって次のコミットをプッシュします(これがローカルでコミットされている場合)。
  4. gitがあなたに尋ねるのは

エラー:一部の参照を ' https://github.com/YOURREPOSITORY/AndroidExperiments.git ' にプッシュできませんでしたヒント:現在のブランチのヒントがヒントの背後にあるため、更新は拒否されました:リモートの対応物。再度プッシュする前に、リモートの変更を統合します(例:ヒント: 'git pull ...')。**

  1. したがって、今できることは

git push --force origin master

  1. したがって、私はそれがうまくいくことを願っています:)

1

ソースツリー:リモートを特定のコミットにリセットする

  1. 下図のようにリモート(origin / feature / 1337_MyAwesomeFeature)に悪いコミットをプッシュした場合

リモコンに移動

  1. [リモート]> [送信元]> [機能]> [1337_MyAwesomeFeature]に移動します
  2. 右クリックして[origin / feature / 1337_MyAwesomeFeatureを削除]を選択します(バックアップが必要な場合は、名前を変更してステップ4をスキップします)。
  3. 「強制削除」と「OK」をクリックします。

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

  1. 古いコミットを選択し、「現在のブランチをこのコミットにリセット」を選択します
  2. 使用するモードを選択し(最後の変更が必要ない場合はハード)、[OK]をクリックします。

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

  1. このコミットを新しいorigin / feature / 1337_MyAwesomeFeatureにプッシュします ここに画像の説明を入力してください

  2. ローカル機能ブランチとリモート機能ブランチが以前の(選択した)コミットになりました ここに画像の説明を入力してください

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