git overwrite branch but keep history

Viewed 779

I want to overwrite all the content in a development branch with another one (namely, master), but I don't want to miss the older commits on the dev branch.

This is what I want:

what I want

I tried both to merge with ours strategy and by doing an hard reset but the dev branch keeps losing the older commits.

What I'm trying to obtain is a commit that has zero diff between blue and red, and the dropped code while diffing blue with the first black one.


Just to share an overview of the solutions tried until now. By doing this:

git checkout master
git merge -s ours dev
git checkout dev
git merge master

I obtain this (dev gets all the history from master)

merge

By doing this

git checkout dev
git reset --hard master

I obtain this (if I push develop i will lose all the black commits):

reset

If i do this:

git checkout dev
git merge $(git commit-tree -p dev -m "Align master > dev" master^{tree})

I obtain this (almost perfect, yet I would be difficult to recall the exact moment when I did the trick):

enter image description here

2 Answers

This can go like this:

git checkout -f develop # go to develop branch
git merge --no-commit master
git checkout master -- . # this checkouts code from master and doesn't switch branch
# you are still in merge process on branch develop
git commit

Note that tailing -- . changes behavior of git checkout.

If I understand your needs correctly, you want to make a new commit on dev and the commit makes the content of dev exactly the same with master. If so,

git checkout dev
git merge $(git commit-tree -p dev -m "foo" master^{tree})

git commit-tree creates a commit from master head's tree, so that the new commit has the same content with master. The command returns the hash of the commit, which can be passed to git merge.

-p dev specifies dev head as the new commit's parent.

-m "foo" uses foo as the new commit's message. You can use literally foo, a random string, because in the end you can use git commit --amend to specify a formal message.

master^{tree} means the hash of the tree object of master head.

In this case git merge has the same effect with git reset --hard.

Related