1回のコミットでローカルおよびリモートのgitリポジトリをロールバックする


187

私はこのトピックに関する同様の投稿を読んだことがあり、これを適切に行う方法を私の人生で理解することはできません。

不要な約1000個のファイルをチェックインしました。1by1を通過してすべてをリポジトリから削除する必要はありません。

  • リモートmasterブランチがあります。
  • 私は地元のmaster支店を持っています。

どちらも同じリビジョンです。

リモートを1コミットでロールバックしたい。

私の歴史がであるmasterと言いA--B--C--D--Eます。
ローカルをにロールバックしたいD
次に、それをリモートにプッシュして、現在のハッシュがリモートとローカルの両方でDになるようにします。

これを行う際に問題があります。
私はGit Towerを使用していますが、コマンドラインに慣れています。何か助けは?

更新: 以下の素晴らしいコメント。特にリポジトリが他のユーザーと共有されている場合、リセットの使用は部分的に推奨されないようです。 ハードリセットを使用せずに以前のコミットの変更を元に戻す最良の方法は何ですか?方法はありますか?


「ハードリセットを使用せずに以前のコミットの変更を元に戻す」ように私の回答を更新しました。
VonC、2011年

3
git revertハードリセットなしで、ユーザーの邪魔をせずに実行するために使用します。
user562374


リモコンをロールバックすることはお勧めできませんが、それがやりたいことなら、それを実行してください。これを行う方法は何百もありますが、サーバー側でも結果は同じです。
FelipeC

回答:


306

リモートリポジトリをまだ誰もプルしていない場合は、ブランチのHEADを変更して、強制的にそのリモートリポジトリにプッシュできます。

git reset --hard HEAD^ 
git push -f 

(または、リモートリポジトリに直接アクセスできる場合は、ベアリポジトリであってもHEAD参照を変更できます)

以下のコメントalien-technologyによってコメントされているように、Windows(CMDセッション)では、次のものが必要です^^

git reset --hard HEAD^^
git push -f 

2011年以来の更新:
使用するには、git push --force-with-lease私はここで提示していること、Gitは1.8.5で、2013年に導入された)方が安全です。

説明については、Schwern回答を参照してください。


誰かがすでにレポをプルしている場合はどうなりますか?それから私は何をしますか?

次に、履歴を書き換えないものを提案します。

  • git revert ローカルで最後のコミット(前のコミットとは逆の新しいコミットを作成)
  • によって生成された「元に戻す」をプッシュしgit revertます。

1
誰かがすでにレポをプルしている場合はどうなりますか?それから私は何をしますか?
Jamis Charles

1
@gwhoはブランチを作成しますか?いいえ、それはブランチのヘッドを移動しますが、あなたはまだ同じブランチにいます。ただし、プッシュは早送りではなくなるため、そうしたプッシュを強制する必要があります。
VonC、2014

1
誰かがリポジトリをプルしたかどうかを知る方法はありますか?
Pinkerton 2016

4
Windowsでは、^文字は行の継続と文字のエスケープに使用され、次のコマンドを作成します。git reset --hard HEAD ^^
Alien Technology

1
@AlienTechnology Powershellを使用して、Windows 10で入力するだけで、最後のコミットをリセットする必要はreset --hard HEAD^ありませんでしreset --hard HEAD^^た。
Gaspacchio

56

ローカルブランチを1つのリビジョンバックに設定します(HEAD^つまり、1つのリビジョンバック)。

git reset --hard HEAD^

変更をオリジンにプッシュします。

git push --force

そうしないとgitはorigin1つのコミットで遅れていることを認識し、何も変化しないため、プッシュを強制する必要があります。

でそれを行うと、--forcegitにHEADリモートリポジトリでの進歩を尊重せずに上書きするよう指示します。


1
これはgitで非常に異なる意味を持つ特定の用語であるため、これを復帰と呼ばないことをお勧めします。
Cascabel、2011年

@Jefromi:ヒントをありがとう。編集。
eckes

すばらしい答えです。特にリポジトリが他のユーザーと共有されている場合は、リセットを使用することは部分的に推奨されていないようです。これを行うよりきれいな方法はありますか?それは以前のコミットの変更をすべて元に戻しますか?
Jamis Charles

注意してください!コミットされていない変更または失われた変更を隠す
Nosov Pavel

カッコいい。では、これはgit push origin master、ローカルブランチが少なくとも1回のコミットで先行しているため、Gitがリモートで新しいコミットを作成できることを意味しますか?さらに、後者は、リモートリポジトリのヘッドが指すものと実質的に異なる必要がありますか?
MadPhysicist

18

最後のコミットのリスニングを元に戻す場合:

ステップ1:

ローカルコミットをメッセージで確認する

$ git log

ステップ2:

ローカルブランチ(またはマスター)からの変更をリセットせずに最後のコミットを削除する

$ git reset HEAD^

または、最後のコミットファイルと更新がリッスンしたくない場合

$ git reset HEAD^ --hard

ステップ3:

ファイルとコードを更新でき、もう一度強制的にプッシュする必要があります。以前のコミットが削除されます。新しいコミットを保持します。

$ git push origin branch -f

それでおしまい!


それはコミットを元に戻すのではなく、コミットを置き換えるものです。慣習的な用語を誤用してgit初心者を混乱させないでください。
Suncat2000 2018

7

以下のコマンドを入力すると、git commitの履歴を確認できます-

$ git log

その特定のブランチの履歴が次のようなものであるとしましょう-commit_A、commit_B、commit_C、commit_D。ここで、commit_Dは最後のコミットで、これがHEADが残る場所です。ここで、ローカルおよびリモートから最後のコミットを削除するには、以下を実行する必要があります。

ステップ1:最後のコミットをローカルで削除-

$ git reset --hard HEAD〜

これにより、コミットHEADがcommit_Cに変更されます

ステップ2:新しいHEADコミットの変更をリモートにプッシュする

$ git push origin + HEAD

このコマンドは、リモートから最後のコミットを削除します。

PSこのコマンドはMac OSXでテストされており、他のオペレーティングシステムでも動作するはずです(他のOSについては主張していません)。



2

安全な手順の更新版を次に示します。

git reset --hard HEAD^ 
git push --force-with-lease

git push -fリモートリポジトリを無差別に独自の変更に置き換えます。他の誰かが変更をプッシュした場合、それらは失われます。git push --force-with-leaseリポジトリが期待どおりの場合にのみ、リベースをプッシュします。他の誰かがすでにプッシュしている場合、プッシュは失敗します。

有害と見なされる力を参照してくださいgitの–force-with-leaseを理解する

これをとしてエイリアス化することをお勧めしrepush = push --force-with-leaseます。

誰かがすでにレポをプルしている場合はどうなりますか?それから私は何をしますか?

彼らに伝えてくださいgit pull --rebase=merges。代わりのgit fetch origingit merge origin/master、それは意志git fetch origingit rebase -r origin/master。これにより、ローカルでの変更masterが新しいリベースに上書きされorigin/masterます。-r彼らが行ったかもしれないあらゆるマージを保存します。

これをプルのデフォルトの動作にすることをお勧めします。安全で、他のユーザーのリベースを処理し、不要なマージを減らします。

[pull]
        rebase = merges

1
同意し、賛成票を投じました。私の弁護のために、私の古い2011年の回答はオプションの導入の2年に書かれ--force-with-leaseました。
VonC

私はすでに(昨日)それをしたと思った:stackoverflow.com/posts/4647362/revisions
VonC



0

最後のコミットをリモートから削除し、コミット履歴もクリアしたかっただけです。以下は魅力のように働きました

git reset --hard HEAD^ 
git push -f 

しかし、「以下」は上記の私の答えとどのように違うのですか?
VonC

0

ヘッドをリセットして前のコミットに戻す方法は、

$ git reset HEAD^ --hard
$ git push <branchname> -f

ただし、リモートブランチでは受け入れられない場合があります。

To ssh:<git repo>
 ! [rejected]        develop -> develop (non-fast-forward)
error: failed to push some refs to 'ssh:<git repo>'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

次に、他の方法は

git revert HEAD
git push <remote branch>

これは正常に動作します。

注:git push -f <force>失敗した場合は、元に戻そうとすることを忘れないでください。やるgit pullリモートとローカルが同期しているし、次に試すように、前にgit revert。リモートとローカルが同じSHA1で同じコミットポイントにあることを
確認するgit logために、で確認してください。

git revert 
A --> B --> C -->D
A--> B --> C --> D --> ^D(taking out the changes and committing reverted diffs)

0

ローカルマスター

git reflog
-- this will list all last commit
  e.g Head@{0} -- wrong push
      Head@{1} -- correct push  
git checkout Head@{1} .
  -- this will reset your last modified files

git status 
git commit -m "reverted to last best"
git push origin/master

他の人が引っ張ったかどうか心配する必要はありません。

できた!


0

ローカルリポジトリに手を加えることなく、リモートリポジトリから最後のコミットのみを削除する場合は、次の1行です。

git push origin +origin/master~:master

これは次の構文を使用します。

git push <remote> <refspec>

ここで<remote>origin、で<refspec>あり、次の構造を持っています:

+origin/master~:master

詳細はにありますgit-push(1)。上記+は「この参照を強制的にプッシュする」ことを意味し、その他の部分は「から(リモートの)origin/master~へ」を意味します。それが前の最後のコミットであることを知るのは難しくありませんよね?masteroriginorigin/master~origin/master


0

私にとってはこの2つのコマンドを動作させます:

git checkout commit_id
git push origin +name_of_branch

0

これを行うこともできます:

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

そして、最新の不良コミットを取得した他のすべてのユーザーをリセットします。

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