Solution for never risking losing anything
TL;DR
What commands to run (assuming you are creating a PR):
# Starting from main branch git checkout -b new-fix-branch git revert <commit-hash-of-revert> git reset --soft <commit-hash-of-commit-one-before-the-revert-of-revert> # Gain peace of mind as you check everything is there. git add -A git commit -m "fix: brought back old changes" # Congrats, syncing your branch will no longer remove the reverted changes.
Explanation
- Revert the revert. This creates a new commit which gives you back all your reverted changes.
- Reset --soft to before reverting the revert. This puts all the changes you've gotten back into your working tree locally as unstaged files.
- Stage and commit changes again. As there is no revert associated with your changes anymore thanks to the reset, git thinks these changes are new and you can sync to your hearts content.
Pros
- Every step can be a PR if you do not have permissions to do stuff on main/develop/prod etc.
- No scary risks of losing code
- Any amount of commits can happen between any step
- Can see all your changes before final step for peace of mind
Cons
- At least 8 commands total (checkout -b, revert, reset --soft, add, commit, push, merge, push).
Long Visual Explanation:
Check-out to main-branch after a revert:
>_ git checkout main-branch main-branch ---o---o---(merge)---(revert)---o---(cool)* / feature-branch ---o---o o = miscellaneous commits (merge) = the commit where you merged in some new changes (revert) = the commit where you reverted the (merge) commit (cool) = the latest commit on main-branch * = head
Create new branch new-fix-branch:
>_ git checkout -b new-fix-branch main-branch ---o---o---(merge)---(revert)---o---(cool) / | feature-branch ---o---o | new-fix-branch *
Revert the revert, giving us the reverted changes back
>_ git revert <hash-of-(revert)> main-branch ---o---o---(merge)---(revert)---o---(cool) / \ feature-branch ---o---o \ new-fix-branch (X-revert)* (X-revert) = changes from original feature-branch, now on your new branch
Soft reset your revert of the revert , putting the changes into your working tree
>_ git reset --soft <(cool)-commit-hash> main-branch ---o---o---(merge)---(revert)---o---(cool) / | feature-branch ---o---o | new-fix-branch X* X = changes from the reverted (merge) commit now in your working tree
Stage & commit entire working tree, git now thinks changes are new
>_ git add -A >_ git commit -m "bringing back old changes" main-branch ---o---o---(merge)---(revert)---o---(cool) / \ feature-branch ---o---o \ new-fix-branch (X)* (X) = changes from the reverted (merge) commit are now back, committed and with no revert associated with them
Sync your branch with main-branch - notice reverted changes DO NOT disappear and will never disappear if you merge back in
>_ git merge origin/main-branch main-branch ---o---(merge)---(revert)---o---(cool)---o---o---o / \ \ feature-branch ---o \ \ new-fix-branch (X)---(get-latest)* (get-latest) = changes from the `main-branch` put into your branch