Whilst I was developing I merged a pr from branch a_feature
into develop
branch. Then I deleted the a_feature
branch both in my computer and in github.
But I mismerged it and I wanted to change it back. Therefore I did a new Pr that reverts the changes via github's build in feature and merged it back. (I did it in order to preventing unwanted code to accidentally be deployed)
But I want to continue the development of the reverted changes into a new branch and do a new pr. So is this approach I do the correct one?
- I pull the
develop
branch:
git checkout develop
git pull origin develop
- I do a new branch:
git checkout a_feature_with_nessesary_changes
- The I look upon the logs for the commit that contains the changes prior to revert:
git revert ^hash^
- Then I commit the changes:
git add .
git commit -am "Un-reverted changes"
- Once it is ready I re-do a new PR.
But is this the way to un-revert the reverted changes and lot lose code, once I revert some merge changes through github?
CodePudding user response:
There are multiple ways to go here, but the most important thing to realize about Git revert
is that reverting a PR is a little different than reverting a commit. When you revert a regular commit you undo the changes of that specific commit. When you revert a PR you are reverting a merge commit, and that commit will undo the sum of all the changes in all of the commits that were brought in by that PR.
This matters because if you choose to continue working on the same branch, when it comes time to merge in the fixed-up version of the branch, if any of the commits you wish to re-merge in still have the same ID as they did in the previous merge, those commits will not be brought in a second time. They need to be re-written, so my preference is to always start from the latest version of the target (like you suggested), which will force it. Here's a slightly more efficient way to create that branch without checking out develop
first:
# make a new branch off of the latest develop
git fetch
git switch -c a_feature_with_nessesary_changes origin/develop --no-track
Now you can either revert the revert commit:
git revert <commit-id-of-revert-commit>`
Or, you can cherry-pick all of the original commits on the branch:
git cherry-pick <commit-id-a_feature-branched-from>..a_feature
Note that the first commit in the cherry-pick range is the parent of the first commit to be picked. It's likely that parent commit you need there is equal to the output of this command:
git merge-base origin/develop a_feature
In the case that merge-base is correct, you could change your cherry-pick to something like this (using Bash):
git cherry-pick $(git merge-base origin/develop a_feature)..a_feature
For completeness, I'll mention if you really wanted to reuse the original commits on a_feature
without starting from the latest develop
(some people don't like changing the original merge base), then you could simply force a rewrite of the branch in place to only change the IDs:
git switch a_feature
git rebase -f $(git merge-base origin/develop a_feature) # -f forces the rewrite
Regardless of which of the above options you selected, now your branch is in a state with the old (still broken) code that is ready to be fixed. At this point you can add your new commits with the changes you wish to make and PR into develop
like you normally would.