我有一个 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
。然后,您需要手动修改提交以设置提交者姓名、电子邮件和日期,然后才能继续。