在新克隆上使用 git-filter-repo 从 git 历史记录中删除文件

Syn*_*hro 14 git repository git-rewrite-history

我正在按照此答案从 git 历史记录中删除包含凭据的单个文件。我有 git 2.35.1 和filter-repo 22826b5a68b6。我需要的命令显然是:

\n
git-filter-repo --path auth.json --invert-paths\n
Run Code Online (Sandbox Code Playgroud)\n

如果我尝试将此应用到我的工作存储库,我会收到此错误:

\n
Aborting: Refusing to destructively overwrite repo history since\nthis does not look like a fresh clone.\n(expected freshly packed repo)\n
Run Code Online (Sandbox Code Playgroud)\n

因此,我使用 检查了一个新副本git clone,并且该命令成功运行:

\n
Parsed 861 commits\nNew history written in 0.69 seconds; now repacking/cleaning...\nRepacking your repo and cleaning out old unneeded objects\nHEAD is now at 7212384 Update app.css\nEnumerating objects: 8203, done.\nCounting objects: 100% (8203/8203), done.\nDelta compression using up to 24 threads\nCompressing objects: 100% (2310/2310), done.\nWriting objects: 100% (8203/8203), done.\nTotal 8203 (delta 5630), reused 8196 (delta 5623), pack-reused 0\nCompletely finished after 2.85 seconds.\n
Run Code Online (Sandbox Code Playgroud)\n

我可以看到该文件已被删除。但是当我去推动时:

\n
git push --force\nfatal: No configured push destination.\n
Run Code Online (Sandbox Code Playgroud)\n

由于某种原因,它丢失了克隆的遥控器,所以我手动将其添加回来:

\n
git remote add origin git@git.example.com:abc/xyz.git\n
Run Code Online (Sandbox Code Playgroud)\n

这失败了:

\n
fatal: The current branch master has no upstream branch.\n
Run Code Online (Sandbox Code Playgroud)\n

所以我添加了

\n
git push --set-upstream origin master\n
Run Code Online (Sandbox Code Playgroud)\n

但这也失败了:

\n
To git.example.com:abc/xyz.git\n ! [rejected]        master -> master (fetch first)\nerror: failed to push some refs to \'git.example.com:abc/xyz.git\'\nhint: Updates were rejected because the remote contains work that you do\nhint: not have locally. This is usually caused by another repository pushing\nhint: to the same ref. You may want to first integrate the remote changes\nhint: (e.g., \'git pull ...\') before pushing again.\nhint: See the \'Note about fast-forwards\' in \'git push --help\' for details.\n
Run Code Online (Sandbox Code Playgroud)\n

但我知道自从检查以来没有任何内容被推送到这个仓库。重复该过程会得到相同的结果。如果我执行git pull更新操作,它会再次失败并出现this does not look like a fresh clone错误,就回到我开始的地方。

\n

我绕了好几次,最终克服了所有错误,却发现这对我的存储库 \xe2\x80\x93 没有任何影响,文件仍然存在。

\n

所以我的问题是,要使此过滤过程在新克隆的存储库上运行,我应该执行哪些具体步骤?

\n

TTT*_*TTT 13

你曾如此接近...

您需要在上一步中这样做的原因git push --force是因为您将清除远程上的提交并用新的提交替换它们。由于您的遥控器不见了,请跳过第一个强制推送命令,然后您只需向最终的推送命令添加强制即可:

git push --set-upstream origin master --force
Run Code Online (Sandbox Code Playgroud)

旁注:我几乎总是更喜欢使用--force-with-leaseover --force,因为它更安全一些,因为如果有人在您上次获取(或在本例中克隆)和推送之间向远程分支添加了新的提交,那么它会出错,而您还没有这样做还没见过。直接把他们吹走可能是不礼貌的。使用时--force-with-lease,如果出现错误,只需执行git fetch,查看新提交并决定是否可以删除它们。如果是,那么--force-with-lease再次使用它就会起作用(除非在您获取后的最后一分钟再次出现新的提交)。

在这种特殊情况下,您要重新添加遥控器,您必须先获取,否则将--force-with-lease无法工作,如果是我,如果在这段时间之间遥控器上可能出现新的提交,我可能会考虑这样做你克隆了,当你准备强制推送你重写的仓库时。在这种情况下,我会将您的最终命令更改为以下步骤:

git fetch
# inspect origin/master to see if new commits appeared after your clone
git push --set-upstream origin master --force-with-lease
Run Code Online (Sandbox Code Playgroud)

或者,也许在您的情况下,一旦您决定要重写分支,请暂时锁定该分支(或删除对其的权限),并在强制推送后将其解锁。然后您就可以确定在您完成之前没有人会添加提交。

  • 由于“origin/master”不存在,因此在filter-repo之后强制租赁将不起作用。(过滤后的存储库是一个全新的存储库,使用“git init”创建并使用“git fast-import”填充。) (2认同)