Is there a "theirs" version of "git merge -s ours"?
Asked Answered
I

21

1128

When merging topic branch "B" into "A" using git merge, I get some conflicts. I know all the conflicts can be solved using the version in "B".

I am aware of git merge -s ours. But what I want is something like git merge -s theirs.

Why doesn't it exist? How can I achieve the same result after the conflicting merge with existing git commands? (git checkout every unmerged file from B)

The "solution" of just discarding anything from branch A (the merge commit point to B version of the tree) is not what I am looking for.

Inelastic answered 6/10, 2008 at 11:16 Comment(11)
Also see this answer: stackoverflow.com/questions/928646/… - it's trivial to change the example to use version B instead of A.Dudek
See SO answer git command for making one branch like another for all the current possible ways to simulate git merge -s their.Meit
So you are not really looking for a git merge -s theirs (that can be achieved easily with git merge -s ours and a temporary branch), since -s ours completely ignores the changes of the merge-from branch...Portraiture
@Torek - do the Git devs really find it that offensive to provide theirs in addition to ours??? This is a symptom of one of the high level engineering and design problems in Git: inconsistency.Blond
@Blond The problem here is not about "git merge -s ours" being offensive, but about it being counter-intuitive. You can see from the OP's question that if such a feature would be added he would use it by mistake when what he actually wants to do is a "git merge -s recursive -X theirs". It's common to want to merge another branch overriding conflicts with the version on the other branch, but completely overwriting the current branch with another branch completely discarding the current one's changes is really an exception case.Nectareous
Everyone should check the OP's "update" carefully as the question has nothing to do with git merge -s ours.Featherveined
See also: git merge strategiesBijection
Bottom line: it's git merge -X theirsJurgen
git merge -X theirs Doesn't work if you have hundreds of file deletions that you are trying to merge to another branch.Superstratum
@Z.Khullah Please don't rush people into quick misconceptions, the accepted answer is dangerous since it seems to answer what OP wanted but not what his question (title) actually asks. Many answers here are worth reading for a full understanding of this touchy point in git.Felicita
I strongly recommend @tshepang answer below https://mcmap.net/q/13248/-is-there-a-quot-theirs-quot-version-of-quot-git-merge-s-ours-quot. It's the most simplest and correct solution in my opinion. Using it solved my similar issue efficiently. Merge master on your branch with -s ours before merging your branch on master. Maybe consider changing accepted answer as certain people find it inaccurate.Soredium
P
1294

A similar alternative is the --strategy-option (short form -X) option, which accepts theirs. For example:

git checkout branchA
git merge -X theirs branchB

However, this is more equivalent to -X ours than -s ours. The key difference being that -X performs a regular recursive merge, resolving any conflicts using the chosen side, whereas -s ours changes the merge to just completely ignore the other side.

In some cases, the main problem using -X theirs instead of the hypothetical -s theirs is deleted files. In this case, just run git rm with the name of any files that were deleted:

git rm {DELETED-FILE-NAME}

After that, the -X theirs may work as expected.

Of course, doing the actual removal with the git rm command will prevent the conflict from happening in the first place.

Photodynamics answered 29/7, 2010 at 15:58 Comment(13)
See other answer below for a better solution (Paul Pladijs) to the original question.Sexagenary
Worth to note that this is not the same as "merge strategy theirs". -Xtheirs is the strategy option applied to recursive strategy. This means that recursive strategy will still merge anything it can, and will only fall back to "theirs" logic in case of conflicts. While this is what one needs in most cases like above, this is not the same as "just take everything from branch B as is". It does the real merge instead anyway.Aggressor
It works with other commands as well. I just did a 'git cherry-pick sha1 -X theirs'. Thanks!Warfield
@AlanWSmith This does not work in case of renamed filesAzal
I run git merge -X theirs branchB git rm --ignore-unmatch $(git diff branchB --name-only) The second command removes all deleted files automatically.Grassy
This is a terrible answer, because it looks correct, but is actually wrong. "git merge -X theirs" does not do what "git merge -s theirs" would do. It does not replace current branch with the content of the merged branch. It prefers "theirs" changes, but only in case of conflict. Therefore, the resulting commit may be quite different from "theirs" branch. This is not what the question poster had in mind.Canica
@IvanKrivyakov it's only a terrible answer, because the question is so terrible, the OP wants the opposite of git merge -X ours as opposed to the opposite of git merge -s ours. This answer should reflect that the question is factually invalid.Featherveined
@user3338098: yes, you're right. I re-read the question, and it is is also not so good. Unfortunately, the root cause of the confusion is not the answer and not even the question. It is the design choice of git authors to give the same name 'ours' to a merge strategy and to an option of merge strategy 'recursive'. The confusion in this case is practically inevitable.Canica
@Timur, it's not the right place to put a question, but which command DO "just take everything from branch B as is"?Spermogonium
@IgorNikiforov, if this solution doesn't suite the need, maybe something composed of multiple git commands can work, like in other answers below.Aggressor
@tshepang answer below https://mcmap.net/q/13248/-is-there-a-quot-theirs-quot-version-of-quot-git-merge-s-ours-quot seems the most simple and the most correct answer, merge master to your branch first, then no conflict will arise when merging back to it.Soredium
This answer really needs a re-write. As the top marked comments above suggests, this does not at all do as the answer describes. I just did a merge with -X theirs and have ended up with a rubbish amalgamation of the changes to a README from both branches. So much of the answer is incorrect, especially: "Everything will merge in the desired way. ... The only thing I've seen cause problems is if files were deleted from branchB."Lundquist
Merge with strategy ort failed. ... thats what I get when attempting git merge -X theirs master , which sucks because based on the answer, and all the discussion, it looks like exactly what I want.Anglim
A
262

A possible and tested solution for merging branchB into our checked-out branchA:

# 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

To automate it you can wrap it into a script using branchA and branchB as arguments.

This solution preserves the first and second parent of the merge commit, just as you would expect of git merge -s theirs branchB.

Archaimbaud answered 11/2, 2011 at 13:42 Comment(11)
Q: Why do you need branchTEMP? Couldn't you just git reset --soft branchA?Thorma
@cdunn2001: Somehow I thought the same thing, but no. Note that git reset --hard changes which commit branchA points to.Photophore
@tsuyoshi-ito: I see. True. But the whole thing is simpler if you just merge branchA into branchB. It's easy to fast-forward A and reset B, if desired. The only drawback is that ^ and ^^ would be reversed. I like Shyam's answer here.Thorma
I think by using git reset --soft HEAD@{1} you can achieve just the same as creating an new branch. By using this instead of git reset --soft branchTEMP you can drop the git branch branchTEMP and git branch -D branchTEMPHouseclean
The hard reset thing doesn't work for me, because then I can't keep history on my A branch.Cruciate
sorry to ask a stupid question but why is this method better the -xtheirs? what are the advantages/disadvantagesAstrophysics
@Astrophysics -x theirs only affects conflicts, if a hunk of ours can be applied cleanly it will get through to the resulting merge. In this case, as shown by the last command, we are getting a merge that is perfectly identical to branchB, regardless of whether there would have been conflicts or not.Bothnia
@Patrick: using reset won't work as the merge commit will be lost; branchTEMP though can be avoided by storing the id of the merge commit instead tmp=`git rev-parse HEAD` and then using that instead of branchTEMPBothnia
...or even better look at siegi's and thoutbeckers answers below for even more concise (and idiomatic) ways to achieve this without a temporary branchBothnia
@Bothnia thank you for the explanation, so basically doing a "theirs" would keep un-conflicted changes and files resulting int code that is not identical to the pulled code.Astrophysics
@UsAaR33 best solution for sure, but with 2 commits, to finish the job you can add : git rebase --interactive --preserve-merges HEAD~2 and result into only 1 commitJaf
B
102

Older versions of git allowed you to use the "theirs" merge strategy:

git pull --strategy=theirs remote_branch

But this has since been removed, as explained in this message by Junio Hamano (the Git maintainer). As noted in the link, instead you would do this:

git fetch origin
git reset --hard origin

Beware, though, that this is different than an actual merge. Your solution is probably the option you're really looking for.

Between answered 6/10, 2008 at 13:28 Comment(10)
thanks, I am not totally satisfy by my answer though, it was missing the checkout of other files in old. it was odd, I add to checkout them... to commit --amend them then.Inelastic
I really don't understand Junio Hamano's explanation at all. How is git reset --hard origin a solution for a theirs style merge? If I wanted to merge BranchB into BranchA (like in Alan W. Smith's answer), how would I do it using the reset method?Winker
@James McMahon: Junio C Hamano’s point is not git reset --hard does a “theirs”-style merge. Of course, git reset --hard does not create any merge commit, or any commit for that matter. His point is that we should not use a merge to replace whatever in HEAD by something else. I do not necessarily agree, though.Photophore
It is a shame that the theirs was removed because the rationale was incomplete. It failed to allow for those instances where the code is good, its just that the upstream is maintained on a different philosophical basis, so in that sense is 'bad', so one does want to both keep up to date with the upstream, but at the same time retain ones good code 'fixes' [git & msysgit have this some of this 'conflict' because of their different target platform's philosophies]Been
It's also missing the use case I'm stuck with right now, where I'm sharing a branch with someone else and we both happened to push up changes (on different files) at the same time. So I want to clobber all the old versions I have locally and use his newer ones instead. He wants to do the same for the files I updated. There's nothing to 'reset'. And the solution to checkout each individual file is not practical when it's ~20 files.Beseem
I really don't understand the philosophy. I just used theirs because I had accidentally changed some files in two separate branches and wanted to discard the changes of one without having to manually do it for every file.Perrine
@szeitlin: If the files are different there won't be any merge conflicts. So you should be able to do a simple merge to get his changes. Am I missing something?Uniat
@SaiManojKumarYadlapati I don't really remember now since it was 3 (!) years ago, but I think this was because we were told to share a branch, which was a dumb idea and pretty much defeats the purpose of git branching.Beseem
This answer should include disclaimer that git pull --strategy=theirs remote_branch is not the same as git pull -s theirs would be. Instead it's same as git pull -X theirs. And this is good but the answer should explain why.Ushas
@PhilipOakley it's not only incomplete, it's at odds with just about the rest of the Git design. The rationale is basically "get better at using T", but there are legitimate use cases to perform a "theirs" merge that have nothing to do with being bad at using Git.Deputy
W
101

It is not entirely clear what your desired outcome is, so there is some confusion about the "correct" way of doing it in the answers and their comments. I try to give an overview and see the following three options:

Try merge and use B for conflicts

This is not the "theirs version for git merge -s ours" but the "theirs version for git merge -X ours" (which is short for git merge -s recursive -X ours):

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

This is what e.g. Alan W. Smith's answer does.

Use content from B only

This creates a merge commit for both branches but discards all changes from branchA and only keeps the contents from 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

Note that the merge commits first parent now is that from branchB and only the second is from branchA. This is what e.g. Gandalf458's answer does.

Use content from B only and keep correct parent order

This is the real "theirs version for git merge -s ours". It has the same content as in the option before (i.e. only that from branchB) but the order of parents is correct, i.e. the first parent comes from branchA and the second from 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

This is what Paul Pladijs's answer does (without requiring a temporary branch).

Special cases

If the commit of branchB is an ancestor of branchA, git merge does not work (it just exits with a message like "Already up to date.").

In this or other similar/advanced cases the low-level command git commit-tree can be used.

Waddell answered 7/12, 2014 at 0:4 Comment(13)
A cleaner version of option 3: git checkout branchA; git merge -s ours --no-commit branchB; git read-tree -um @ branchB; git commitHurless
@jthill: While your version is more concise it also uses the low-level ("plumbing") command read-tree that the average git user might not be used to (at least I am not ;-) ). The solutions in the answer use only the high-level ("porcelain") commands most git users should know. I prefer them but thank you for your version nevertheless!Waddell
Can you explain the second to last step (checkout branchA)? It seems like it should not be there.Houseclean
@Patrick, this step is required. If you skip it, you'll get the same commit but you would not have a branch pointing to this commit. So as soon as you switch to another commit/branch the commit you did with the last command (…commit --amend…) would be "lost". I'm planning to add some graphical explanations to this answer as soon as I have time to do them… ;-)Waddell
I think the last option should not use words "correct parent order" because logically this option has incorrect parent order even though it does match the order asked in the question. The reason this is logically incorrect is that merging is usually done into some branch and if you merge code that's ignored, it's logically merged into current branch and as such, -s ours should always be used instead. The -s ours is intended to save some branch as deprecated and all "users" of that branch should fast forward to another branch. Putting parents in "correct" (sic) order would be opposite.Ushas
Also, this should be the accepted answer because it correctly explains that the're multiple interpretations for that seemingly simple question.Ushas
@MikkoRantalainen, my thoughts: Merging branchB into branchA should always result in branchA being the first parent and branchB the second. The chosen strategy should have no influence on this. So imitating (the non existing) strategy -s theirs to merge branchB into branchA should result in branchA being the first parent too. I agree it might not be useful that often (thats the reason it does not exist), but if you really want to do -s theirs, the correct parent order is the reverse of a content-equivalent -s ours by definition, in my opinion. Why else would you need it?Waddell
Upvoted for the "for dummies" explanations, but the last bit (getting the "right" parent order) can be done much more simply with git commit-tree (Raymod Chen's favorite git command). See the answers by jthill and Boaz Nahum for how this is done. It does require understanding git tree objects, which most git users don't.Masoretic
And git commit-tree is the only way you can do this is if "theirs" is an older version of the same branch, assuming you want that an actual merge commit. See tne 2nd graph in devblogs.microsoft.com/oldnewthing/20200928-00/?p=104302Masoretic
@Fizz, as I already stated in 2016, the exclusive use of high-level ("porcelain") commands in this answer is intentional, but thanks for the pointers to the other answers. The "theirs is an older version of the same branch" case is interesting, indeed this is not possible using simple merge, thanks for sharing! I added a reference to git commit-tree to the answer for such advanced cases.Waddell
Why do we need the first merge commit? Can't we just commit at the end, without --amend?Fuzee
@Karalga, you need the first commit (i.e. the git merge) to have a merge commit with the correct parent order. If you leave the git merge out and do the git commit without --amend you would just get a commit with the contents of branchB on top of branchA without actually merging branchB into branchA.Waddell
Right, yes, you would get a squashed commit, that makes sense, thanks.Fuzee
M
72

I used the answer from Paul Pladijs since now. I found out, you can do a "normal" merge, conflicts occur, so you do

git checkout --theirs <file>

to resolve the conflict by using the revision from the other branch. If you do this for each file, you have the same behaviour as you would expect from

git merge <branch> -s theirs

Anyway, the effort is more than it would be with the merge-strategy! (This was tested with git version 1.8.0)

Mustache answered 3/11, 2012 at 12:51 Comment(5)
would be great if the list of files could be retrieved. For example, git ls-files --modified | xargs git add I wanted to do this for added on both sides merge :/Cosec
Actually git returns the added on both sides files with git ls-files --modified so i guess this is also a viable solution.Cosec
Thanks for adding this too. More often then not it's needed on a file-by-file base. Also, git status shows "Unmerged Paths" at the very bottom. To get the list of unresolved paths, I use this alias: git config --global alias.unresolved '!git status --short|egrep "^([DAU])\1"'Undesigning
what's the meaning of -X and what's the difference between -X and -s? cannot find any document.Kindergartner
will git checkout --theirs **.* works?Dachia
F
26

When merging topic branch "B" in "A" using git merge, I get some conflicts. I >know all the conflicts can be solved using the version in "B".

I am aware of git merge -s ours. But what I want is something like git merge >-s their.

I'm assuming that you created a branch off of master and now want to merge back into master, overriding any of the old stuff in master. That's exactly what I wanted to do when I came across this post.

Do exactly what it is you want to do, Except merge the one branch into the other first. I just did this, and it worked great.

git checkout Branch
git merge master -s ours

Then, checkout master and merge your branch in it (it will go smoothly now):

git checkout master
git merge Branch
Felid answered 8/9, 2013 at 9:40 Comment(1)
Thanks. This should be the accepted answer, by far the simplest and the most correct. If your branch is behind/conflicts with master, then its the branch job to merge and make everything work before merging back everything to master.Soredium
I
22

I solved my problem using

git checkout -m old
git checkout -b new B
git merge -s ours old
Inelastic answered 6/10, 2008 at 11:34 Comment(2)
a branch "B" from "old" branchInelastic
question about merging from B to old with solving conflicts using changes from branch b ove old, your answer is working telling opposite way.Subdeacon
T
14

If you are on branch A do:

git merge -s recursive -X theirs B

Tested on git version 1.7.8

Turbellarian answered 12/4, 2012 at 19:17 Comment(1)
this is logical, -s and -X togetherTenorrhaphy
M
10

Why doesn't it exist?

While I mention in "git command for making one branch like another" how to simulate git merge -s theirs, note that Git 2.15 (Q4 2017) is now clearer:

The documentation for '-X<option>' for merges was misleadingly written to suggest that "-s theirs" exists, which is not the case.

See commit c25d98b (25 Sep 2017) by Junio C Hamano (gitster).
(Merged by Junio C Hamano -- gitster -- in commit 4da3e23, 28 Sep 2017)

merge-strategies: avoid implying that "-s theirs" exists

The description of -Xours merge option has a parenthetical note that tells the readers that it is very different from -s ours, which is correct, but the description of -Xtheirs that follows it carelessly says "this is the opposite of ours", giving a false impression that the readers also need to be warned that it is very different from -s theirs, which in reality does not even exist.

-Xtheirs is a strategy option applied to recursive strategy. This means that recursive strategy will still merge anything it can, and will only fall back to "theirs" logic in case of conflicts.

That debate for the pertinence or not of a theirs merge strategy was brought back recently in this Sept. 2017 thread.
It acknowledges older (2008) threads

In short, the previous discussion can be summarized to "we don't want '-s theirs' as it encourages the wrong workflow".

It mentions the alias:

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

Yaroslav Halchenko tries to advocate once more for that strategy, but Junio C. Hamano adds:

The reason why ours and theirs are not symmetric is because you are you and not them---the control and ownership of our history and their history is not symmetric.

Once you decide that their history is the mainline, you'd rather want to treat your line of development as a side branch and make a merge in that direction, i.e. the first parent of the resulting merge is a commit on their history and the second parent is the last bad one of your history. So you would end up using "checkout their-history && merge -s ours your-history" to keep the first-parenthood sensible.

And at that point, use of "-s ours" is no longer a workaround for lack of "-s theirs".
It is a proper part of the desired semantics, i.e. from the point of view of the surviving canonical history line, you want to preserve what it did, nullifying what the other line of history did.

Junio adds, as commented by Mike Beaton:

git merge -s ours <their-ref> effectively says 'mark commits made up to <their-ref> on their branch as commits to be permanently ignored';
and this matters because, if you subsequently merge from later states of their branch, their later changes will be brought in without the ignored changes ever being brought in.

Meit answered 14/10, 2017 at 6:19 Comment(0)
B
9

To really properly do a merge which takes only input from the branch you are merging you can do

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

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

git commit --amend

There will be no conflicts in any scenario I know of, you don't have to make additional branches, and it acts like a normal merge commit.

This doesn't play nice with submodules however.

Badge answered 30/10, 2013 at 14:47 Comment(4)
What does the -R do here?Competence
This way you lose the history of files "moved and changed". Am I right?Nagano
The -R is --reverse, I updated the answer with that to be more self-documenting.Chan
This doesn't seem to work if the files you are trying to merge are deleted in the incoming branch.Lissotrichous
H
8

See Junio Hamano's widely cited answer: if you're going to discard committed content, just discard the commits, or at any rate keep it out of the main history. Why bother everyone in the future reading commit messages from commits that have nothing to offer?

But sometimes there are administrative requirements, or perhaps some other reason. For those situations where you really have to record commits that contribute nothing, you want:

(edit: wow, did I manage to get this wrong before. This one works.)

git update-ref HEAD $(
        git commit-tree -m 'completely superseding with branchB content' \
                        -p HEAD -p branchB    branchB:
)
git reset --hard
Hurless answered 13/5, 2013 at 15:48 Comment(1)
This the Raymond-Chen-favored method of getting Paul Pladijs' result. Not surprisingly, few people here get it.Masoretic
P
4

This one uses a git plumbing command read-tree, but makes for a shorter overall workflow.

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>
Performing answered 22/4, 2015 at 19:18 Comment(0)
C
2

The equivalent(which keep parent order) to 'git merge -s theirs branchB'

Before merge:enter image description here

!!! Make sure you are in clean state !!!

Do the merge:

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

What we did ? We created a new commit which two parents ours and theirs and the contnet of the commit is branchB - theirs

After merge:enter image description here

More precisely:

git commit-tree -m "take theirs" -p HEAD -p 'SOURCE^{commit}' 'SOURCE^{tree}'
Caret answered 14/5, 2018 at 15:43 Comment(1)
Same as jthill's answer, methinks, but with a bit more visual explantion.Masoretic
S
2

This answer was given by Paul Pladijs. I just took his commands and made a git alias for convenience.

Edit your .gitconfig and add the following:

[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"

Then you can "git merge -s theirs A" by running:

git checkout B (optional, just making sure we're on branch B)
git mergetheirs A
Superstratum answered 29/5, 2019 at 21:17 Comment(0)
E
1

I think what you actually want is:

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

This seems clumsy, but it should work. The only think I really dislike about this solution is the git history will be confusing... But at least the history will be completely preserved and you won't need to do something special for deleted files.

Estreat answered 31/8, 2016 at 13:41 Comment(0)
C
1

this experiment helps. It creates a conflict and then resolves it

git checkout -b b1
echo "on branch b1 making the first change" >> merge_test.txt
git add merge_test.txt
git commit merge_test.txt -m "b1 first change"

git checkout -b b1-2
echo "on branch b1-2 making the first change" >> merge_test.txt
git add merge_test.txt
git commit merge_test.txt -m "b1-2 first change"

git checkout b1
echo "on branch b1 making the second change" >> merge_test.txt
git add merge_test.txt
git commit merge_test.txt -m "b1 2nd change"

git checkout b1-2

at this stage if you run git merge b1 you see there is a conflict. so you run git merge --abort to revert it

then run git merge -X theirs b1

if you have a look you will see that the content of the file is now

on branch b1 making the first change
on branch b1 making the second change

the changes from b1 are reflected in the b1-2 branch

Corroboree answered 19/4, 2023 at 16:24 Comment(0)
S
0

This will merge your newBranch in existing 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
Sessile answered 28/1, 2013 at 12:35 Comment(1)
I'd suggest adding git commit --amend to the end of your example, or users may see the merge commit with git log and assume the operation is complete.Performing
P
0

Revisiting this old question, as I just found a solution that is both short and – since it uses only porcelain commands – easy to understand. To be clear, I want to answer the problem stated in the title of the question (implement git merge -s theirs), not the question body. In other words, I want to create a merge commit with a tree identical to the tree of its second parent:

# Start from the branch that is going to receive the merge.
git switch our_branch

# Create the merge commit, albeit with the wrong tree.
git merge -s ours their_branch

# Replace our working tree and our index with their tree.
git restore --source=their_branch --worktree --staged :/

# Put their tree in the merge commit.
git commit --amend

Caveat: git restore is a fairly new command, introduced in git 2.23. git help restore warns that

THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.

I did test this method with multiple versions of git (2.25.1, 2.30.2, 2.31.1, 2.34.1 and 2.35.1), and it worked as expected.

Pilcomayo answered 14/10, 2022 at 13:35 Comment(1)
Don't worry about the "experimental" disclaimer: those commands are here to stay.Meit
S
0

This doesn't necessarily answer the original poster's question, but I landed here in a situation where I had already attempted a merge but ended up with conflicts. Usually I manage conflicts in an IDE, but when I don't have access to that, the following REGEX can be used to find and replace differences with the "theirs" content:

Replce <<<<<<< HEAD\n[^•>]+\n=======\n([^•>]+)>>>>>>> .+\n with \1

(Just in case anyone else lands on this page for the same reason I did).

Stupe answered 1/12, 2022 at 14:36 Comment(0)
A
-1

I just recently needed to do this for two separate repositories that share a common history. I started with:

  • Org/repository1 master
  • Org/repository2 master

I wanted all the changes from repository2 master to be applied to repository1 master, accepting all changes that repository2 would make. In git's terms, this should be a strategy called -s theirs BUT it does not exist. Be careful because -X theirs is named like it would be what you want, but it is NOT the same (it even says so in the man page).

The way I solved this was to go to repository2 and make a new branch repo1-merge. In that branch, I ran git pull [email protected]:Org/repository1 -s ours and it merges fine with no issues. I then push it to the remote.

Then I go back to repository1 and make a new branch repo2-merge. In that branch, I run git pull [email protected]:Org/repository2 repo1-merge which will complete with issues.

Finally, you would either need to issue a merge request in repository1 to make it the new master, or just keep it as a branch.

Amen answered 27/3, 2017 at 14:31 Comment(0)
R
-1

A simple and intuitive (in my opinion) two-step way of doing it is

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

followed by

git merge -s ours branchB

(which marks the two branches as merged)

The only disadvantage is that it does not remove files which have been deleted in branchB from your current branch. A simple diff between the two branches afterwards will show if there are any such files.

This approach also makes it clear from the revision log afterwards what was done - and what was intended.

Regain answered 5/10, 2018 at 6:44 Comment(3)
this may be correct for the original question, however the OP updated the question in 2008 in such a way that this answer is incorrect.Featherveined
@Featherveined Yeah, such a pity that they left the misleading title and just slapped a not so visible update at the end of the question body.... because this answers does answer correctly the title question.Felicita
I completely agree with @RomainValeriFeedback

© 2022 - 2024 — McMap. All rights reserved.