I have a branch, where I did some changes, but I'd originally mistaken and create it from wrong branch, so I have many different changes I don't want to have in it. So how can I clean it so I only have changes I've done and changes from master branch?
问题:
回答1:
You can create a new branch from master and then cherry-pick the changes you have made into the new branch.
Find the commit hashes for every commit you want to save. Then:
git checkout master
git checkout -b <new branch name>
git cherry-pick <commit hash> # for every commit you want to save
cherry-pick
ing single commits can be tedious, when you have a lot of them. Since git 1.7.2+ cherry-pick
can handle commit ranges.
git cherry-pick <first commit to save>^..<last commit to save>
As EOL pointed out in the comments, cherry-pick applies each patch in turn and waits for the user to commit it, if there are conflicts. In this case, resolve the conflicts and do a git cherry-pick --continue
to automatically move to the next commit. Or use git cherry-pick --abort
to abort the whole operation.
Now inspect your current branch. If everything worked well, you can delete the previous messed-up branch:
git branch -D <old messed up branch name>
See the git cherry-pick manual page for further details.
Edit: included info about git cherry-pick --continue
, which EOL mentioned in the comments.
Update
You mentioned you want to cherry-pick only those commit you created. This can be done with this little bash script:
author_name="Your Git Author Name"
start_commit="earliest commit hash to cherry-pick"
end_commit="latest commit hash to cherry-pick"
git rev-list --reverse --topo-order "$start_commit^..$end_commit" | while read rev
do
commit_author_name=`git log --pretty=format:"%an%n" -n 1 $rev`
if [[ $commit_author_name == *"$author_name"* ]]; then
git cherry-pick $rev || break
fi
done
回答2:
If your changes are all made on top of the upstream branch (i.e. you don't have any merge commits from upstream mixed in with your changes), you can just rebase it on top of master.
git branch backup # always make a backup first ;)
git rebase --onto master <latest commit from wrong upstream branch>
Assuming that your branch is up-to-date with respect to the upstream, that's just
git rebase --onto master <wrong upstream branch>
Afterwards, you might want to change the tracking branch of your current branch to master:
git branch --set-upstream <your branch> origin/master
(or just git branch -u origin/master with git >=1.8)