951

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

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

4

6 に答える 6

1293

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

git push -f <remote> <branch>

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

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

更新:補足を追加すると思いました。他の人がレビューする変更を作成している場合、それらの変更を含むブランチを作成し、定期的にリベースして、メインの開発ブランチで最新の状態に保つことは珍しくありません。他の開発者に、これが定期的に発生することを知らせてください。

更新 2upstream : 視聴者数が増加しているため、強制プッシュが発生した場合の対処方法について追加情報を追加したいと思います。

あなたのレポを複製し、次のようなコミットをいくつか追加したとします。

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

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

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

ここで競合 と を修正できますが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: Cupcake の回答で言及されているように--force-with-lease、オプションを「より安全な」強制プッシュとして使用することもできます。

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

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

使用方法の詳細について--force-with-leaseは、次のいずれかを参照してください。

于 2012-05-09T05:48:23.470 に答える
35

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

  • 新しいコミットを専用ブランチに入れる
  • masterオンをリセットするorigin/master
  • 専用ブランチを にマージし、専用ブランチからmasterのコミットを常に保持します (専用ブランチmasterをミラーリングする新しいリビジョンを作成することを意味します)。.
    _ _ _git merge --strategy=theirs

そうすれば、何も強制することなく、マスターをリモートにプッシュできます。

于 2012-05-09T06:00:57.320 に答える
4

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

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

于 2017-07-05T11:32:34.087 に答える