Git-プッシュされたコミットを元に戻す


609

リモートリポジトリにプロジェクトがあり、ローカルリポジトリ(開発)およびサーバーリポジトリ(製品)と同期しています。既にリモートにプッシュされ、サーバーからプルされたコミット済みの変更をいくつか行っています。今、それらの変更を元に戻したいと思います。したがってgit checkout、変更の前にコミットして新しい変更をコミットすることもできますが、それらをリモートに再度プッシュするのに問題があると思います。どのようにすればよいですか?


回答:


735

個々のコミットを元に戻すには:

git revert <commit_hash>

これにより、指定したコミットの変更を元に戻す新しいコミットが作成されます。特定のコミットのみを元に戻し、その後はコミットしないことに注意してください。コミットの範囲を元に戻すには、次のようにします。

git revert <oldest_commit_hash>..<latest_commit_hash>

これは、指定されたコミット間のコミットと指定されたコミットを含みます。

コマンドの詳細については、git-revertのmanページをご覧くださいgit revert。コミットを元に戻す方法の詳細については、この回答もご覧ください。


22
つまり、<oldest_commit_hash>に戻ります;)
David

7
@mr_jigsaw使用git log
-gitaarik

2
gitドキュメントでは、revertコマンドは最初と最後のコミット(最初と最後の両方を含む)の間のコミットを元に戻すと述べています。 ドキュメントを参照
Onur Demir

4
@aodは正しいです。この回答は更新する必要があります。元に戻すための現在のgit APIは、元に戻す<oldest_commit_hash>のリストに含まれています
JHixson '19年

4
git 2.17.2 revert <old> .. <new>にはoldは含まれていませんが、<new>は含まれています
chingis

353

「元に戻す」の痕跡を残さないソリューション。

注:誰かがすでに変更をプルしている場合は、これを行わないでください(これは私の個人リポジトリでのみ使用します)

行う:

git reset <previous label or sha1>

これにより、すべての更新がローカルで再チェックアウトされます(そのため、git statusはすべての更新されたファイルをリストします)

次に、「作業を行い」、変更を再コミットします(注:この手順はオプションです)

git commit -am "blabla"

現在、ローカルツリーはリモートツリーと異なります

git push -f <remote-name> <branch-name>

リモートをプッシュして強制的にこのプッシュを検討し、以前のプッシュを削除します(リモート名とブランチ名の指定は必須ではありませんが、更新フラグですべてのブランチを更新しないようにすることをお勧めします)。

!! 一部のタグがまだ削除されたコミットを指している可能性があることに注意してください!! リモートタグの削除方法


4
-aすべての追跡ファイルがコミットされます-mコミットメッセージが続きます
jo_

3
まさに私が探したもの。誰かが不完全なコミットを行い、その後再度プッシュして元に戻しました。枝はこのためにマージすることができませんでしたし、私はリポジトリが再び正しい状態を取得したい(と彼らはとにかく障害のあるものだったとして履歴からコミット削除)
byemute

1
どの「以前のラベルまたはsha1」を使用すればよいですか。最後の「正しい」ものまたはその前のものを入力し、最後の正しいものによって行われたすべての変更をやり直す必要がありますか?
elysch 2016年

3
誤ったコミットの直前
jo_

1
まさに私が必要とするもの。誤ってブランチをマスターにプッシュしました。その結果、すべてのコミット履歴で多くのゴミのコミットがありました。私git push -fは最後の正しいコミットとリモートの履歴をクリーンアップしただけです!ありがとう!
アントン・

193

これらの場合に私がすることは:

  • サーバーで、カーソルを最後の既知の適切なコミットに戻します。

    git push -f origin <last_known_good_commit>:<branch_name>
    
  • ローカルでは、同じことを行います:

    git reset --hard <last_known_good_commit>
    #         ^^^^^^
    #         optional
    



my_new_branchこの目的で作成したブランチの完全な例を参照してください。

$ git branch
my_new_branch

これはいくつかのものを追加した後の最近の歴史ですmyfile.py

$ git log
commit 80143bcaaca77963a47c211a9cbe664d5448d546
Author: me
Date:   Wed Mar 23 12:48:03 2016 +0100

    Adding new stuff in myfile.py

commit b4zad078237fa48746a4feb6517fa409f6bf238e
Author: me
Date:   Tue Mar 18 12:46:59 2016 +0100

    Initial commit

すでにプッシュされた最後のコミットを取り除きたいので、実行します。

$ git push -f origin b4zad078237fa48746a4feb6517fa409f6bf238e:my_new_branch
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:me/myrepo.git
 + 80143bc...b4zad07 b4zad078237fa48746a4feb6517fa409f6bf238e -> my_new_branch (forced update)

いいね!これで、そのコミットで変更されたファイル(myfile.py)が「ステージングされていないコミット」に表示されます。

$ git status
On branch my_new_branch
Your branch is up-to-date with 'origin/my_new_branch'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   myfile.py

no changes added to commit (use "git add" and/or "git commit -a")

これらの変更は必要ないので、カーソルもローカルに戻します。

$ git reset --hard b4zad078237fa48746a4feb6517fa409f6bf238e
HEAD is now at b4zad07 Initial commit

したがって、HEADはローカルとリモートの両方で、前のコミットにあります。

$ git log
commit b4zad078237fa48746a4feb6517fa409f6bf238e
Author: me
Date:   Tue Mar 18 12:46:59 2016 +0100

    Initial commit

10
これが正解です。これがまさに私の場合に必要なことです。おかげで今日何か新しいことを学びました:)
Egli Becerra

2
これが正解です。それはpush(!)コミットに関するものです!
powtac

3
(変更をプッシュしたことがないかのように)本当に変更を元に戻したい場合、これ正解です。
ジェイコブ

1
完璧な答え。期待どおりに機能しました!
RafiAlhamd

2
誰かがこの男にビールを買う!
Jay Nebhwani

72

gitコマンドラインで以下の手順を実行すると、ローカルとリモートの両方で Git Commit をREVERT(またはDELETEと呼ぶこともできます)できます。

次のコマンドを実行して、元に戻すコミットIDを確認します

git log --oneline --decorate --graph

次のスクリーンショットのようになります ここに画像の説明を入力してください

(Webインターフェイス経由で)リモートもチェックすると、これは以下に示すものと同じであることがわかります

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

スクリーンショットあたりのとおり、現在、あなたがオンになっているのIDコミットe110322をあなたに戻すしたいしかし030bbf6 BOTH ローカルおよびリモート

ローカル+リモートでコミットを削除/リバートするには、次の手順を実行します


最初にローカルでコミットしてコミットID 030bbf6

git reset --hard 030bbf6

に続く

git clean -f -d

これらの2つのコマンドは、以下のスナップショットに示すように、ステージ030bbf6をコミットするために強制リセットをクリーンアップします。

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

ここでgit statusを実行すると、次に示すように、リモートブランチからBEHINDの2つのコミットであることがわかります。 ここに画像の説明を入力してください

以下を実行してインデックスを更新します(更新がある場合)。すべての開発者に、メインのリモートブランチでのプルリクエストを受け入れないように依頼することをお勧めします。

git fetch --all

それが完了したら、次に示すように、ブランチの前に+記号を使用して、このコミットを強制的プッシュする必要があります。私はここでマスターブランチとして使用しました。

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

git push -u origin +master

これで、リモートのWebインターフェイスが表示された場合は、コミットも元に戻す必要があります。

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


61

これにより、プッシュされたコミットが削除されます

git reset --hard 'xxxxx'

git clean -f -d

git push -f

7
このメソッドは、履歴を適切に書き換えてコミットを削除します。すばらしい
Jesse Reza Khorasanee

2
この答えはエル・マグニフェコです!
TruthAdjuster

3
:)
Dzenis H.

1
明確にするために(確信がありません):コミットは、操作後の現在のコミットになります。最後に削除するものではありません。
Maik639

21
git revert HEAD -m 1

上記のコード行。「最後の引数は表す」

  • 1-1つのコミットを元に戻します。

  • 2-最後の2つのコミットを元に戻します。

  • n-最後のn回のコミットを元に戻します。

リモートで有効にするには、このコマンドの後にプッシュする必要があります。元に戻すコミットの範囲を指定するなど、他のオプションがあります。これはオプションの1つです。


後で使用git commit -am "COMMIT_MESSAGE" 後、git pushまたはgit push -f


8
これは真実ではありません--mパラメーターは、元に戻す親の数を指定します(通常は、受信した「theirs」の変更を元に戻したい場合は1、マージされた変更の場合は「ours」-マージの場合は2コミット)。元に戻されたコミットの数とは何の関係もありません-コミット範囲を元に戻したい場合は、次を使用しますgit revert ref1..ref2
Null Reference

1
望ましい効果がなかった
Sam Tuke

4

2020シンプルな方法:

git reset <commit_hash>

(保持したい最後のコミットのハッシュ)。

コミットされていない変更をローカルに保持します。

もう一度プッシュしたい場合は、次のようにする必要があります。

git push -f

0

これが私のやり方です:

ブランチ名がであるとしましょうdevelop

# Create a new temp branch based on one history commit
git checkout <last_known_good_commit_hash>
git checkout -b develop-temp

# Delete the original develop branch and 
# create a new branch with the same name based on the develop-temp branch
git branch -D develop
git checkout -b develop

# Force update this new branch
git push -f origin develop

# Remove the temp branch
git branch -D develop-temp

0

あなたは次のようなことができます

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