web-dev-qa-db-ja.com

「git Push」でリモートファイルを上書きする

私は自分のローカルファイルをプッシュして、マージの競合に対処する必要なしにリモートレポジトリにそれらを持たせたいのです。私は自分のローカルバージョンがリモートバージョンよりも優先されるようにしたいだけです。

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

619
opensas

次のようにして、ローカルのリビジョンをリモートレポジトリに強制することができます。

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(content):<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 'development 

更新3: --force-with-leaseオプションを "より安全な"強制プッシュとして使うこともできます、 彼の答えでCupcakeが述べたように

「リース」による強制プッシュでは、予期していなかった新しいコミットがリモート上にある場合(強制的にまだリモート追跡ブランチにコミットしていない場合)、強制プッシュが失敗する可能性があります。あなたはまだあなたがまだ知らなかった他の誰かのコミットを誤って上書きしたくない、そしてあなたはあなた自身を上書きしたいだけです:

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

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

896
Trevor Norris

あなたはプッシュを強制したい

あなたが基本的にやりたいことは、リモートブランチを上書きするために、あなたのローカルブランチをプッシュすることです。

以下の各コマンドの詳細説明が必要な場合は、以下の詳細セクションを参照してください。あなたは基本的に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

分岐を省略する

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

git Push <remote> --force

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

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

Remoteとbranchの両方が省略された場合、git Push --forceだけの振る舞いはあなたのPush.default Git設定によって決定されます。

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

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

Push.defaultまたは オンライン版のgit-config(1)マニュアルページ を読むことで、git help config設定をもっと読むことができます。

--force-with-leaseでより安全にプッシュする

「リース」による強制プッシュでは、予期していなかった新しいコミットがリモート上にある場合(強制的にまだリモート追跡ブランチにコミットしていない場合)、強制プッシュが失敗する可能性があります。あなたはまだあなたがまだ知らなかった他の誰かのコミットを誤って上書きしたくない、そしてあなたはあなた自身を上書きしたいだけです:

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

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

110
user456814

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

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

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

28
VonC

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

{--force-with-lease}がすることは、私たちが期待している状態でない限り、ブランチの更新を拒否することです。すなわち、誰も上流のブランチを更新していない。実際には、これは上流のrefが期待通りのものであることをチェックすることによって機能します。なぜなら、refはハッシュであり、暗黙的に親のチェーンをそれらの値にエンコードするからです。何をチェックするのかを正確に{--force-with-lease}に伝えることができますが、デフォルトでは現在のリモート参照をチェックします。これが実際に意味することは、Aliceが彼女のブランチを更新してそれをリモートリポジトリにプッシュアップすると、ブランチのrefを指すヘッドが更新されるということです。今、ボブがリモートから引っ張らない限り、リモートへの彼のローカル参照は時代遅れになるでしょう。彼が{--force-with-lease}を使用してPushにアクセスすると、gitはローカルのrefを新しいリモートと照合し、pushを強制することを拒否します。 {--force-with-lease}は、その間に他に誰も変更をリモートにプッシュしていない場合にのみ、事実上、強制プッシュを許可します。シートベルトがついている{--force}です。

3
Lando Ke

git Push --set-upstream Origin master -f

0
Jithish P N