Gitプッシュを適切に強制するにはどうすればよいですか?


1274

私はリモートの裸でない「メイン」リポジトリをセットアップし、それを自分のコンピューターに複製しました。ローカルに変更を加え、ローカルリポジトリを更新して、変更をリモートリポジトリにプッシュしました。その時点までは順調でした。

さて、リモートリポジトリで何かを変更する必要がありました。次に、ローカルリポジトリで何かを変更しました。リモートリポジトリへの変更は必要ないことに気付きました。そのためgit push、ローカルリポジトリからリモートリポジトリに移動しようとしましたが、次のようなエラーが発生しました。

履歴が失われないようにするために、非早送りの更新は拒否されました。リモートの変更をマージしてから、もう一度プッシュします。詳細については、「早送りに関する注意」セクションgit push --helpを参照してください。

たぶん

git push --force

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

私はで述べたように答えの1のコメント

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

この問題を解決するにはどうすればよいですか?


4
間もなく(git1.8.5、2013年第4四半期)git push -forceより慎重実行できるようになります
VonC


6
私自身の回答詳しく説明しているようにgit push --force確かにプッシュを強制する別の有効な方法でありgit push origin master --force、Gitのデフォルトと同様にブランチをプッシュしますがpush.default config settings、具体的にプッシュされるブランチは、2.0以前のGitバージョンと2.0以降のGitバージョンで異なります。

2
git push --force最近はFWIWで問題なく動作します...
rogerdpack

git push --force-with-leaseそれがあなたが期待する状態でない限り、それはより良く動作します:)、それはブランチを更新することを拒否します。(developer.atlassian.com/blog/2015/04/force-with-leaseを参照)
spoorcc

回答:


2309

ただやる:

git push origin <your_branch_name> --force

または、特定のリポジトリがある場合:

git push https://git.... --force

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

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

短い旗

また、はの-f略な--forceので、

git push origin <your_branch_name> -f

も動作します。


58
git push origin +master代わりに使用できます。これにより、すべてを強制せずに複数のrefspecをプッシュできます。
ニックグリム2013年

5
あなたが誤ってばかりならば、あることに注意してくださいgit push --force、あなたはあなたのmasterブランチをいじりに終わるかもしれない...どの吸うかもしれない(あなたのプッシュデフォルトの動作によって異なります)。..ビット..:D
Jeewes

9
@JeewesはGitバージョン2.0以降、基本的にはのデフォルトの動作でgit push --force、現在チェックアウトされているブランチをリモートカウンターパーツに強制的にプッシュするため、マスターブランチをチェックアウトしている場合はと同じになりgit push origin master --forceます。2.0より前のGitバージョンのデフォルトであるのmatching設定を使用している場合は異なりますpush.defaultすべてのローカルブランチを同じ名前のリモートブランチにmatchingプッシュするため、強制プッシュは確実に実行したくないものになる可能性があります...

@Jeewesしかし、Git 2.0では、デフォルトの方が安全であり、少なくとも危険なほど危険でgit push origin master --forceはありません。

2
push -fは適切ですが、ほとんどの企業リポジトリではマスターに対して-fが無効になっているため、マスターには推奨されません。merge -s ours私のために働いた
mihai

247

動作push --forceしない場合は、行うことができますpush --delete。このインスタンスの2 行目を見てください。

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
  • 誰かがすでに引っ張っている可能性のあるレポの中でこれまでに、resetまたは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

実際には元のHEAD(復帰悪意のあるリセット)の両方に同じファイルが含まれます。


編集して、更新された情報と周囲の引数を追加します push --force

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

別の問題としてpush --forceは、誰かがあなたの前に何かを押したときですが、あなたがすでにフェッチした後です。リベースされたバージョンを今すぐ強制すると、他の人の作業置き換えられます

git push --force-with-leasegit 1.8.5で導入された(質問に対する@VonCコメントのおかげで)は、この特定の問題に対処しようとします。基本的に、エラーが発生し、最後のフェッチ以降にリモートが変更された場合はプッシュされません。

これは、a push --forceが本当に必要であると確信しているが、それ以上の問題を回避したい場合に適しています。私はそれがデフォルトのpush --force振る舞いであるべきだと言って遠くまで行きます。しかし、それを強制するための言い訳にはほど遠いpushリベースの前にフェッチした人はまだ多くの問題を抱えていますが、元に戻せば簡単に回避できます。

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

なぜ誰かがプッシュを強制したいのですか?

@linquizeは、コメントに優れたプッシュフォースの例、機密データをもたらしました。プッシュすべきではないデータを誤ってリークしました。十分に速い場合は、上にプッシュすることで「修正」できます*

*データはまだ、リモートになります、あなたもやるしない限り、収集ごみを、または何らかの形でそれをきれいに。また、それをすでに取得している他のユーザーによって拡散される可能性があることは明らかですが、そのアイデアは理解できます。


1
問題、@ rogerdpackは、それが実行可能であるかどうかではありません。そうです。しかし、それは大災害を要約することができます。誰かがそれを実行すればするほど(強制プッシュ)、パブリックリポジトリからの更新(プル)の頻度が少ないほど、災害は大きくなります。ご存知のように世界を解体することができます!!! 111少なくともその特定のリポジトリで構成される世界。
cregox 2013

3
機密データがある場合は、強制的にプッシュしてください
2013年

3
@Cawas:リポジトリから機密データを削除しようとしている場合は、履歴を書き換えたいという意味だと思います。元に戻すと、機密データは以前のコミットに残っています。とはいえ、他の誰かがすでにリポジトリからプルした場合、履歴を書き換えても、機密データへのアクセスを防ぐことはできません。その時点ではすでに遅すぎます。
Stuart Golodetz

3
git push origin master --delete # do a very very bad bad thing git push origin master # regular pushこれは実際に私の問題を完全に解決しました(私と私の友達だけのリポジトリで)。多分それは公共のリポジトリにとっては間違っていますが、民間のリポジトリにとってはこれは命の恩人です。
缶Poyrazoğlu

1
これは、一部のレポマネージャー、別名自動スカッシュなどで自動的に行われます。コミットを削減するために機能ブランチを終了した後に強制的にプッシュすることは一般的であり、予想されます。
FlavorScape

18

まず第一に、「メイン」レポジトリに直接変更を加えません。本当に「メイン」のリポジトリが必要な場合は、プッシュするだけで、直接変更しないでください。

発生しているエラーについて、git pullローカルリポジトリからgit pushメインリポジトリにトライしましたか?あなたが現在行っていること(私がそれをよく理解している場合)は、プッシュを強制し、「メイン」リポジトリの変更を失うことです。最初にローカルで変更をマージする必要があります。


はい私はプルを試みましたが、そのプルのためにデータを失っています。メインから更新することなく、ローカルと同じようにメインリポジトリを作成したいと考えています。
Spyros、2011

1
その場合はを使用しgit push -fますが、メインリポジトリを再度変更する場合は、ローカルリポジトリに戻ってgit pull、最新の変更と同期するようにする必要があります。その後、あなたはあなたの仕事をして、もう一度押すことができます。この "push-pull"ワークフローに従うと、不満を言っていたようなエラーは発生しません。
ubik

ええ、私はこれが私のせいだったと理解しています:/私はそれを試して少しの間戻ってきます。ありがとう
Spyros

1
強制しようとしましたが、マスターサーバーに戻って変更を保存すると、古いステージングが表示されます。したがって、私がコミットするとき、リポジトリは同じではありません。もう一度git pushを使用しようとすると、同じエラーが発生します。
Spyros

17

ローカルブランチAにいて、ローカルブランチBをオリジンブランチに強制的にプッシュする場合CIは、次の構文を使用できます。

git push --force origin B:C

2
私は自分の地元の支店Bにいても、まだやらなければならないことがわかりましたgit push --force origin B:C。私の場合、git push --force origin C現在どのブランチにいるかに関係なく、ローカルマスターからリモートCブランチにのみプッシュするようです。 git version 2.3.8 (Apple Git-58)
Weishi Zeng 2015

12

次のコマンドを使用します。

git push -f origin master

1
この答えが他の答えよりも好ましい理由と、それが異なる点について、もう少し説明してください。
アダム

ああ、ご迷惑をおかけして申し訳ありません。私は同じ問題を抱えていました。このコマンドで解決しました。共有する必要があると思いました。
mustafa Elsayed 2017

12
それは他のものと同じで、-f旗の位置を変更しただけです...
svelandiag

11

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

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

  • 必ずメインのレポがあることを確認裸のレポメインレポ作業ツリーはそのと同期していないことに問題がないんために、.gitベースを。「ローカルgitリポジトリを別のコンピューターにプッシュする方法は?」を参照してください

  • メイン(ベア)リポジトリで変更を行う必要がある場合は、それを(メインサーバーで)複製し、変更を行ってからプッシュします。

つまり、メインサーバーとローカルコンピューターの両方からベアリポジトリにアクセスできるようにして、プル/プルの対象となる単一のアップストリームレポを取得/プルできるようにします。


5

これは、履歴を維持しながら企業のgitHubリポジトリでマスターを置き換えるためのソリューションでした。

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

ブランチをプッシュしてdesiredOriginPRを作成する


3

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

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