简体   繁体   中英

Accidental merging of "release" branch into "master"

Recently I made a mistake of committing something that is intended for the master branch into the release branch and to make things worse i merged the release branch into the master branch.

I have commits on the release branch that are not merged into the master branch because they are only intended for release.

Below are two graphs displaying the mistake and what I actually want to achieve, which is doing the commits that are intended for master on master and avoiding the merge of release into master. Note that I did not make just one commit after v0.2 but multiple, this is just for illustration.

Mistake错误

How it should be应该如何

Here is your diagram, with 'M' and 'A' commits highlighted :

                previous correct state for Master
                v
Master:   *-----M------*
           \     \    /
Release:    *--*--*--A
                  ^  ^
               v0.2  accidental commit

You can "fix" the history locally, and publish it using push --force .

If this is a shared repository, first check with your colleagues if they have some work based on the "wrong" commits, and inform them that they will have to reapply/rebase their work after your operations.

  • in order to set your Master to the state you expect :

    run the following actions :

     # from your master branch : git checkout Master # reset it to its previous M state : git reset --hard M # cherry-pick commit A : git cherry-pick A # publish the 'fixed' Master branch using push --force : git push --force origin Master

    replace M and A in the commands above by their respective sha.

  • in order to revert the accidental commit on Release :

     # replace 'v0.2' with the actual name of the tag, or the sha of `v0.2` the commit, # replace 'Release' with the actual name of the release branch git push origin --force v0.2:Release

Git has two different commands for backing out a commit that work in different ways.

Reset
git reset <commit> will reset the current branch back to the commit specified. There are also a number of aliases for undoing the last commit etc. By default it will keep the changes from the commit in your working copy but as unstaged changes. If you want to fully get rid then use the --hard option.

Given that you have already pushed to the server it won't be safe to do a reset. This effectively re-writes the history which can mess up other peoples workspaces if they have already pulled your commit. Generally I would only use this for local commits that have not been pushed yet.

Revert
git revert <commit> does the same thing by resetting the current branch to a previous commit but instead of deleting the unwanted commits, it adds a new commit that backs out the changes. This means your history is potentially a bit messier but it is much safer as you are not re-writing history.

Cherry pick
There is another command that you may find useful. If you make a commit to a wrong branch, or even if you just want to copy a commit over without doing a full merge, then you can use git cherry-pick <commit> .

You may also want to look into protecting the master branch. We use gitlab and have this branch protected, requiring a merge request from another branch to save on accidental pushes like this. I'm sure other tools can do something similar.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM