web-dev-qa-db-ja.com

エラーのあるgit Push -f Origin masterから回復するにはどうすればよいですか?

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

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

74
mrdavenz

Gitは一般に何も捨てませんが、これからの回復は依然として難しい場合があります。

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

最善の方法:すべてをバックアップし、ローカルリポジトリにまだあるものを確認します。可能であれば、リモートで同じことを行います。 _git fsck_を使用して、回復できるかどうかを確認し、何よりも_git gc_を実行しないでください。

何よりも、本当に(本当に)意味しない限り、_--force_オプションを使用しないでください。

44
Cameron Skinner

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

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

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

git Push Origin :master

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

git checkout 5794458
git branch master
git Push Origin master
45
user1094125

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

# 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
21
Abdelhafid

強制プッシュが発生したローカルリポジトリにない場合、Origin/masterレベルでは回復する方法はありません。しかし、 GitHub または GitHub for Enterprise を使用するのに十分なluckyであれば、 [〜#〜] 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 "restoreed commit" && git Push Origin master

6

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

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

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

ソース:おそらく 連続配信:ビルド、テスト、および展開の自動化による信頼性の高いソフトウェアリリース(Addison-Wesley Signature Series(Fowler))

2
user7610

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

私がやったことは(必死にローカルレポのコピーをもう少し作成した後)でした:

git add .
git status

(Origin/masterは68件のコミットで先行していると言っていましたが、それらは私が削除したすべてのコミットでした)

git remote set-url Origin <GIT_SSH_URL>
git Push

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

2
Pran

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

2番目は助けてくれました。これらのコマンドを間違えた

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一部分岐->起源/一部分岐

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

git Push --force Origin 0b258eb:some-branch
0
Andrey