【问题标题】:Git - Rewrite all affected commits user email - not working for activityGit - 重写所有受影响的提交用户电子邮件 - 不适用于活动
【发布时间】:2022-01-14 01:48:30
【问题描述】:

两年多来,我对 Gitlab 上的许多存储库进行了大量提交。但是我意识到我没有设置正确的电子邮件。

我使用git filter-branch 过滤历史并更改用户电子邮件。

$ git filter-branch --env-filter '
OLD_EMAIL="old@example.com"
NEW_NAME="New Example"
NEW_EMAIL="new@example.com"
if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
  export GIT_COMMITTER_NAME="$NEW_NAME"
  export GIT_COMMITTER_EMAIL="$NEW_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
  export GIT_AUTHOR_NAME="$NEW_NAME"
  export GIT_AUTHOR_EMAIL="$NEW_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags

然后我用git push --force 强制推送这些更改。 它会更新 master 分支上的贡献者。

git push --force --tags origin 'refs/heads/master' 之后,它也会更改标签上的贡献者。

问题:
它不会更改活动页面上的提交。转到 {Repository} > 项目信息 > 活动(显示更新的贡献者),但单击任何提交编号 --> 它会加载未更新贡献者的提交。

问题:
如何重写正确的历史记录,包括在活动日志中发布的提交。

【问题讨论】:

  • 我想几年前我也遇到过类似的问题,最后只是删除了 gitlab 项目并将 repo 重新推送到一个新项目......不会所有活动都回来,但会清除不需要的信息来自旧活动

标签: git gitlab commit git-filter-branch


【解决方案1】:

活动流是不可变的

不幸的是,活动提要直接来自数据库事件记录,并且在创建记录后与 git 完全分离。据我所知,除非您具有数据库级别的访问权限,否则无法删除活动提要中的条目。

但是,可以使用git-filter-repo 完全删除这些提交并运行存储库清理,以便它们无法查看 在 GitLab 中。这些链接仍会存在于活动提要中,但在尝试查看重写/删除的提交 SHA 时,您会看到一个 404 页面。

另一种可能的解决方法是完全删除活动提要 -- 这样做 这个,只需导出你的项目,然后导入它。如果您在推送 git-filter-repo 更改之前 这样做,那么所有提交的所有活动都将显示为您推送这些更改的时间戳:

如果您在 之后执行此操作,Feed 中将根本没有任何活动:

来自 GitLab 的深度清理参考

除了分支上的提交之外,GitLab 还保留了(额外的)内部引用,当您克隆它时,这些引用通常不会出现在您的本地 git 存储库中。包括合并请求、管道、注释和其他地方的引用。即使您更新了refs/heads/*,您也可能需要更新遥控器上的其他参考,以便看到更改在不同的地方生效。

这会破坏某些 UI 页面并可能导致数据丢失,但这是让 GitLab 除了删除和重新创建项目之外完全删除旧引用的唯一方法。

在开始通过导出备份您的存储库之前

要彻底改变事物,您还需要更改这些引用:

refs/merge-requests/* for merge requests.
refs/pipelines/* for pipelines.
refs/environments/* for environments.
refs/keep-around/* are created as hidden refs to prevent commits referenced in the database from being removed

不幸的是,GitLab 不允许您直接访问其中的一些“隐藏引用”。要完全删除这些引用,您必须将项目导出到 tarball 并从 tarball 中恢复本地 git repo,然后再次应用过滤器,然后推送到远程。

导出您的项目,然后在 tarball 中有一个 project.bundle 文件。

git clone --bare --mirror ./project.bundle myrepo
cd myrepo

然后use git-filter-repo 彻底改变所有地方的电子邮件。

# replace with your actual filter-repo command needed
git filter-repo --name-callback '...' --email-callback '...' --commit-callback '...'

然后强制推回所有的 refs,包括隐藏的 refs:

# reset the origin
git remote remove origin
git remote add origin https://gitlab.example.com/<namespace>/<project_name>.git

# push all refs
git push origin --force 'refs/heads/*'

# tags
git push origin --force 'refs/tags/*'

# prevent dead links to commits that no longer exist
git push origin --force 'refs/replace/*'

之后,您需要使用git filter-repo 生成的commit-map 初始化存储库清理。它位于./filter-repo/commit-map 的仓库中。它看起来像这样:

$ cat filter-repo/commit-map
old                                      new
87c5016db64c6e8f4fc0feba4810b17c2c2222b5 2bb77407040e8a658eceacdf3034d24cedcc1ecd
cea6d9aa25e52dd755b694876a482a158debc60a 9a9b1d1a845d1096f4d3734191f883b52ffac6e9
5f1ac8c5fa47ac393d5e3f24b4b9812aaefbf5d7 b659497ed15ab0a3191dc5c6451c9440ca10d6e4

使用提交映射,转到设置 -> 存储库 -> 清理并上传 commit-map 文件。您会看到一条消息:

存储库清理已开始。清理操作完成后,您将收到一封电子邮件。

一段时间后(取决于 repo 大小),旧的提交应该完全消失了。

如前所述,在活动提要中,旧提交的链接仍将那里:

但是,如果您单击链接,提交本身现在会产生 404,并且无法在 GitLab 中查看(永远消失了!):

【讨论】:

  • 我已经导出、删除和导入了我的存储库。这为我解决了这个问题,因为这些活动对我来说并不重要。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2012-07-19
  • 2020-11-10
  • 2011-11-14
  • 2014-03-17
  • 1970-01-01
  • 1970-01-01
  • 2019-07-15
  • 2011-11-26
相关资源
最近更新 更多