リモートファイルを上書きするように「git push」を強制する


768

マージの競合に対処することなく、ローカルファイルをプッシュしてリモートリポジトリに配置したいと考えています。ローカルバージョンをリモートバージョンよりも優先したいだけです。

Gitでこれを行うにはどうすればよいですか?


106
git push origin --forceうまくいきませんでしたか?


.gitファイルのみ、または関連する作業コピーを上書きするかどうかは不明です。それがgitリポジトリであれば、git pushが答えです。リモートの作業用コピーを更新する場合は、ポスト受信フックを使用する必要があります
Pierre-Olivier Vares

@Mikeそれは私のために何らかの理由で動作します... OPで何が起こったのか疑問に思います

考えられる原因は、強制プッシュが機能しないことです。これは、リモートレポで明示的に無効にされている可能性があります(ばかばかしいまたは悪質な寄稿者が原因で何も失われないようにするため)config receive.denyNonFastforwards
Frank Nocke 2017年

回答:


1088

次のコマンドを使用して、ローカルリビジョンをリモートリポジトリに強制できるはずです。

git push -f <remote> <branch>

(例git push -f origin master)。立ち去る<remote>と、<branch>設定したすべてのローカルブランチが強制的にプッシュされ--set-upstreamます。

注意してください。他の人がこのリポジトリを共有している場合、その変更履歴は新しいリポジトリと競合します。また、変更後のローカルコミットがある場合、それらは無効になります。

更新:サイドノートを追加すると思いました。他の人がレビューする変更を作成している場合、それらの変更を含むブランチを作成し、定期的にリベースしてメインの開発ブランチで最新の状態に保つことは珍しいことではありません。これが定期的に行われることを他の開発者に知らせて、彼らが何を期待するかを知ってもらいます。

アップデート2:視聴者の数が増加しているためupstream、フォースプッシュが発生した場合の対処方法について追加情報を追加したいと思います。

私があなたのリポジトリを複製し、そのようないくつかのコミットを追加したとしましょう:

            D ---- Eトピック
           /
A ---- B ---- C開発

しかし、後でdevelopmentブランチはでヒットされ、rebase実行するとgit pull次のようなエラーが発生します。

オブジェクトの解凍:100%(3/3)、完了。
<repo-location>から
 *ブランチ開発-> FETCH_HEAD
<ファイル>の自動マージ
CONFLICT(コンテンツ):<場所>での競合のマージ
自動マージが失敗しました。競合を修正してから結果をコミットします。

ここで私は衝突を修正することができましたcommitが、それは私に本当に醜いコミット履歴を残すでしょう:

       C ---- D ---- E ---- Fトピック
      / /
A ---- B -------------- C '開発

魅力的に見えるかもしれませgit pull --forceんが、取り残されたコミットが残るので注意してください。

            D ---- Eトピック

A ---- B ---- C '開発

したがって、おそらく最良のオプションはを実行することgit pull --rebaseです。これにより、以前と同様に競合を解決する必要がありますが、コミットする代わりに各ステップでを使用しますgit rebase --continue。結局、コミット履歴はずっと良く見えるでしょう:

            D '--- E'トピック
           /
A ---- B ---- C '開発

更新3:カップケーキの回答で述べられているように--force-with-lease、このオプションを「より安全な」強制プッシュとして使用することもできます

「リース」を使用した強制プッシュでは、リモートに予期しない新しいコミットがある場合(技術的には、まだそれらをリモート追跡ブランチにフェッチしていない場合)、強制プッシュが失敗します。これは、次の場合に便利です。まだ知らない他人のコミットを誤って上書きしたくないので、自分のコミットを上書きしたいだけです。

git push <remote> <branch> --force-with-lease

--force-with-lease次のいずれかを読むと、使用方法の詳細を知ることができます。


5
これが選択された答えなので、ここでコメントします。自分で作業する場合、力の使用は問題ではありません。たとえば、私のクラウドホストは独自のgitで始まります。ローカルで作業してプロジェクトをビルドし、それを自分のクラウドホスト(OpenShift)に置きたい場合、2つの別々のgitプロジェクトがあります。私のローカルと私のOpenShift One。私は自分の好きなようにローカルを取得しましたが、OpenShiftでプレビューしたいと思います。次に、-fフラグを使用して、初めてOpenShiftにプッシュします。基本的に、ローカルgitをOpenShiftに配置します。
2016

128

強制的に押したい

基本的には、リモートブランチを上書きするためにローカルブランチを強制的にプッシュする必要があります。

次の各コマンドの詳細な説明が必要な場合は、以下の詳細セクションを参照してください。基本的に、Gitでの強制プッシュには4つの異なるオプションがあります。

git push <remote> <branch> -f
git push origin master -f # Example

git push <remote> -f
git push origin -f # Example

git push -f

git push <remote> <branch> --force-with-lease

各コマンドの詳細な説明が必要な場合は、以下の私の長い回答のセクションを参照してください。

警告:強制プッシュは、リモートブランチを、プッシュしているブランチの状態で上書きします。これが実際に使用したいことを確認してから使用してください。そうしないと、実際に保持したいコミットが上書きされる可能性があります。

強制プッシュの詳細

リモートとブランチの指定

特定のブランチとリモートを完全に指定できます。-fフラグの短いバージョンであります--force

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

ブランチを省略する

pushブランチへのブランチが省略されている場合、Gitは構成設定に基づいてそれを理解します。2.0以降のGitバージョンでは、新しいリポジトリには、現在チェックアウトされているブランチをプッシュするデフォルト設定があります。

git push <remote> --force

2.0より前のバージョンでは、新しいリポジトリにはデフォルト設定があり、複数のローカルブランチをプッシュします。問題の設定はremote.<remote>.pushおよびpush.default設定です(以下を参照)。

リモートとブランチを省略する

リモートとブランチの両方が省略されている場合、justの動作はGit構成設定git push --forceによって決まりpush.defaultます。

git push --force
  • Git 2.0以降、デフォルト設定のはsimple、基本的には現在のブランチを上流のリモートカウンターにプッシュするだけです。リモートはブランチのbranch.<remote>.remote設定によって決まり、それ以外の場合はデフォルトでオリジンリポジトリに設定されます。

  • Gitバージョン2.0より前のデフォルト設定はmatching、基本的に、すべてのローカルブランチをリモート上の同じ名前のブランチにプッシュするだけです(デフォルトはoriginです)。

git-config(1)マニュアルページをpush.default読んgit help configだり、オンライン版を読んだりしてより多くの設定を読むことができます。

より安全に押す --force-with-lease

「リース」を使用した強制プッシュでは、リモートに予期しない新しいコミットがある場合(技術的には、まだそれらをリモート追跡ブランチにフェッチしていない場合)、強制プッシュが失敗します。これは、次の場合に便利です。まだ知らない他人のコミットを誤って上書きしたくないので、自分のコミットを上書きしたいだけです。

git push <remote> <branch> --force-with-lease

--force-with-lease次のいずれかを読むと、使用方法の詳細を知ることができます。


あなたは正しいですが、これは本当に例外的な状況でのみ使用されるべきです。
Scott Berrevoets、2014

1
@ScottBerrevoets「私は自分が持っているものをプッシュして、統合するのではなくリモートで上書きすることを望みます。」私はOPに彼の要求を正確に与えました。

私は知っていますが、OPはこれを行うことの結果を認識していない可能性があります。あなたは技術的に質問に答えましたが、これを行わないという警告は場違いではないと思います。
Scott Berrevoets 14

1
私は新しい言及ので、私は司会を持ってしようとしている@ScottBerrevoetsは、正規のに私の答えをマージ--force-with-leaseオプションを;)


32

別のオプション(他の貢献者にとって問題になる可能性のある強制プッシュを回避するため)は、次のとおりです。

  • 新しいコミットを専用ブランチに入れます
  • あなたのリセットmasterにしますorigin/master
  • 専用ブランチをにマージしmaster、常に専用ブランチからのコミットを維持します(つまり、masterその上に新しいリビジョンを作成すると、専用ブランチがミラー化されます)。をシミュレーションする方法については、「あるブランチを別のブランチにするためのgitコマンド
    」を参照してください。git merge --strategy=theirs

そうすれば、何も強制せずにマスターをリモートにプッシュできます。


結果は "push -force"とどのように異なりますか?
alexkovelsky

6
@alexkovelsky強制的にプッシュすると、履歴が書き直され、リポジトリの他のユーザーが自分のローカルリポジトリをリセットして、新しくプッシュされたコミットに一致するようになります。このアプローチでは、新しいコミットが作成されるだけで、強制的なプッシュは必要ありません。
VonC、2018年

1
回答に見出しを追加することをお勧めします。「プッシュを強制したくない」:)
alexkovelsky

@alexkovelsky良い点。私はそれに応じて答えを編集しました。
VonC、2018年

4

git push -fは、チームの他のユーザーが行ったリモートの変更をリセットするため、少し破壊的です。より安全なオプションは{git push --force-with-lease}です。

{--force-with-lease}が行うことは、私たちが期待する状態でない限り、ブランチの更新を拒否することです。つまり、誰も上流のブランチを更新していません。実際には、これは上流のrefが期待どおりであることを確認することで機能します。これは、refがハッシュであり、親のチェーンをその値に暗黙的にエンコードするためです。何をチェックするかを正確に{--force-with-lease}に伝えることができますが、デフォルトでは現在のリモート参照をチェックします。これが実際に意味することは、アリスがブランチを更新してリモートリポジトリにプッシュすると、ブランチの参照ポインティングヘッドが更新されるということです。ここで、ボブがリモートからプルしない限り、リモートへのローカル参照は古くなります。{--force-with-lease}を使用してプッシュしようとすると、gitはローカル参照を新しいリモートに対してチェックし、プッシュの強制を拒否します。{--force-with-lease}を使用すると、変更を暫定的にリモートにプッシュした人が他にいない場合にのみ、強制的にプッシュすることができます。シートベルトを装着した状態で{--force}です。



0

TortoiseGitを使用した簡単な手順

ローカルファイルをコミットしてGitリポジトリにプッシュするGIT。

手順:

1)stashは stash名を変更します

2)引っ張る

3)スタッシュポップ

4)コミット 1つのまたは複数のファイルを変更し、記述のセット著者と日付をコミット与えます

5)押す

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