在Git提交日志中查找/替换

时间:2012-03-16 22:28:12

标签: git history privacy git-filter-branch

如何重写我们的提交历史记录以确保某些关键字永远不会出现?

背景:我们有三层存储库:

  1. 本地 - 我们的开发环境。
  2. 内部 - 我们团队的私人GH资料库
  3. 客户 - 生产/最终客户。我们所有的真实姓名,电子邮件等都不能在这里制作。
  4. 我已经发现git-filter-branch可以帮助重写历史记录以删除名称,使用类似的东西......

    git filter-branch -f --env-filter "GIT_AUTHOR_NAME='safeusername'; GIT_AUTHOR_EMAIL='safe@email.com'; GIT_COMMITTER_NAME='safeusername'; GIT_COMMITTER_EMAIL='safe@email.com';" HEAD
    

    这似乎很有效。当我推到最后一个遥控器时,我们的名字都没有出现。但是,在一些合并之后,我不希望任何分支名称或其他评论可能意外发生。

    此外,我希望继续配置我们的实际电子邮件和用户名,以便我们的内部项目管理系统可以正常运行。

    如何确保关键字或名称列表永远不会出现在提交消息中?还有,解决这个问题的任何其他方法?

    谢谢!

1 个答案:

答案 0 :(得分:0)

好的,所以你想做这样的事情的一般流程是:

  • 克隆/拉入未经修改的仓库(每次可能是新的仓库,可能重复使用)
  • 运行filter-branch,做魔术
  • 验证一切都安全
  • 发布到客户回购

首先:魔术。您需要使用git filter-branch --commit-filter my-commit-filter-script。它直接调用而不是commit-tree,获取必要的参数,以及stdin上的提交消息。所以你会想做这样的事情:

#!/bin/bash

GIT_AUTHOR_NAME=$(sanitize "$GIT_AUTHOR_NAME")
# ... similar for AUTHOR_EMAIL, COMMITTER_(NAME|EMAIL)

sed 's/scary-string/safe-string/' |
git commit-tree "$@"

也就是说,通过适当的环境变量更改名称和电子邮件,在消息上运行您需要的任何过滤,并将其传递给已经正常运行的commit-tree调用。 sanitize是一个功能/脚本,可以对名称/电子邮件进行一些私人>公开映射;如果您只想将它​​们全部更改为单个名称,那么这一点非常简单。并且sed命令可能是一个有点发展的东西,例如读取转换表。这取决于你需要做的消毒的复杂程度。

如果您信任提交邮件过滤,那么您已完成此操作。如果要验证,可以手动执行,也可以单独搜索“危险”字符串。例如,如果您有文件dangerous-strings.txt,则可以执行git log --pretty="%an %ae %cn %ce%n%B" [branches] | grep -f dangerous-strings.txt。 (log命令打印author / committer name / email,后跟提交消息。)

然后正常发布 - 推测,推测。

最后,一些替代建议,也许是针对具有不同要求的未来读者:

  • 不是重写提交,而是进行新的提交。消息可能只是快速版本控制信息(包括它所代表的内部提交的SHA1),或者它可能包括引入的提交的短消息(只是主题)。您可以通过保留发布分支并使用git merge --squash [--log],或者在复制内容后在单独的仓库中提交新内容来完成此操作。

  • 将您的回购保存在不需要转换的表单中。对于OP来说这似乎是不可能的,但如果您的情况不同,请保持简单。风险较小,工作量较少。