Search code examples
gitgit-merge

Git merge? - completely ignore one branch changes


I got a classic situation - master and multiple branches. I need to merge changes (many changes through multiple commits) into master, but I want to ignore any changes that were made in master itself. I want master to be a clone of my branch.

I know that I could just checkout every file from branch into master and commit changes, but that won't make graph pretty :)

How can I achieve that? Solving merge-conflits is not enough, because there are still some changes that were auto-merged. Do I have to remove them manually or is there some git merge --magic option that could help me?

ADD: I'd like files to be exact copy between branch and master (not commit history), but I'd like to have all that squished to single commit.


Solution

  • The key here is to realize that Git stores snapshots (which Git calls the tree of a commit). There are no changes in any commit, just a snapshot and some metadata. If you see changes, that's an illusion brought about by taking two commits and comparing them. Think about an old style movie film: each frame of the film holds a snapshot image, frozen in time, and we only see movement because we look at 24 carefully-sequenced frames every second.

    What this means is that you can construct a commit "by hand" at any time if you like. If you want the snapshot of commit a123456 to be the next snapshot on the current branch, you simply make a new commit whose parent is the current commit, but whose tree is from commit a123456:

    git commit-tree -m "insert your message here" -p HEAD -p a123456 a123456^{tree}
    

    or similar. The two -p arguments here make this a merge commit, so that this is the result of the missing -s theirs merge strategy. This new commit—Git prints its hash ID to stdout; you must grab it from there—is not yet on any branch, so you now need to update the current branch name, using git merge --ff-only or git update-ref.

    See jthill's answer to Is there a "theirs" version of "git merge -s ours"? (note that the question itself is now a bit confused due to December 2008 edit to the original October 2008 question, and some answers are about -X theirs, which is different).