I was working on branch feature1 and accidentally made a new branch feature2 without switching back to master first. Then I added a commit and pushed it to GitHub.
Now a PR that I submitted based on feature2 includes commit D, which it shouldn't.
I want to move feature2 so it's a direct descendant of master and no longer includes commit D.
To illustrate, I want to turn this:
┌─────────────┐ ┌─────┐ ┌─────┐ ┌─────┐
│ master │────▶│ A │───▶│ B │───▶│ C │
└─────────────┘ └─────┘ └─────┘ └─────┘
╲
╲ ┌───────────┐ ┌─────┐
╲──────▶│ feature1 │───▶│ D │
└───────────┘ └─────┘
╲
╲ ┌───────────┐ ┌─────┐
╲───▶│ feature2 │───▶│ E │
└───────────┘ └─────┘
To this:
┌───────────┐ ┌─────┐
╱─────────────────────────────▶│ feature2 │───▶│ E │
╱ └───────────┘ └─────┘
╱
┌─────────────┐ ┌─────┐ ┌─────┐ ┌─────┐
│ master │────▶│ A │───▶│ B │───▶│ C │
└─────────────┘ └─────┘ └─────┘ └─────┘
╲
╲ ┌───────────┐ ┌─────┐
╲──────▶│ feature1 │────▶│ D │
└───────────┘ └─────┘
I read Move the most recent commit(s) to a new branch with Git. I'm sure the answer is in there somewhere, but among the dozens of replies I couldn't find one that seemed accurate and safe for this case.
CodePudding user response:
This should do the trick:
git rebase --onto master feature1 feature2
--onto mastersays you want to wind up with the result being based on top ofmasterfeature1is the branch that's included that you don't want to be includedfeature2is the branch you're wanting to update / separate
CodePudding user response:
Conceptually, you want to do something like this:
- Create a new branch based on the latest
master. - Cherry-pick all of the commits that are only on
feature2onto your new branch. - Rename your new branch to
feature2.
You could actually do exactly that and get what you want. There is also a one-line rebase command for doing the same thing which is described in Amber's answer.
The only tweak I would consider is to fetch first, and then use origin/master instead of master. This is so you don't have to worry about whether your local copy of master is up to date. Every time you git fetch, you update all of your remote tracking branches, such as origin/master. Then you can use origin/master any place you previous would have used master, without having to ever update master again. In fact, I'd recommend you delete your local copy of master and just use origin/master instead from now on! You started this off because you:
accidentally made a new branch
feature2without switching back tomasterfirst.
Note even if you do switch to master first, you still need to remember to pull it to update it. If you don't have a copy of master at all, from now on you can always use this method to create a new branch off of the latest master:
git fetch
git switch -c new-branch origin/master --no-track
Now your new branch will always be created with the latest master from the remote, which is almost always preferred in a Pull Request workflow.
