Git clean branch to save only my changes and chang

2019-07-29 09:42发布

问题:

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-picking 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)