Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I 'overwrite', rather than 'merge', a branch on another branch in Git?

Tags:

git

I have two branches, email and staging. staging is the latest one and I no longer need the old changes in email branch, yet I don't want to delete them.

So I just want to dump all the contents of staging into email so that they both point to the same commit. Is that possible?

like image 861
Rafid Avatar asked Jan 07 '11 10:01

Rafid


People also ask

How do I pull changes from another branch without merging?

You could use git checkout from the branch you want to transfer the changes to: git checkout <branch name> . That will change all files to match the version in the desired branch. Then you can commit, change, discard whatever you want.

Does git merge overwrite?

Usually git does not overwrite anything during merge.


1 Answers

You can use the 'ours' merge strategy:

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

EDIT 2020-07-30:

I thought a bit more about this question and possible solutions. If you absolutely require the merge parents in the correct order, need to perform this action with a single command line invocation, and don't mind running plumbing commands, you can do the following:

$ git checkout A $ git merge --ff-only $(git commit-tree -m "Throw away branch 'A'" -p A -p B B^{tree}) 

This basically acts like the (non-existent) merge -s theirs strategy. You can find the resulting history in the plumbing branch of the demo repository

Not very readable and not as easy to remember compared to the -s ours switch, but it does the job. The resulting tree is again the same as branch B:

$ git rev-parse A^{tree} B^{tree} HEAD^{tree} 3859ea064e85b2291d189e798bfa1bff87f51f3e 0389f8f2a3e560b639d82597a7bc5489a4c96d44 0389f8f2a3e560b639d82597a7bc5489a4c96d44 

EDIT 2020-07-29:

There seems to be a lot of confusion as to what the difference between -s ours and -X ours (the latter being equivalent to -s recursive --strategy-option ours) is. Here's a small example to show the two results from using these two methods. I also recommend reading the question and answers of (Git Merging) When to use 'ours' strategy, 'ours' option and 'theirs' option?

First, setup a repository with 2 branches and 3 commits (1 base commit, and 1 commit per branch). You can find the sample repository on GitHub

$ git init $ echo 'original' | tee file1 file2 file3 $ git commit -m 'initial commit' $ git branch A $ git branch B $ git checkout A $ echo 'A' > file1 $ git commit -m 'change on branch A' file1 $ git checkout B $ echo 'B' > file2 $ git commit -m 'change on branch B' file2 

Now, let's try the strategy option (doesn't really matter if we use theirs or ours for this explanation):

$ git merge -X ours A $ cat file* A B original 

We end up with a merge of both branches' contents (branch "strategy-option" in the sample repo). Compare that to using the merge strategy (re-init your repository or reset branch, before executing the next steps):

$ git merge -s ours A $ cat file* original B original 

The result is quite different (branch "merge-strategy" in the sample repo). With the strategy option, we get a merge result of both branches, with the strategy we throw away any changes which happened in the other branch.

You will also notice that the commit created by the merge-strategy in fact points to the exact same tree than the latest commit of "our" branch, while the strategy-option created a new, previously unseen tree:

$ git rev-parse A^{tree} B^{tree} merge-strategy^{tree} strategy-option^{tree} 3859ea064e85b2291d189e798bfa1bff87f51f3e 0389f8f2a3e560b639d82597a7bc5489a4c96d44 0389f8f2a3e560b639d82597a7bc5489a4c96d44 5b09d34a37a183723b409d25268c8cb4d073206e 

OP indeed asked for "I no longer need the old changes in […] branch" and "So I just want to dump all the contents of [A] into [B]", which is not possible to do with a strategy option. Using the 'ours' merge strategy is one possibility of many, but likely the easiest (other possibilities include using low level commands of Git such as write-tree and commit-tree).

like image 79
knittl Avatar answered Sep 21 '22 06:09

knittl