jackr
jackr

Reputation: 1437

Make git just *copy* (not merge)?

How can I tell git "make this branch HEAD look just like this other branch HEAD"?

We have some history of developing on develop, branching for releases, and doing whatever it takes to make the release branch work. But we've been lax about updating master. Fortunately, we have tags for what was actually released. We want now, post hoc, to make master be the series of released versions.

This is more than just resolving all merge conflicts "theirs"; I want all differences resolved "theirs", if you will. If, for example, during the release/1 process we added x = x + 1; to Foo.java, but never added that to develop or release/2, then when we deliver release/1 to master, this line should be there, but by the time we've delivered release/2 to master, it should disappear. Understand, there's no change anywhere in the history that removes the line; it just was added only to a dead-end branch.

Also, I think git rebase .... isn't what I want: I don't want to lose the deep history. Once I've successfully done this for releases 1 through 37, git log master should show all the changes that actually contributed to each release (and, likely, some merge fix-up commits).

Upvotes: 2

Views: 97

Answers (2)

jthill
jthill

Reputation: 60555

git checkout -B master release/X       # release/X is the new master version

is what you want. Nothing in the current master history is relevant as you're just taking release/X whole.

If you really really have to keep the abandoned history reachable from your active work,

git checkout -B master release/X       # release/X is the new master version
git merge -s ours --no-ff master@{1}

but there's not much reason for that. You could tag it instead, if it's even worth that.

Upvotes: 2

torek
torek

Reputation: 489848

If I understand correctly, you basically want to make one new commit on master that, in effect, removes everything that was under master and replaces it all with everything that was (and still is) under release/X.

There are shorter and faster ways to do this, but I'll show you the slower method first, because I think it's clearer. Note that this assumes you're at the top level of the git directory (git rev-parse --show-cdup will tell you how many ../'s you may need to go up to that level):

$ git checkout master           # onto the branch we want to whack
$ git rm -rf .                  # remove everything
$ git checkout release/X -- .   # repopulate index and work tree
$ git commit                    # and commit the result

If this really is what you want to do, note that you can do this quicker with git commit-tree, which adds a new commit to the repository by taking the given tree-ID and parent-IDs. Since the desired new tree is 100% identical to some existing tree (that of release/X), you need only identify the desired parent commit (presumably whatever master points to initially), create the new commit, and make master point to that, without bothering with the index and work-tree. If you have a lot of these release/N items to do, it will be faster this way, it's just a bit trickier.

Upvotes: 3

Related Questions