编辑所有 Git 提交消息以删除行

编辑所有 Git 提交消息以删除行

我有一个 Git 存储库,它是从 Subversion 转换而来的git svn。我不再有原始的 Subversion 存储库,并且所有提交消息都有如下一行:

git-svn-id: file:///home/jordan/Development/wxSVG/wxsvg-svn/trunk@618 918b0bbe-f86e-4b6f-834e-cb0f658702cb

我想编辑所有提交消息以删除此行。我知道我的 Git 历史记录将被重写,我对此没意见。手动编辑每个提交将花费很长时间,我想知道是否有办法自动完成此操作。

我使用的是 Windows 系统,但使用的是类 Unix shell,因此 Unix/Linux 命令没问题。我猜我需要以sed某种方式使用该命令来修改提交消息,但我不知道该怎么做。

当我运行git rebase -i <commit-id>命令时,我的编辑器打开了,我必须将所有pick值更改为reword。然后,我需要删除以git-svn-id每次提交时编辑器打开时开头的行。

这可能吗?

编辑:我刚刚发现这个答案,所以我的问题可能被视为重复。我现在正在尝试建议,并且已经找到了将“pick”自动更改为“reword”的答案。

答案1

答案找到了这里帮助我找到了解决方案:

我的问题的第一部分是如何自动将pick关键字更改为,reword以便编辑所有提交。答案是将序列编辑器设置git config为命令sed -i s/pick/reword/。可以使用开关对单个命令执行此操作-c

git -c sequence.editor='sed -i s/pick/reword/' rebase -i <commit-id>

对于第二部分,即实际更改所有提交消息,事实证明我不需要担心第一部分。我只需要使用开关-x对要编辑的每个提交消息执行 git 命令。为此,不需要设置序列编辑器,而是需要使用以下命令设置核心编辑器-c core.editor='<sed-command>'

git rebase <commit-id> -x "git -c core.editor='sed -i s/git-svn-id.*//g' commit --amend"

保存提交者姓名、电子邮件和日期的其他信息

**编辑:**可以使用以下命令从每次提交的作者信息中复制提交者的姓名、电子邮件和日期:
git rebase <commit-id> -x "GIT_COMMITTER_DATE=\"$(git log -1 --pretty=format:%ad)\" git -c user.name='$(git log -1 --pretty=format:%an)' -c user.email='$(git log -1 --pretty=format:%ae)' -c core.editor='sed -i s/git-svn-id.*//g' commit --amend"
**编辑:** 之前的编辑有错误。提交者日期设置不正确。为了对每个单独的提交使用正确的日期,请`cat .git/rebase-merge/orig-head`在 `GIT_COMMITTER_DATE` 命令的末尾添加:
git rebase <commit-id> -x "GIT_COMMITTER_DATE=\"$(git log -1 --pretty=format:%ad `cat .git/rebase-merge/orig-head`)\" git -c user.name='$(git log -1 --pretty=format:%an)' -c user.email='$(git log -1 --pretty=format:%ae)' -c core.editor='sed -i s/git-svn-id.*//g' commit --amend"
这将使用来自原始提交的哈希来检索日期,而不是仅使用来自最近提交的日期。


编辑:我在使用带有 rebase 的环境变量保存每次提交的提交者日期时遇到了麻烦GIT_COMMITTER_DATE。所以经过一番尝试,我能够用 做我想做的事情git cherry-pick。这可能不是实现这一点的最佳方法,但对我来说很有效。

首先,我按相反的顺序列出了所有提交哈希(请注意,<start-commit>不包括:

git log --reverse --format="%H" <start-commit>...<end-commit> > ../hashes.txt

然后我使用以下循环命令单独添加每个提交,同时保留提交者的姓名、电子邮件和日期(如果您不需要修改提交消息,请省略-c core.editor='<editor-command>'并添加--no-edit提交命令的选项):

for COMMIT in $(cat ../hashes.txt); do \
  git cherry-pick $COMMIT && \
  GIT_COMMITTER_DATE="$(git log -1 --format=%cd $COMMIT)" git -c user.name="$(git log -1 --format=%cn $COMMIT)" -c user.email="$(git log -1 --format=%ce $COMMIT)" -c core.editor='sed -i s/git-svn-id.*//g' commit --amend; \
  if [ "$?" -ne "0" ]; then break; fi; done

如果 cherry pick 失败,代码if [ "$?" -ne "0" ]; then break; fi;会强制退出循环。如果发生这种情况,您需要先从文件中删除所有哈希,hashes.txt然后才能继续。如果它在 cherry pick 进行中停止,您需要解决所有冲突,然后使用git cherry-pick continue。然后,您需要手动修改提交以设置提交者姓名、电子邮件和日期,然后才能继续。

相关内容