“ theirs”はありますか“ git merge -s ours&#8221 ;?

StackOverflow https://stackoverflow.com/questions/173919

  •  05-07-2019
  •  | 
  •  

質問

トピックブランチ" B"をマージする場合「A」に git merge を使用すると、競合が発生します。すべての競合は" B"のバージョンを使用して解決できることを知っています。

git merge -s ours を知っています。しかし、私が欲しいのは git merge -s theirs のようなものです。

なぜ存在しないのですか?既存の git コマンドとの競合のマージ後に同じ結果を得るにはどうすればよいですか? ( git checkout Bのすべてのマージされていないファイル)

UPDATE:" solution"ブランチA(ツリーのBバージョンへのマージコミットポイント)から何かを単に破棄することは、私が探しているものではありません。

役に立ちましたか?

解決

-X オプションを theirs に追加します。例:

git checkout branchA
git merge -X theirs branchB

すべてが目的の方法でマージされます。

問題が発生するのは、ファイルがbranchBから削除された場合のみです。 git以外の何かが削除を行うと、競合として表示されます。

修正は簡単です。削除されたファイルの名前で git rm を実行するだけです:

git rm {DELETED-FILE-NAME}

その後、 -X theirs は期待どおりに動作するはずです。

もちろん、 git rm コマンドを使用して実際の削除を行うことにより、そもそも競合が発生しなくなります。


:より長い形式のオプションもあります。使用するには、次を置き換えます。

-X theirs

with:

--strategy-option=theirs

他のヒント

ブランチBをチェックアウトされたブランチAにマージするための可能なテスト済みソリューション:

# in case branchA is not our current branch
git checkout branchA

# make merge commit but without conflicts!!
# the contents of 'ours' will be discarded later
git merge -s ours branchB    

# make temporary branch to merged commit
git branch branchTEMP         

# get contents of working tree and index to the one of branchB
git reset --hard branchB

# reset to our merged commit but 
# keep contents of working tree and index
git reset --soft branchTEMP

# change the contents of the merged commit
# with the contents of branchB
git commit --amend

# get rid off our temporary branch
git branch -D branchTEMP

# verify that the merge commit contains only contents of branchB
git diff HEAD branchB

自動化するには、branchAとbranchBを引数として使用してスクリプトにラップします。

このソリューションは、 git merge -s theirs branchB で予想されるように、マージコミットの最初と2番目の親を保持します。

gitの古いバージョンでは、「theirs」を使用できました。マージ戦略:

git pull --strategy=theirs remote_branch

ただし、このメッセージで浜野潤夫によって説明されているように、これはその後削除されました。 (Gitメンテナー)。リンクに記載されているように、代わりにこれを行います:

git fetch origin
git reset --hard origin

ただし、これは実際のマージとは異なることに注意してください。あなたのソリューションはおそらくあなたが本当に探しているオプションです。

私は今からPaul Pladijsの回答を使用しました。私は、「通常」を実行できることを知りました。マージ、競合が発生するため、あなたは

git checkout --theirs <file>

他のブランチのリビジョンを使用して競合を解決します。ファイルごとにこれを行うと、予想される動作と同じ

git merge <branch> -s theirs

とにかく、努力はマージ戦略の場合よりも多くなります! (これはgitバージョン1.8.0でテストされました)

希望する結果が何であるかは完全には明らかではないため、「正しい」ことについて混乱が生じています。回答とコメントでそれを行う方法。概要を説明しようとすると、次の3つのオプションが表示されます。

マージにBを使用して競合を解決します

これは、 git merge -s ours &quot;の&quot;バージョンではありません;ただし、「 git merge -X ours &quot;のバージョン」 (これは git merge -s recursive -X ours の略です):

git checkout branchA
# also uses -s recursive implicitly
git merge -X theirs branchB

これは、たとえばアランW.スミスの答えはそうです。

Bのコンテンツのみを使用する

これにより、両方のブランチに対してマージコミットが作成されますが、 branchA からのすべての変更が破棄され、 branchB からの内容のみが保持されます。

# Get the content you want to keep.
# If you want to keep branchB at the current commit, you can add --detached,
# else it will be advanced to the merge commit in the next step.
git checkout branchB

# Do the merge an keep current (our) content from branchB we just checked out.
git merge -s ours branchA

# Set branchA to current commit and check it out.
git checkout -B branchA

マージのコミットの最初の親は branchB からのものであり、2番目の親は branchA からのものです。これは、例えば Gandalf458の答えはそうです。

Bのコンテンツのみを使用し、正しい親の順序を維持する

これは、 git merge -s ours &quot;の実際の&quot;バージョンです。前のオプションと同じ内容(つまり、 branchB からのみ)がありますが、親の順序は正しいです。つまり、最初の親は branchA から、2番目は親から branchB

git checkout branchA

# Do a merge commit. The content of this commit does not matter,
# so use a strategy that never fails.
# Note: This advances branchA.
git merge -s ours branchB

# Change working tree and index to desired content.
# --detach ensures branchB will not move when doing the reset in the next step.
git checkout --detach branchB

# Move HEAD to branchA without changing contents of working tree and index.
git reset --soft branchA

# 'attach' HEAD to branchA.
# This ensures branchA will move when doing 'commit --amend'.
git checkout branchA

# Change content of merge commit to current index (i.e. content of branchB).
git commit --amend -C HEAD

これは、ポールプラディスの答えの機能です(一時的なブランチは不要です)。

使用して問題を解決しました

git checkout -m old
git checkout -b new B
git merge -s ours old

ブランチAにいる場合:

git merge -s recursive -X theirs B

gitバージョン1.7.8でテスト済み

  

トピックブランチ&quot; B&quot;をマージする場合&quot; A&quot; git mergeを使用すると、競合が発生します。 &gt; Bのバージョンを使用すると、すべての競合を解決できることがわかっています。

     

git merge -s oursを知っています。しかし、私が欲しいのはgit merge&gt; -s theirのようなものです。

masterからブランチを作成し、masterにマージして、master内の古いものを上書きしたいと仮定しています。それがまさにこの投稿に出会ったときにやりたかったことです。

最初に1つのブランチを他のブランチにマージすることを除いて、やりたいことを正確に実行します。私はちょうどこれをやった、そしてそれはうまくいった。

git checkout Branch
git merge master -s ours

次に、マスターをチェックアウトし、ブランチをマージします(今はスムーズに進みます):

git checkout master
git merge Branch

マージするブランチからのみの入力を受け取るマージを本当に適切に行うには、次のようにします

git merge --strategy = ours ref-to-be-be-merged

git diff --binary ref-to-be-merged | git apply --reverse --index

git commit --amend

私が知っているどのシナリオでも競合はありません。追加のブランチを作成する必要はなく、通常のマージコミットのように動作します。

ただし、これはサブモジュールではうまくいきません。

浜野順夫の広く引用されている回答を参照:コミットを破棄する場合コンテンツ、単にコミットを破棄する、またはとにかくそれをメイン履歴から除外します。なぜ提供するものがないコミットからのコミットメッセージを読んで、将来誰もが気にするのですか?

ただし、管理上の要件がある場合や、その他の理由がある場合があります。何も貢献しないコミットを本当に記録しなければならない状況では、以下が必要です:

(編集:うわー、前にこれを間違えたことがありましたか。これは動作します。)

git update-ref HEAD $(
        git commit-tree -m 'completely superseding with branchB content' \
                        -p HEAD -p branchB    branchB:
)
git reset --hard
  

なぜ存在しないのですか

&quot; あるブランチを別のブランチのように作成するgitコマンド&quot; git merge -s theirs をシミュレートする方法、Git 2.15(2017年第4四半期)がより明確になったことに注意してください:

  

マージの「 -X&lt; option&gt; 」のドキュメントは誤解を招くようなものでした   &quot; -s theirs &quot;を示唆するために書かれた存在しますが、そうではありません。

commit c25d98b (2017年9月25日)を参照してください。 ://github.com/gitster "rel =" nofollow noreferrer "> C Hamanoジュニオ( gitster )。
C浜野邦夫- gitster - commit 4da3e23 、2017年9月28日)

  

merge-strategies:&quot; -s theirs &quot;存在する

     

-Xours マージオプションの説明には括弧付きの注記があります   それは読者に -s ours とは非常に異なることを伝えます。   正しいですが、それに続く -Xtheirs の説明   &quot;これは ours &quot;の反対であり、誤って   読者もそれが非常に重要であると警告される必要があるという印象   実際には存在しない -s theirs とは異なります。

-Xtheirs は、再帰戦略に適用される戦略オプションです。これは、再帰戦略が可能な限りすべてをマージし、&quot; theirs &quot;のみにフォールバックすることを意味します。競合の場合のロジック。

theirs マージ戦略の適切性に関する議論が最近持ち帰られましたこの2017年9月のスレッドで。
古い(2008)スレッド

  

要するに、前の議論は、「 -s theirs 」は間違ったワークフローを助長するため、「 -s theirs 」にはなりません。

エイリアスについて言及しています:

mtheirs = !sh -c 'git merge -s ours --no-commit $1 && git read-tree -m -u $1' -

ヤロスラフ・ハルチェンコはその戦略のためにもう一度擁護しようとしている、ジュニオC.浜野

  

私たちのものと彼らのものが対称ではない理由は、あなたがあなたであり彼らではないからです。私たちの歴史と彼らの歴史の制御と所有権は対称ではありません。

     

履歴がメインラインであると判断したら、開発ラインをサイドブランチとして扱い、その方向にマージすることをお勧めします。つまり、結果のマージの最初の親は履歴のコミットです。そして、2番目の親はあなたの歴史の最後の悪い親です。そのため、&quot; 彼らの履歴をチェックアウト&amp;&amp; merge -s your-history &quot;に   最初の親権を賢明に保ちます。

     

そして、その時点で&quot; -s ours &quot;を使用します&quot; -s theirs &quot;の不足の回避策ではなくなりました。
  これは望ましいセマンティクスの適切な部分です。つまり、存続する標準的な履歴行の観点からは、それが行った内容を保存し、他の履歴行が行ったことを無効にします

>

これはgit plumbingコマンドread-treeを使用しますが、全体的なワークフローが短くなります。

git checkout <base-branch>

git merge --no-commit -s ours <their-branch>
git read-tree -u --reset <their-branch>
git commit

# Check your work!
git diff <their-branch>

これにより、newBranchが既存のbaseBranchにマージされます

git checkout <baseBranch> // this will checkout baseBranch
git merge -s ours <newBranch> // this will simple merge newBranch in baseBranch
git rm -rf . // this will remove all non references files from baseBranch (deleted in newBranch)
git checkout newBranch -- . //this will replace all conflicted files in baseBranch

あなたが実際に欲しいのは:

git checkout -B mergeBranch branchB
git merge -s ours branchA
git checkout branchA
git merge mergeBranch
git branch -D mergeBranch

これは不器用なようですが、動作するはずです。私がこのソリューションについて本当に嫌いだと思うのは、gitの履歴が紛らわしいということだけです...しかし、少なくとも履歴は完全に保存され、削除されたファイルに対して特別なことをする必要はありません。

「git merge -s theirs branchB」と同等の(親の順序を保持する)

マージ前: ここに画像の説明を入力してください

!!!クリーンな状態であることを確認してください!!!

マージを実行:

git commit-tree -m "take theirs" -p HEAD -p branchB 'branchB^{tree}'
git reset --hard 36daf519952 # is the output of the prev command

私たちがしたこと  2人の親が自分と自分の親であり、コミットのコントロールがbranchB-彼らのものである新しいコミットを作成しました

マージ後: ここに画像の説明を入力してください

より正確には:

git commit-tree -m "take theirs" -p HEAD -p 'SOURCE^{commit}' 'SOURCE^{tree}'

この回答はPaul Pladijsによって与えられました。便宜上、彼のコマンドを使用してgitエイリアスを作成しました。

.gitconfigを編集して、次を追加します。

[alias]
    mergetheirs = "!git merge -s ours \"$1\" && git branch temp_THEIRS && git reset --hard \"$1\" && git reset --soft temp_THEIRS && git commit --amend && git branch -D temp_THEIRS"

その後、「git merge -s theirs A」を使用できます実行:

git checkout B (optional, just making sure we're on branch B)
git mergetheirs A

最近、共通の履歴を共有する2つの別個のリポジトリに対してこれを行う必要がありました。始めたのは:

  • Org / repository1マスター
  • Org / repository2マスター

repository2 master からのすべての変更を repository1 master に適用し、repository2が行うすべての変更を受け入れるようにしました。 gitの用語では、これは と呼ばれる戦略である必要がありますが、存在しません。 -X theirs はあなたが望むものと同じように命名されているので注意してください。 >

これを解決したのは、 repository2 に移動して、新しいブランチ repo1-merge を作成することでした。そのブランチでは、 git pull git@gitlab.com:Org / repository1 -s ours を実行しましたが、問題なくマージされます。それをリモートにプッシュします。

次に repository1 に戻り、新しいブランチ repo2-merge を作成します。そのブランチでは、 git pull git@gitlab.com:Org / repository2 repo1-merge を実行しますが、これは問題を抱えて完了します。

最後に、 repository1 でマージリクエストを発行して新しいマスターにするか、ブランチとして保持する必要があります。

シンプルで直感的な(私の意見では)2段階の方法があります

git checkout branchB .
git commit -m "Picked up the content from branchB"

続いて

git merge -s ours branchB

(2つのブランチをマージ済みとしてマークします)

唯一の欠点は、branchBで削除されたファイルを現在のブランチから削除しないことです。その後、2つのブランチ間の単純なdiffは、そのようなファイルがあるかどうかを示します。

このアプローチは、何が行われたのか、そして何が意図されたのかを、その後の改訂ログからも明確にします。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top