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 master
says you want to wind up with the result being based on top ofmaster
feature1
is the branch that's included that you don't want to be includedfeature2
is 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
feature2
onto 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
feature2
without switching back tomaster
first.
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.