Suppose I have a feature branch that modifies half a dozen files. Most of the commits on that branch involve file.py
. I eventually realize that there's a potentially better way to implement this feature without touching file.py
at all. Is there a way to tweak all the commits on my branch to not touch that file? I feel that there should be some kind of trick with interactive rebase that does this easily, but I'm not sure what trick that would be.
Of course, I could simply revert the changes as a new commit, but seems a pity to clutter up history for posterity.
This can be automated by using automatic conflict resolution during the rebase. The algorithm could work like this:
--onto
) the new temp branch, and use merge strategy "ours" (-Xours
).--onto
as demonstrated below.Here's a bash script that demonstrates the algorithm in action:
#!/bin/bash -v
git init
git branch -m main # name branch main in case that isn't your default
echo asdf > asdf; echo stuff > file.py; git add .; git commit -m "Create commit 1"
echo line2 >> asdf; echo line2 >> file.py; git add .; git commit -m "Create commit 2"
echo line3 >> asdf; echo line3 >> file.py; git add .; git commit -m "Create commit 3"
echo line4 >> asdf; echo line4 >> file.py; git add .; git commit -m "Create commit 4"
git branch main-rebase # make a copy of main for the rebase
# make a branch off of commit 1 (3 commits ago)
git switch -c temp-branch @~3
# make a temp commit that modifies file.py
echo testing > file.py; git add .; git commit -m "wip: change file.py"
# rebase using "ours" strategy to remove all changes to file.py after commit 1
git rebase main-rebase~3 main-rebase --onto temp-branch -Xours
# remove the temporary wip commit from the branch
git rebase main-rebase~3 main-rebase --onto main-rebase~4
# remove the temp branch
git branch -D temp-branch
# show the full log
echo "Oneline graph log of all branches:"
git log --all --graph --oneline
echo "Show history of file.py on main"
git log main --oneline -- file.py
echo "Show history of file.py on main-rebase"
git log main-rebase --oneline -- file.py