9

I have two branches, "private" and "public". I work on the private and periodically, I want to replace everything in "public" branch to have a clean copy of files in "private".

As I don't want the history of "private" go to "public", I use git merge --squash, but I still manually have solve merge files one by one. Is there a better way to do this?

Nevik Rehnel
  • 40,995
  • 6
  • 55
  • 46
Fred Yang
  • 2,441
  • 1
  • 21
  • 26
  • possible duplicate of (or rather, probably answer by): http://stackoverflow.com/questions/1922336/how-to-merge-a-branch-into-another-with-override-option-in-git – Nevik Rehnel Feb 06 '13 at 14:45
  • seems similar question, but the answer is wrong. "ours" is actually do the other way around, discard private and keep public. What I want is something like --strategy="theirs", but this is not a legal options. – Fred Yang Feb 06 '13 at 15:14
  • 1
    possible duplicate of [git merge -s ours, what about "theirs"](http://stackoverflow.com/questions/173919/git-merge-s-ours-what-about-theirs) –  Apr 12 '14 at 02:40

2 Answers2

11

I think

git merge -X theirs private

is what you are looking for. And of course you can append --squash as you like.

dyng
  • 2,621
  • 19
  • 22
6

Squashing the merge will not change the fact that there are conflicts if the same lines have changed on both files of the commit.

To completely discard everything on the "public" branch and take over the exact state of "public", you can do one of these:

  1. Use the ours merge strategy (not the strategy option) as pointed out in several other commits:
    1.a assume you are on branch "private" (otherwise, do git checkout private)
    1.b git merge -s ours public
    1.c git checkout public
    1.d git merge --ff-only private
    1.e (optional: both branches are now pointing to the merge commit; if you want "private" to point to the commit before the merge, do:) git checkout private; git reset --hard private@{1} (Note that this uses the reflog and will only work like this if you havent changed "private" in the meantime)

  2. Check out the "theirs" side manually:
    2.a assume you are on branch "public" (otherwise, git checkout public)
    2.b git merge --no-commit private will prepare a merge-commit, but stop before committing no matter if there is a merge conflict or not
    2.c git checkout -f private -- . to check out the current state of "private"
    2.d git add . to mark conflicts as resolved (if any)
    2.e git commit to save the merge commit; "public" will now have the exact same contents as "private"

Edit: Note that this is the inverted case of How do I 'overwrite', rather than 'merge', a branch on another branch in Git?

Edit 2: If you want to hide your single commits of public, you can use the --squash switch here too, of course (in steps 1.b and 2.b, respectively)

Tim Sylvester
  • 21,850
  • 2
  • 69
  • 92
Nevik Rehnel
  • 40,995
  • 6
  • 55
  • 46