Git:从历史记录中删除提交而不更改任何其他内容日期、提交者

问题描述

我希望这会像交互式 rebase 一样简单,但我注意到 rebase 会更改提交日期和提交者。

从历史记录中删除提交同时保持其他所有内容不变的最简单方法是什么?

解决方法

git rebase 有一个 -x/--exec option 可以提供帮助。

您可以添加 environment variables,对于 rebase todo 列表中的每个提交,有助于保持日期/作者不变:

我在“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

(将 x 中的 @~x 替换为您希望交互式变基开始的提交次数)

问题是:您需要在第一个 pick 待办事项项之前手动复制这些生成的行,以便第一次提交使用这些设置。

,

我使用 git rebasegit filter-branch 尝试了多种方法,但都没有奏效。 git filter-branch 可能无法工作,因为它对快照进行操作,而删除提交则需要对变更集/补丁进行操作。

唯一有效的解决方案是基于 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