5

I have the master branch that has a bunch of features in it that will not be released. I was asked to remove those features from master and create a new branch that that has them in it so we can merge back to master later.

The steps I took were:

  1. Create a new branch off of master called "NewFeatures"
  2. Go back to master, delete all offending code (months of commits, hundreds) by hand
  3. Commit deletes to master

The expectation was that I would keep working on "NewFeatures" and periodically merge master into "NewFeatures" so that when I merge back in, it is seamless.

Now, when I want to keep "NewFeatures" up to date with master, master wants to delete all the code in NewFeatures.

My question is, what would have been the proper way to accomplish with Git "deleting a bunch of features from master and placing them into another branch for later merging"?

UPDATE Thanks for the responses. I've made a diagram that hopefully explains things. The biggest problem is that at the first merge from main to feature (the first xy on the second row), the main branch wants to erase everything that was y because I removed all y's.

- y - x - y - (remove y's) - x - x - (release x)-x - x - xy - xy - xy - (release xy) \ \ \ / y - y - y - y - y - xy - y - y - xy - (done)

UPDATE 2 I ended up moving the branch to just after I deleted NewFeature from main (but I had copied out the removed files) and then copied the removed files back in. This way, main can merge into NewFeature without killing things, and NewFeature can merge back into main without problems. I lose some commit log tracking, but it seemed better than cherry-picking files for the next three days.

The below help seemed to be the correct way to do it, but this way seems to be good enough for me (and the discussion led me to the way I finally did it, so thanks guys).

Thanks, Brian

  • If all of the code is properly 'segregated' so that each commit (or linear group of commits) is a feature, just create the new branch and ` git reset --hard ` on master to a commit before the features were created – g19fanatic May 04 '17 at 11:38

2 Answers2

3

I believe what you would have to do is create two branches from your existing master branch. One would include just commits that should have gone in to master and the other would include just commits that contain work for new-feature.

I've made a quick diagram to show what I mean. Currently you have something like this (latest commit at the top):

*   - Master work
|
*   - New feature work
|
*   - Master work
|
*   - New feature work
|
*   - Master work
|
*   - New feature work
|
*   - Common commit

You need to get to here:

*       - Master work
|
|  *    - New feature work
|  |
*  |    - Master work
|  |
|  *    - New feature work
|  |
*  |    - Master work
|  |
|  *    - New feature work
| /
|/
*       - Common commit

It's important that no commits are duplicated across your two branches as this could cause a problem when you merge later.

You can use git rebase to achieve this however if like you say you have hundreds of commits, you're not in for a good time as you'll have to review each commit individually.

Adam Nierzad
  • 942
  • 6
  • 19
  • So I could git rebase single commits (hundreds) to my new branch, and not do the "delete NewFeature from main branch"? Essentially rewriting history to think that all the previous work was done on the new branch. – GreatBigGiantBrain May 04 '17 at 14:08
  • I'm afraid splitting them in to two branches is the only way to go about it. If you record a commit in master that removes the new-feature work, it'll still apply when you merge the `new-feature` branch in. So it'll be like the `new-feature` branch is making changes to a file that was previously deleted. – Adam Nierzad May 04 '17 at 14:17
2

The question you are essentially asking is how to get commits from another branch and bring them into your new feature branch, without wiping out your changes. Assuming these commits aren't touching the same files as the ones you made changes to, the solution has been provided already in another question.

This is the gist of the other person's answer:

# wss-starting-point is the SHA1/branch immediately before the first 
commit to rebase
git branch wss-to-rebase wss
git rebase --onto v2.1 wss-starting-point wss-to-rebase
git checkout v2.1
git merge wss-to-rebase

Use his original answer as a reference. I hope this helps!

Community
  • 1
  • 1
MorrisLaw
  • 71
  • 5
  • I got the impression from the OP's question that they do want to wipe out the commits from master – Robbie May 03 '17 at 22:39
  • Yes, but OP also wants to continually update their NewFeatures branch with any new commits in master, without deleting code from their NewFeatures branch. Then when the time comes, be able to seamlessly merge the branches. I'm assuming that OP's not working on the same files as someone else is, that would explain the merge conflicts. In that case, they can always resolve the merge conflicts. Here's a step by step [tutorial](https://confluence.atlassian.com/bitbucket/resolve-merge-conflicts-704414003.html) explaining an example on doing that. – MorrisLaw May 03 '17 at 22:50
  • In the links, it mentions cherry-pick. That seems more like what I want (since the commits I want are spread across hundreds of other commits). Is rebase only for moving an entire line of commits to another point in time? I guess if I had branched correctly to begin with, I would not have this problem. – GreatBigGiantBrain May 04 '17 at 14:04
  • Yes, you can think of rebase as rewriting the commit history. – MorrisLaw May 04 '17 at 14:26