I've a tree like this:
(commit 1) - master
\-- (commit 2) - (commit 3) - demo
\-- (commit 4) - (commit 5) - PRO
and I have to move the PRO branch to master
(commit 1) - master
|-- (commit 2) - (commit 3) - demo
\-- (commit 4) - (commit 5) - PRO
I've tried a git rebase master from PRO branch, but nothing happens.
To clarify: I was working in master and then I had to make a product demo (git checkout -b demo and some commits). Then, by mistake, I create another branch from demo (git checkout -b PRO and some commits) and now I need to move PRO branch to master and leave demo intact. At the end, both demo and PRO will hang from master.
6 Answers
Assuming newBase is the branch you want to move your commits onto, oldBase is the old basis for your branch, you can use --onto for that:
git rebase --onto newBase oldBase feature/branch
Given your case:
git checkout PRO # Just to be clear which branch to be on.
git rebase --onto master demo PRO
Basically, you take all the commits from after demo up to and including PRO, and rebase them onto the master commit.
I will try to be as generic as I can be. First, be sure that you are on the desired branch:
git checkout current-branch
Then use the following command (where new-base-branch is the branch which you want to be your new base, and current-base-branch is the branch which is your current base.)
git rebase --onto new-base-branch current-base-branch
If you do not have conflicts, then great - you are done. If you do (in most cases), then please read on.
Conflicts might arise, and you will have to resolve them manually. Git now tries to do a "3-way merge" between your current-branch, current-base-branch and new-base-branch. Roughly this is how git will work internally:
Git will first rebase the
current-base-branchon top of thenew-base-branch. There might be conflicts; which you will have to resolve manually. After that is done, you usually dogit add .andgit rebase --continue. It will create a new temporary committemp-commit-hashfor this.After this, Git will now rebase your
current-branchon top oftemp-commit-hash. There might be further conflicts and again you will have to resolve them manually. Once done, you continue again withgit add .andgit rebase --continue, after which you have successfully rebased yourcurrent-branchon top thenew-base-branch.
Note: If you start to mess up, then you can do git rebase --abort anytime during the rebase process and get back to the starting point.
Checkout to PRO branch, Copy the oldest (commit4) and latest (commit5) commit hashes of this branch and paste somewhere else:
$ git checkout PRO
$ git log # see the commit history
# copy the oldest & latest commit-hash
Delete the PRO branch (keep a backup just for safety). Create and checkout to a new PRO branch from master:
$ git branch PRO.bac # create a new branch PRO.bac = PRO as backup
$ git checkout master
$ git branch -D PRO # delete the local PRO branch
$ git checkout -b PRO # create and checkout to a new 'PRO' branch from 'master'
Take (cherry-pick) the range of commits of Previous PRO branch into the new PRO branch:
$ git cherry-pick commit4^..commit5 # cherry-pick range of commits
# note the '^' after commit4
Now, if all is ok, then do force (-f) push to remote PRO branch and delete local PRO.bac branch:
$ git log # check the commit history
$ git push -f origin HEAD # replace the remote PRO by local PRO branch history
# git branch -D PRO.bac # delete local PRO.bac branch
I had a slightly different approach using reset and stashes that avoids deleting and re-creating branches as well as eliminating the need to switch branches:
$ git checkout PRO
$ git reset commit4 # This will set PROs HEAD to be at commit 4, and leave the modified commit 5 files in ur working index
$ git stash save -m "Commit message"
$ git reset commit3
$ git stash save -m "Commit message"
$ git reset master --hard
$ git stash pop
$ git stash pop
$ git push --force # force if its already been push remotely
By resetting the branch on a commit-by-commit basis your basically just rewinding that branches history a commit at a time.
I know this question is quite old but sharing in case it helps someone.
I was in same condition where I raised PR from different base branch and where changing base branch and rebase was showing 200+ file conflicts.
Even resolving it was showing older commits which I didn't wanted. So what I did was
- Delete branch from local
- Create new branch with same name, make sure you select correct base branch this time
- Cherry-pick commit id if you have any
Finally ran below command
git push origin +branchName:branchName
here above you can use -f as well instead of +.
Above command put my branch in a state without impacting my pull request.
git branch --set-upstream-to another_branch