Gitの別のブランチにあるブランチを「マージ」するのではなく、「上書き」するにはどうすればよいですか?


257

私は2本の枝を持っている、emailstagingstagingは最新のものであり、emailブランチの古い変更は不要になりましたが、削除したくありません。

私はただのすべての内容をダンプするようstagingemailので、彼らは同じに両方のポイントコミットしていること。それは可能ですか?


回答:


196

「ours」マージ戦略を使用できます。

$ git checkout staging
$ git merge -s ours email # Merge branches, but use our branch head

26
私はこれを試しました、そしてそれは私には逆のようですか?これは、電子メールの内容をステージングにダンプし、その逆ではないのですか?
最大

27
@マックス私も同じように混乱していて、多くのトラブルを引き起こしました。新しいブランチ(ステージング)からこのコマンドを実行してから、古いブランチ(メール)に通常のマージ/ PRを実行する必要があります。
MrGlass 2014

7
なぜ;各コマンドの最後にあるのですか?私はなしでやった;、それは働いているようです。また、この回答は不完全です。3番目の手順は、古いブランチ(メール)をチェックアウトしてから、ステージングと再度マージすることです。
Rosdi Kasim 2014

4
git rebase -s theirs <oldbranc> <newbranch> 同様に機能します(あなたがどのブランチであるかは関係ありません)。リベースでは、「私たち」が現在コミットを適用しているヘッドであるため、「彼ら」は実際には新しいブランチです。
Rolf

4
@Rolf:ただし、リベースはマージ情報を削除し、履歴をフラット化します。必ずしもあなたが求めているものとは限りません。また、すでに公開されている履歴を使用している場合もお勧めできません。
knittl 2015年

99

2つのブランチ「email」と「staging」を同じにしたい場合は、「email」ブランチにタグを付けてから、「email」ブランチを「staging」ブランチにリセットします。

$ git checkout email
$ git tag old-email-branch
$ git reset --hard staging

'staging'ブランチを 'email'ブランチにリベースすることもできます。ただし、結果には2つのブランチの変更が含まれます。


1
おそらくあなたはgit checkoutgit check私の知る限り存在しないことを意味します
knittl

4
そうです、私はgitコマンドのタブ補完に慣れているので、常に「git check <TAB>」と書いて「git checkout」と書いています。修正。
Sylvain Defresne、2011年

17
git resetは、あなたのリポジトリを複製した他の人々のリポジトリを壊します
Geoffrey De Smet

これが正しい答えだと思います。emailブランチのヘッドは同じヘッドを指すだけstagingで、どちらも同じコミット、同じ履歴を持ちます。
cicerocamargo 2017

76

私はいくつかの回答を見てきましたが、これが競合なしに修正できる唯一の手順です。

branch_oldのbranch_newからのすべての変更が必要な場合:

git checkout branch_new
git merge -s ours branch_old
git checkout branch_old
git merge branch_new

これらの4つのコマンドを適用すると、問題なくbranch_oldをプッシュできます。


5
HEADをリセットしたくなかったので、あなたの答えは本当に私の問題に最もよく当てはまります。古いものにマージするときに新しいブランチの新しいファイルの設定を指定し、問題なく動作しました!+1
2015

「ours merge」の後、branch_newをリモートにプッシュしましたが、この方法でうまくいきました。プッシュする必要があったのですか?またはそれなしでうまくいったでしょうか?(ローカルブランチとリモートのどちらを使用するかは不明でした)。ありがとう!
aspergillusOryzae 2016年

なぜあなたは単に以下を行うことができないのですか?gitのチェックアウトbranch_old gitのマージはから取ら彼らbranch_new手がかり-s stackoverflow.com/questions/14275856/...
Ripuダマン

それは、マージ戦略「彼ら」を見つけることができなかったと言います。
arango_86

私にとって完璧に機能し、何もリセットしないという利点があります
Romain

68

他の答えは私に正しい手がかりを与えましたが、それらは完全に助けにはなりませんでした。

これが私のために働いたものです:

$ git checkout email
$ git tag old-email-branch # This is optional
$ git reset --hard staging
$
$ # Using a custom commit message for the merge below
$ git merge -m 'Merge -s our where _ours_ is the branch staging' -s ours origin/email
$ git push origin email

私たちの戦略とマージする4番目のステップがないと、プッシュは早送りではないと見なされ、拒否されます(GitHubによって)。


それはマージコミットメッセージを間違っていますが、そうです、それはうまくいきます。
cdunn2001

cdunn2001、私は好奇心が強い。あなたが期待していたマージコミットメッセージは何でしたか?
Shyam Habarakada 2012年

「リモート追跡ブランチ 'origin / email'を電子メールにマージする」と書かれています。ステージングについては触れていません。大したことはありません。コミットを修正するか、を使用してくださいmerge -m 'This is not my beautiful house.' -s ours origin/email
cdunn2001

@ShyamHabarakada、私はあなたが言うとおりにします、そして私は非早送りアップデートについて問題を抱えています。4番目のステップを実行しても何も起こらないからです。
kommradHomer

4番目のステップではorigin / emailを使用する必要があります。ローカルのメールだけでは機能しません。
Travis Reeder 2013

45

あなたが私のようなものであり、マージに対処したくない場合は、上記の手順を実行できますが、マージの代わりにforceを使用します。

git checkout email
git reset --hard staging
git push origin email --force

注:これは、本当にメールの内容を二度と見たくない場合のみです。


1
git push origin email --Step2で分岐が分岐したため、forceが機能しませんでした。ステップ2の後、これは私がやったことです:git reset origin / emailそしてgit push
user3505394

2
これはまさに、質問された「マージではなく上書きする方法」です。受け入れられるべき答え。
jozols 2018

17

2つのブランチをマージして、すべてのコンテンツをのコンテンツでold_branch更新したかったnew_branch

私にとってこれは魅力のように機能しました:

$ git checkout new_branch
$ git merge -m 'merge message' -s ours origin/old_branch
$ git checkout old_branch
$ git merge new_branch
$ git push origin old_branch

10

どうですか:

git branch -D email
git checkout staging
git checkout -b email
git push origin email --force-with-lease

@emptywallsは、サーバーに拒否される可能性があることをユーザーに警告せずに強制プッシュを実行するため、また、それが必要な理由を説明しないためです。つまり、1-開発プロジェクトのための現実的な選択肢だ、と述べた
デヴィッド・コスタ

@DavidCostaなぜこれがサーバーによって拒否されるのですか?これは単純なメールブランチの削除とステージングをメールにコピーすることです...だから、私は「ステージング」のすべてのコンテンツを「メール」にダンプして、両方が同じコミットを指すようにしたいだけです-これがまさに起こっていることですここに。
Arek S 2016

@ArekSブランチがGitLabなどで「保護されている」と設定されている場合、サーバー側のフックによって拒否される可能性があります。問題は、この操作の前に誰かがメールからブランチを派生させてプッシュしようとすると、参照が一致しないことです(一部のコミットが単純に消滅したため)
David Costa

1
オリジナルを--forceから--force-with-leaseに編集しました。これは、非破壊的な方法でトリックを実行します。
frandroid

1
これは、ブランチを吹き飛ばして、ソースブランチからクリーンに開始したい場合に最適な方法です。
シェーン

6

他の回答は不完全に見えました。
私は完全に以下を試しました、そしてそれはうまくいきました。

注意:
1.安全のため、以下を試す前にリポジトリのコピーを作成してください。

詳細:
1.すべての開発はdevブランチで行われます
2. qaブランチはdevの同じコピーです
3.時々、コードはqaブランチに移動/上書きする必要があります

したがって、開発ブランチからqaブランチを上書きする必要があります

パート1:
以下のコマンドで、古いqaが新しい開発に更新されました:

git checkout dev
git merge -s ours qa
git checkout qa
git merge dev
git push

最後のプッシュの自動コメントは以下になります:

// Output:
//  *<MYNAME> Merge branch 'qa' into dev,*  

上記のシーケンスも逆に見えるため、このコメントは逆に見えます

パート2:

以下は、devでの予期しない新しいローカルコミットであり、不要なものである
ので、捨てて、devをそのままにする必要があります。

git checkout dev

// Output:
//  Switched to branch 'dev'  
//  Your branch is ahead of 'origin/dev' by 15 commits.  
//  (use "git push" to publish your local commits)


git reset --hard origin/dev  

//  Now we threw away the unexpected commits

パート3:
すべてが期待どおりであることを確認します。

git status  

// Output:
//  *On branch dev  
//  Your branch is up-to-date with 'origin/dev'.  
//  nothing to commit, working tree clean*  

それで全部です。
1.古いqaが新しいdevブランチコードによって上書きされるようになりました
2.ローカルがクリーンです(リモートorigin / devはそのままです)


6

それを行う最も簡単な方法:

//the branch you want to overwrite
git checkout email 

//reset to the new branch
git reset --hard origin/staging

// push to remote
git push -f

これで、メールブランチとステージングは​​同じです。


2
警告:これにより、emailブランチ上のすべてのコミットが削除されます。これは、emailブランチを削除して、ブランチの先頭に新しく作成するようなものstagingです。
キャメロンハドソン

2
git checkout email
git merge -m "Making email same as staging disregarding any conflicts from email in the process" -s recursive -X theirs staging

1
コマンドでのコメントのマージとは別にコメントを作成した場合、この答えはより明確になります。-Xの機能と、このマージへの影響を簡単に説明してください。ありがとう。:)
noelicus

@noelicusコメントをありがとう、あなたは正しい。将来は答えを編集するかもしれません。
ウィラ

0

これは元の新しいブランチを変更せず、最終的なコミットの前にさらに変更を加える機会を与えます。

git checkout new -b tmp
git merge -s ours old -m 'irrelevant'
git checkout old
git merge --squash tmp
git branch -D tmp
#do any other stuff you want
git add -A; git commit -m 'foo' #commit (or however you like)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.