Imagine you want to submit a huge merge request (gitlab terminology), that has many changes from a bunch of commits. You realize that you don’t want to see some changes, but these changes are not in separate commits, so they can’t be easily reverted. There are a lot of small changes. You don’t want to type their reverse, or copy-paste for minutes. You want to keep the commits, not squash them together in the end. What would you do?
I did not want to spend time to find the perfect solution, so I came up with a quick one.
What I really wanted is to see all changes in one commit, that I saw in my merge request, and select the code I wanted to get rid of, then apply these changes to my original branch.
In order to achieve that, I got the latest master
, created a sandbox branch,
squashed my target branch inside it, selected what code I wanted to get rid of,
reverted that commit, and cherry picked it to my target branch.
SANDBOX_BRANCH=sandbox
TARGET_BRANCH=target
# 1. Get a clear sandbox with recent master
git checkout master
git pull
git checkout -b $SANDBOX_BRANCH
## 2. Get all changes as one commit
git merge $TARGET_BRANCH --squash
# ... select only the unnecessary code,
# ... that you want to revert
git add .
git commit -m "Unnecessary code"
git revert HEAD
HASH=`git rev-parse --short HEAD`
## 3. Apply the inverse changes, cleanup
git checkout $TARGET_BRANCH
git cherry-pick $HASH
git commit --amend -v # rename commit
git branch -D $SANDBOX_BRANCH
Enjoy :)
P.S: Let me know if you have a better idea.