48

我有一个相当大的 Git 存储库,其中包含 1000 次提交,最初是从 SVN 导入的。在我公开我的 repo 之前,我想清理数百条在我的新 repo 中没有意义的提交消息,以及删除所有添加的 git-svn 信息文本。

我知道我可以使用 'git rebase -i' 然后使用 'git commit --amend' 来编辑每个单独的提交消息,但是要编辑数百条消息,这对你知道的事情来说是一个巨大的痛苦。

有没有更快的方法来编辑所有这些提交消息?理想情况下,我会将每条提交消息都列在一个文件中,我可以在一个文件中将它们全部编辑。

谢谢!

4

7 回答 7

45

这是一个老问题,但由于没有提到git filter-branch,我只加了两分钱。

我最近不得不大量替换提交消息中的文本,用另一个文本块替换一个文本块,而不更改其余的提交消息。例如,我必须将Refs: #xxxxx替换为Refs: #22917

git filter-branch是这样用的

git filter-branch --msg-filter 'sed "s/Refs: #xxxxx/Refs: #22917/g"' master..my_branch
  • 我使用了--msg-filter仅编辑提交消息的选项,但您可以使用其他过滤器来更改文件、编辑完整的提交信息等。
  • 我将其限制filter-branch为仅将其应用于不在 master ( master..my_branch) 中的提交,但您可以通过省略提交范围将其应用于整个分支。

按照文档中的建议,在您的分支副本上尝试此操作。希望有帮助。


用于答案的来源

于 2016-06-21T10:04:45.853 回答
17

这很容易做到,如下所示:

  • 执行第一次导入。
  • 将所有提交导出为文本:

    git format-patch -10000
    

    数量应大于提交总数。这将创建大量名为NNNNN-commit-description.patch.

  • 使用一些脚本编辑这些文件。(不要触摸其中的任何内容,除了带有提交消息的顶部)。
  • 将已编辑的文件复制或移动到空的 git repo 或分支。
  • 将所有已编辑的提交导入回来:

    git am *.patch
    

这仅适用于单个分支,但效果很好。

于 2013-01-15T07:03:03.763 回答
11

现在推荐使用git-filter-repo https://github.com/newren/git-filter-repo 。我像这样使用它:

PS C:\repository> git filter-repo --commit-callback '
>> msg = commit.message.decode(\"utf-8\")
>> newmsg = msg.replace(\"old string\", \"new string\")
>> commit.message = newmsg.encode(\"utf-8\")
>> ' --force
New history written in 328.30 seconds; now repacking/cleaning...
Repacking your repo and cleaning out old unneeded objects
HEAD is now at 087f91945a blah blah
Enumerating objects: 346091, done.
Counting objects: 100% (346091/346091), done.
Delta compression using up to 8 threads
Compressing objects: 100% (82068/82068), done.
Writing objects: 100% (346091/346091), done.
Total 346091 (delta 259364), reused 346030 (delta 259303), pack-reused 0
Completely finished after 443.37 seconds.
PS C:\repository>

您可能不想复制 powershell 额外的东西,所以这里只是命令:

git filter-repo --commit-callback '
msg = commit.message.decode(\"utf-8\")
newmsg = msg.replace(\"old string\", \"new string\")
commit.message = newmsg.encode(\"utf-8\")
' --force

如果您想击中所有分支,请不要使用--refs HEAD. 如果您不想使用--force,可以在 clean 上运行它git clone --no-checkout。这让我开始了:https ://blog.kawzeg.com/2019/12/19/git-filter-repo.html

于 2020-06-18T20:12:22.993 回答
4

您可以使用git rebase -i和替换pickreword(或只是r)。然后 git rebase 在每次提交时停止,让您有机会编辑消息。

唯一的缺点是您不会一次看到所有消息,并且当您发现错误时无法返回。

于 2016-09-15T09:23:39.513 回答
3

一个伟大而简单的方法是使用git filter-branch --msg-filter ""python 脚本。

python 脚本看起来像这样:

import os
import sys
import re

pattern = re.compile("(?i)Issue-\d{1,4}")


commit_id = os.environ["GIT_COMMIT"]
message   = sys.stdin.read()

if len(message) > 0:

    if pattern.search(message):
        message = pattern_conn1.sub("Issue",message)

print message

您将进行的命令行调用是git filter-branch -f --msg-filter "python /path/to/git-script.py"

于 2016-10-04T17:19:41.703 回答
0

As alternative, consider skipping the import of the whole repository. I would simply checkout, clean up and commit important points in the history.

于 2013-01-15T07:47:26.070 回答
0

我混合使用这两种解决方案:

  1. Vscodium 和扩展“ Git rebase 快捷方式”使用git rebase -i简单方法

  2. Git 历史编辑器,它允许:

  • 批量修改姓名+电子邮件
  • 在精美的界面中重新编写 Git 提交消息
  • 使用日期选择器更改提交日期

您粘贴您的提交,然后使用 Web 界面进行更改,它会为您提供一个正确的git filter-branch命令来粘贴到您的终端中。

界面截图:

Git 编辑历史

祝你好运!

于 2021-12-29T22:13:23.520 回答