エラーのあるgit push -f originマスターから回復するにはどうすればよいですか?


92

--forceオプションを使用してプロジェクトに間違ったソースをコミットしました。

元に戻すことはできますか?以前のすべてのブランチが-fオプションを使用して上書きされていることを理解しているため、以前のリビジョンを台無しにした可能性があります。


回答:


53

通常、Gitは何も破棄しませんが、これからの回復には依然として注意が必要です。

正しいソースがあれば、--forceオプションでそれをリモートにプッシュすることができます。指示がない限り、Gitはブランチを削除していません。実際にコミットを失った場合は、この便利なガイドを参照してコミットを回復してください。必要なコミットのSHA-1がわかっている場合は、おそらく大丈夫です。

最善の策:すべてをバックアップし、ローカルリポジトリに残っているものを確認します。可能であれば、リモートでも同じ操作を行います。git fsck物事を回復できるかどうかを確認するために使用し、何よりも実行しないでくださいgit gc

何よりも、--force本当に意味がない限り、このオプションを使用しないでください。


64
おそらく、reflogsを見て、リモートブランチが元々どこにあったかを判断できます。たとえば、git reflog show remotes/origin/master。そこにプッシュが表示されるはずです。前の行のコミットは、失敗する前の場所です。次に、そのリビジョンを(を使用して--force)オリジンにプッシュし、元の場所に戻ることができます!
Cascabel

@David:ああ。あなたはあなたの質問であなたがレポを持っていなかったとは言いませんでした。(もちろん、これは決してやりたくないことです。)ただし、プッシュした場所にファイルシステムへのアクセス権がある場合でも、そこですべてを行うことができます。
Cascabel、

1
@David:Yikes。そのようなことを避けるために、プロンプトの一部として現在のディレクトリを保持することは常に良いことです。
Cascabel、

1
@Jefromiあなたが言ったのは実際の回答であると思います:古いバージョン(git fetch長い間編集していない)でも、GitHub側のreflogを表示して回復できます!
nh2 '13

1
@Jefromiによるこの回答はどこにありますか?このユーザーがこのコメントスレッドの外でこのページに言及しているのを見かけません。
Don McCurdy

47

コミットハッシュがわかっている場合は簡単です。ブランチを再作成するだけです。

5794458...b459f069 master -> master (forced update)

リモートブランチを削除します。

git push origin :master

次に、次のコマンドを使用してブランチを再作成します。

git checkout 5794458
git branch master
git push origin master

28

解決策はすでにここで言及さています

# work on local master
git checkout master

# reset to the previous state of origin/master, as recorded by reflog
git reset --hard origin/master@{1}

# at this point verify that this is indeed the desired commit.
# (if necessary, use git reflog to find the right one, and
# git reset --hard to that one)

# finally, push the master branch (and only the master branch) to the server
git push -f origin master

ありがとう、これは私のために働いた。マスターを削除するアクセス権がなかったため、承認されたコメントは失敗しました。
アンディ

はい、そしてgit reflog show remotes/origin/mastergit reflogが必要な場合(上記の@Cascabelで言及されたとおり)
Josiah Yoder

2
これは正しい答えです。正しいものにリンクしてくれてありがとう。
Noitidart

6

強制プッシュが発生したローカルリポジトリにいない場合、オリジン/マスターレベルでは回復する方法はありません。しかし、幸運にもGitHubまたはGitHub for Enterpriseを使用できる場合は、REST APIを確認して、失われたコミットをパッチとして取得できます(例:)。

  1. イベントを一覧表示し、コミットsha1ロングフォーマットを見つける

https://api.github.com/repos/apache/logging-log4j2/events

  1. 失われたコミットをダウンロードし、jsonパス.files [] / patchで関連するパッチを取得します

https://api.github.com/repos/apache/logging-log4j2/commits/889232e28f3863d2a17392c06c1dd8cac68485de

  1. ローカルに適用してもう一度プッシュ

git apply patch.patch && git commit -m "restored commit" && git push origin master


4

以前のプッシュがローカルリポジトリからではない場合、失われたコミットを回復する、または失われたコミットを特定する別の方法は、CIマシンを調べることです。

すべてのコミット(または一連の連続したコミット)の後にマスターブランチをテストする必要があるジョブがある場合、最後にテストしていた内容を確認できます。これが、復元する必要があるコミットです。

CIマシンは、リポジトリのローカルクローンを保持することもでき、そこからこのリカバリを実行できる場合があります。

ソース:おそらく継続的デリバリー:ビルド、テスト、およびデプロイメントの自動化による信頼性の高いソフトウェアリリース(Addison-Wesley Signature Series(Fowler))


3

はい、コミットを回復できます git push -f your_branch

Docからのテキスト

指定された時間より古いエントリを整理します。このオプションが指定されていない場合、有効期限は構成設定gc.reflogExpireから取得され、デフォルトでは90日になります。--expire = allは、年齢に関係なくエントリをプルーニングします。--expire = neverは到達可能なエントリのプルーニングをオフにします(ただし--expire-unreachableを参照してください)。

だからあなたはできる:

1- git reflog

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

2-あなたはHead_Numberを選択します git reset –hard HEAD@{HEAD-NUMBER}

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

3-あなたはこの頭のすべてのコミットを見ることができます git cherry -v branch_name

4-最後にあなたはプッシュを強制する必要があります git push -f branch_name

または

1-GITクライアント(インターフェース)からSHAの数を取得する

git reset --hard commit_SHA

2-力押し

git push -f your_branch

お役に立てれば


2

1つのファイルのみの最後のプッシュを取り消すときに、同じことを行いました。リポジトリの元の状態に戻ることになってしまいました。Linuxにローカルコピーがあるため、Linusからのgitコマンドを使用していました。幸いなことに、そのコピーはまだ無傷でした。

私がしたのは(ローカルリポジトリのコピーを必死にいくつか作成した後)だけです。

git add .
git status

(それはorigin / masterが68コミット進んでいると言った、結構...それらは私が削除したすべてのコミットでした)

git remote set-url origin <GIT_SSH_URL>
git push

そして、すべてが私が強制的なプッシュをする前の状態に復元されました。覚えておくべき最も重要なことは、決してgitチェックアウトを行わないことです。あなたが強制的に押した後。ただし、ベストプラクティスはプッシュオプションを無効にすることです。二度と使用しません。私のレッスンを学びました!


0

ここで決定を読むことができますhttps://evilmartians.com/chronicles/git-push---force-and-how-to-deal-with-it

二つ目は私を助けました。これらのコマンドを間違えました

1) (some-branch) git pull -> correct command was git pull origin some-branch

2) (some-branch) git push -f origin some-branch

これらのコマンドの後、私は3つのコミットを失いました。それらを回復するために、私は間違って「git pull」したターミナルを見て、次のような出力を見ました

60223bf ... 0b258eb some-branch-> origin / some-branch

2番目のハッシュ0b258ebは、まさに私が必要としたものです。だから、私はこのハッシュを取り、コマンドを生成しました

git push --force origin 0b258eb:some-branch

0

私のように本当に悪い状況にいる人(たとえば、bad object実行中にエラーが発生した場合git reset --hard)は、次のようになります。

私が書いたtreesaverというスクリプト最後の手段としてのGitHub APIからすべてのファイルを取得します。使用方法は次のとおりです。

  1. treesaverスクリプトのクローンを作成cdします。
  2. SHAアクセスして、復元するツリーの文字列を見つけます https://api.github.com/repos/<your_username_or_org>/<repo>/events
  3. ではpayload、あなたのプッシュイベントに対応するプロパティ、見つけるcommitあなたがに戻すと、その上でクリックしたいと思いますurl
  4. 下ではcommit.tree、コピーtreeのをurl
  5. を実行しますpython3 main.py <tree_url> <path_to_save_to>

たとえば、私の場合、次のように実行します。

python3 main.py https://api.github.com/repos/anthonykrivonos/my-repo/git/trees/1234567 .

もちろん、PRは歓迎します。

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