Avoid the effects of a revert commit in another Git branch while merging

后端 未结 2 807
被撕碎了的回忆
被撕碎了的回忆 2020-12-30 08:19

Working with git flow. We have a co-worker who is not familiar with Git that accidentally merged develop into master yesterday.

Develop has quite a few features tha

2条回答
  •  时光说笑
    2020-12-30 08:49

    Option 1: Hard reset and force push

    If it's possible to do a non-fast-forward forced-update to your master branch in your upstream repository, then instead of reverting the merge of develop into master, you could simply do a hard reset of master:

    # On master branch, do a hard reset back to the commit before the merge
    git reset --hard 
    
    # Force push to upstream ONLY IF IT'S OK WITH OTHER DEVELOPERS
    git push  master --force
    

    A possible disadvantage to doing a hard-reset and force-push is that if other developers have already based work off of the merge commit (i.e. have made commits on top of it), then they'll need to redo that same work on top of the reset head of master. This may or may not be a difficult/costly task for them.

    Option 2: Revert the revert

    I tested this out with a quick test repo. I have to stress that it might work, I'm not 100% confident that there aren't any cases that I didn't consider. So be sure to test it out locally with a backup clone of your repo first. If you choose to use this in your actual repo, please do so at your own risk.

    Also, this may not be the easiest/simplest solution. Its advantage over the hard-reset option, however, is that it doesn't force developers to have to redo work on top of a reset master branch.

    Ok, with all of that out of the way, one thing you could try doing is merging master into develop, then revert the revert of the merge from develop into master, then merge develop into master when you're ready. In commands:

    # Coworker accidentally merges develop into master before it's ready
    git merge --no-ff develop
    
    # You revert the merge in the master branch (this creates commit "ABCDEFG"
    git revert -m 1 
    
    # You want to merge fixes from master into develop
    git checkout develop
    git merge --no-ff master
    
    # But now all that work in develop is reverted, so revert the revert "ABCDEFG"
    git revert ABCDEFG
    
    # When you're ready to merge develop into master...
    git checkout master
    git merge --no-ff develop
    

    Here's a sequence of commands I used to test this out in a test repo:

    mkdir practice
    cd practice/
    git init
    
    touch readme.txt
    git add practice.txt
    git commit -m "Add practice.txt"
    
    git checkout -b develop
    
    touch feature1.txt
    git add feature1.txt
    git commit -m "Add feature 1"
    
    touch feature2.txt
    git add feature2.txt
    git commit -m "Add feature 2"
    
    git checkout master
    
    touch hotfix1.txt
    git add hotfix1.txt
    git commit -m "Fix issue 1"
    
    git merge --no-ff develop
    
    # Creates commit "ABCDEFG" that reverts the merge
    git revert -m 1 head
    git checkout develop
    git merge --no-ff master
    git revert ABCDEFG
    git checkout master
    git merge --no-ff develop
    

    You can read more about the "Reverting Revert" technique at the official Linux Kernel Git documentation for git revert:

    -m parent-number

    --mainline parent-number

    Usually you cannot revert a merge because you do not know which side of the merge should be considered the mainline. This option specifies the parent number (starting from 1) of the mainline and allows revert to reverse the change relative to the specified parent.

    Reverting a merge commit declares that you will never want the tree changes brought in by the merge. As a result, later merges will only bring in tree changes introduced by commits that are not ancestors of the previously reverted merge. This may or may not be what you want.

    See the revert-a-faulty-merge How-To for more details.

    The link to How to revert a faulty merge is highly recommended if you fully want to understand how this technique works, it's not difficult to understand and it actually kind of interesting and fascinating.

提交回复
热议问题