'Remove commit from history without changing anything else (dates, committers)
I expected this to be as easy as interactive rebase, but I've noticed that rebase changes commit dates and committers.
What would be the easiest way to remove a commit from history while leaving everything else the same?
Solution 1:[1]
git rebase
has a -x
/--exec
option which can help.
You can add environment variables which will, for each commit in the rebase todo
list, help to keep date/author unchanged:
I mention that in "git rebase without changing commit timestamps"
git rebase -i --committer-date-is-author-date \
-x 'git config user.name "$(git show -s --format=%an $(git rev-parse HEAD))"' \
-x 'git config user.email "$(git show -s --format=%ae $(git rev-parse HEAD))"' \
@~x
(replace x
in @~x
by the number of commits you want your interactive rebase to start)
The problem is: you will need to manually copy those generated lines before the first pick
todo item, in order for the first commit to use those settings.
Solution 2:[2]
I've tried multiple approaches using git rebase
and git filter-branch
, but neither worked. git filter-branch
likely cannot work, since it operates on snapshots, while removing commits require operating on change-sets/patches.
The only solution that worked was to create my own rebase based on git cherry-pick
:
# !!! Only do this when the working copy is clean !!!
git checkout --orphan new_branch
# Now clean up all the files
# !!! Careful !!!
# git reset --keep
git log --reverse --format=%H source_branch |
grep -v -E "sha1|sha2|sha3" |
while read sha; do
(
echo "Cherry-picking $(git show --no-patch --format=oneline "$sha")"
export GIT_COMMITTER_NAME=$(git show -s --format=%cn "$sha")
export GIT_COMMITTER_EMAIL=$(git show -s --format=%ce "$sha")
export GIT_COMMITTER_DATE=$(git show -s --format=%cd "$sha")
git cherry-pick "$sha" -Xtheirs
)
done
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Ark-kun |