web-dev-qa-db-ja.com

どのようにしてGitプッシュを適切に強制するのですか?

私はリモートの非ベア "メイン"レポジトリをセットアップし、それを私のコンピュータにクローンしました。私はいくつかのローカルな変更を加え、私のローカルリポジトリを更新し、そしてその変更を私のリモートリポジトリにプッシュしました。それまでは問題ありませんでした。

今、私はリモートレポの何かを変更しなければなりませんでした。それから私は私の地元のレポの何かを変えました。私は、リモートリポジトリへの変更は必要ないことに気づきました。そこで私は自分のローカルレポジトリから自分のリモートレポジトリへgit Pushを試みましたが、以下のようなエラーになりました。

あなたが履歴を失うのを防ぐために、早送りでない更新は拒否されました再度プッシュする前にリモートの変更をマージしてください。詳細はgit Push --helpの '早送りについての注意'をご覧ください。

私はおそらくそれを考えた

git Push --force

私のローカルコピーを強制的にリモートのものに変更をプッシュし、それを同じにします。 更新を強制します しかし、リモートリポジトリに戻ってコミットすると、ファイルに古い変更が含まれていることがわかります(メインのリモートリポジトリに以前にあったもの)。

で述べたように、答えの1つに対するコメント

[I]強制しようとしましたが、変更を保存するためにマスターサーバーに戻ると、古いステージングが発生します。したがって、コミットしたときにリポジトリが同じではありません。そしてもう一度git Pushを使おうとすると、同じエラーが出ます。

どうすればこの問題を解決できますか?

1133
Spyros

ただしてください:

git Push Origin <your_branch_name> --force

あるいはあなたが特定のレポを持っているなら:

git Push https://git.... --force

これにより、以前のコミットを削除して現在のコミットをプッシュします。

それは適切ではないかもしれませんが、誰かがこのページにつまずいた場合、彼らは単純な解決策を望んでいるかもしれないと思いました...

短い旗

-f--forceの短縮形であることにも注意してください。

git Push Origin <your_branch_name> -f

また動作します。

2066
Katie S

また、Push --forceが機能しない場合は、Push --deleteを実行できます。 2を見てくださいnd このインスタンスの行:

git reset --hard HEAD~3  # reset current branch to 3 commits ago
git Push Origin master --delete  # do a very very bad bad thing
git Push Origin master  # regular Push

しかし、注意してください...

公共のgit履歴に戻ることはありません!

言い換えると:

  • forceパブリックリポジトリをプッシュしないでください。
  • これや、誰かのpullを壊すようなことはしないでください。
  • reporesetまたはrewrite履歴は、誰かがすでにプルした可能性があります。

もちろん、このルールにも非常にまれな例外がありますが、ほとんどの場合、それを行う必要はなく、他のすべての人に問題が発生します。

代わりに元に戻します。

そして、常に公開リポジトリにプッシュするものに注意してください。元に戻す:

git revert -n HEAD~3..HEAD  # prepare a new commit reverting last 3 commits
git commit -m "sorry - revert last 3 commits because I was not careful"
git Push Origin master  # regular Push

実際には、bothOrigin HEAD(fromrevertおよびfromevil reset)には同じファイルが含まれます。


編集して、Push --forceの周りに更新された情報とより多くの引数を追加します

プッシュの代わりにリースで力をプッシュすることを検討しますが、それでも元に戻すことを好みます

Push --forceがもたらす可能性のある別の問題は、誰かがあなたの前に何かをプッシュしたとき、しかしあなたがすでにフェッチした後です。 rebasedバージョンを強制的にプッシュすると、他の人から作業を置き換えます

git 1.8.5@ VonCに感謝 質問へのコメント)で導入されたgit Push --force-with-leaseは、この特定の問題に対処しようとします。基本的に、最新のフェッチ以降にリモートが変更された場合、プッシュではなくエラーが発生します。

これは、Push --forceが本当に必要であるが、それ以上の問題を防ぎたい場合に適しています。私は、それがデフォルトのPush --forceの振る舞いであるべきだと言っているまで行きます。しかし、Pushを強制する言い訳になるにはほど遠い。 rebaseの前にfetchedする人々は、まだ多くのトラブルを抱えています。reverted代わりに。

そして、git --Pushインスタンスについて話しているので...

なぜ誰かがプッシュを強制するのでしょうか?

@ linquize コメントに適切なプッシュフォースの例を示しました:sensitive data。プッシュすべきではないデータを誤ってリークしました。十分な速さであれば、プッシュを上に強制することで "fix"*できます。

*データは引き続きリモートにありますガベージコレクト 、または 何らかの方法でクリーンアップ も実行しない限り。また、すでにフェッチした他のユーザーによって拡散される可能性もありますが、アイデアは得られます。

233
cregox

まず第一に、私は「メイン」リポジトリに直接変更を加えることはしません。あなたが本当に "メイン"レポを持ちたいのなら、あなたはそれにプッシュするだけで、決して直接それを変更するべきではありません。

あなたが得ているエラーに関して、あなたはあなたのローカルレポジトリからgit pullを、そして次にメインレポジトリにgit Pushを試みましたか?あなたが現在やっていることは(私がそれをよく理解していれば)プッシュを強制してから「メイン」レポであなたの変更を失うことです。まずローカルで変更をマージする必要があります。

18
ubik

私がローカルブランチAにいて、ローカルブランチBをOriginブランチCにプッシュしたい場合は、次の構文を使用できます。

git Push --force Origin B:C
14
IcedDante

私は本当にお勧めします:

  • メインリポジトリのみにプッシュする

  • メインリポジトリの作業ツリーが.gitベースと同期していないことで問題が発生しないように、メインリポジトリが bare repo であることを確認してください。 「 ローカルのgitリポジトリを別のコンピュータにプッシュする方法? 」を参照してください。

  • もしあなたがメイン(ベア)リポジトリに変更を加える必要があるならば、それを(メインサーバ上で)クローンし、あなたの変更を行いそしてそれにプッシュバックしてください

言い換えれば、プルアップ/プルする/からプルアップする単一の上流レポジトリを持つために、メインサーバとローカルコンピュータの両方からベアレポジトリにアクセスできるようにしてください。

11
VonC

次のコマンドを使用してください。

git Push -f Origin master
6
mustafa Elsayed

これは、歴史を維持しながら企業のgitHubリポジトリのmasterを置き換えるための私達の解決策でした。

企業のリポジトリをマスターするためのPush -fは、ブランチの履歴を維持するためにしばしば無効にされます。この解決策は私たちのために働きました。

git fetch desiredOrigin
git checkout -b master desiredOrigin/master // get Origin master

git checkout currentBranch  // move to target branch
git merge -s ours master  // merge using ours over master
// vim will open for the commit message
git checkout master  // move to master
git merge currentBranch  // merge resolved changes into master

ブランチをdesiredOriginにプッシュしてPRを作成してください

5
mihai

私は同じ質問をしましたが、ついにそれを考え出しました。最も必要なことは、次の2つのgitコマンドを実行することです(hashをgit commitのリビジョン番号に置き換えます)。

git checkout <hash>
git Push -f HEAD:master
0
Brian