提问人:klor 提问时间:1/14/2023 最后编辑:Christopher Mooreklor 更新时间:1/20/2023 访问量:331
如何从 GIT 存储库历史记录中删除所有文件,路径在文件名中带有冒号:?
How to remove all files from GIT repo history with path having colon : in filename?
问:
我有 ISCSI 节点文件名和冒号存储在 Debian 10 Linux 上的 GIT 存储库中。
例:
'iscsi/nodes/iqn.2000-01.com.synology:NAS01-DS916.nas/ff11::111:11ff:ff1f:1ff1,3260,1/default'
'iscsi/send_targets/1.2.3.4,3260/iqn.2000-01.com.synology:NAS01-DS916.nas,ff11::111:11ff:ff1f:1ff1,3260,1,default'
但是在 Windows 上签出失败,因为冒号是 Windows 文件名中的无效字符。
我在 Windows 结帐时收到以下 GIT 错误:
error: invalid path 'iscsi/nodes/iqn.2000-01.com.synology:NAS01-DS916.nas/ff11::111:11ff:ff1f:1ff1,3260,1/default'
...
error: invalid path 'iscsi/send_targets/1.2.3.4,3260/iqn.2000-01.com.synology:NAS01-DS916.nas,ff11::111:11ff:ff1f:1ff1,3260,1,default'
问题:
1)如何列出所有带有冒号的路径:在完整的GIT存储库历史记录中?
2)如何从GIT存储库历史记录中删除所有文件,其路径至少有一个冒号:在文件名中?
解决方案 1) :
作品1:
git log --all --name-only -m --pretty= -- '*:*' | sort -u
Works2(仅适用于命名的存储库主节点):
git ls-tree -r master --name-only | grep ":"
Works3:最后我用它来列出文件名中带有冒号的文件:
git log --format="reference" --name-status --diff-filter=A "*:*" >/opt/git_repo_files_w_colons.txt
UPDATE1 for 2):
我得到了
Aborting: Refusing to destructively overwrite repo history since
this does not look like a fresh clone.
(expected freshly packed repo)
Note: when cloning local repositories, you need to pass
--no-local to git clone to avoid this issue.
Please operate on a fresh clone instead. If you want to proceed
anyway, use --force.
执行时
git filter-repo --invert-paths --path-match "*:*"
UPDATE2 for 2) :
克隆存储库的副本:
git clone --no-local /source/repo/path/ /target/path/to/repo/clone/
# Cloning into '/target/path/to/repo/clone'...
# remote: Enumerating objects: 9534, done.
# remote: Counting objects: 100% (9534/9534), done.
# remote: Compressing objects: 100% (4776/4776), done.
# remote: Total 9534 (delta 4216), reused 8042 (delta 3136), pack-reused 0
# Receiving objects: 100% (9534/9534), 7.40 MiB | 17.08 MiB/s, done.
# Resolving deltas: 100% (4216/4216), done.
从存储库历史记录中删除带有冒号的文件:
git filter-repo --invert-paths --path-match "*:*"
# Parsed 591 commits
# New history written in 0.47 seconds; now repacking/cleaning...
# Repacking your repo and cleaning out old unneeded objects
# HEAD is now at 501102d daily autocommit
# Enumerating objects: 9534, done.
# Counting objects: 100% (9534/9534), done.
# Delta compression using up to 8 threads
# Compressing objects: 100% (3696/3696), done.
# Writing objects: 100% (9534/9534), done.
# Total 9534 (delta 4216), reused 9534 (delta 4216), pack-reused 0
# Completely finished after 1.33 seconds.
检查仍然显示带冒号的文件名:
git log --format="reference" --name-status --diff-filter=A "*:*"
# A iscsi/nodes/iqn.2000-01.com.synology:NAS01-DS916.nas/ff11::111:11ff:ff1f:1ff1,3260,1/default
# ...
不幸的是,似乎执行了 filter-repo,但日志仍然列出了带有冒号的文件名:-(
答:
- 如何列出所有带有冒号的路径:在完整的 GIT 存储库历史记录中?
你可能在这里不走运。有关此问题和 Windows 中的解决方法的更多讨论,请点击此处。
- 如何从 GIT 存储库历史记录中删除路径至少有一个冒号 : 的文件名?
如果您与他人一起开发,请小心使用这种方法。当在源中修改现有分支时,当其他人试图将其拉下时,会引起很多冲突。
但是,如果您可以继续,可以在此处尝试一种方法。
评论
链接 #1 未提供列出具有 colo 的路径的解决方案
检查:
git ls-tree -r master --name-only | grep ":"
但建议的方法是重置所有没有“:”的文件,并删除其余的文件:
git ls-tree -r master --name-only | grep -v ":" | xargs git reset HEAD
git commit -m "deleting all files with a colon in the name"
git restore -- .
OP klor 报告以 git log
pretty 格式 “” 列出这些文件(即):reference
<abbrev-hash> (<title-line>, <short-author-date>)
git log --format="reference" --name-status --diff-filter=A "*:*" >/opt/git_etc_repo_files_w_colons.txt
OP建议:
# Clone repository, to be executed on a safe repo:
git clone --no-local /source/repo/path/ /target/path/to/repo/clone/
# Cloning into '/target/path/to/repo/clone'...
# remote: Enumerating objects: 9534, done.
# remote: Counting objects: 100% (9534/9534), done.
# remote: Compressing objects: 100% (4776/4776), done.
# remote: Total 9534 (delta 4215), reused 8043 (delta 3136), pack-reused 0
# Receiving objects: 100% (9534/9534), 7.41 MiB | 16.78 MiB/s, done.
# Resolving deltas: 100% (4215/4215), done.
cd /target/path/to/repo/clone/
# List the files with colon from repo history into a list file:
git log --all --name-only -m --pretty= -- '*:*' | sort -u >/opt/git_repo_files_w_colons.txt
# Remove the files with colon from repo history:
git filter-repo --invert-paths --paths-from-file /opt/git_repo_files_w_colons.txt
# Parsed 591 commits
# New history written in 0.74 seconds; now repacking/cleaning...
# Repacking your repo and cleaning out old unneeded objects
# HEAD is now at e5fdf93 daily autocommit
# Enumerating objects: 9347, done.
# Counting objects: 100% (9347/9347), done.
# Delta compression using up to 8 threads
# Compressing objects: 100% (3696/3696), done.
# Writing objects: 100% (9347/9347), done.
# Total 9347 (delta 4078), reused 9345 (delta 4076), pack-reused 0
# Completely finished after 1.59 seconds.
# List files with colon to check result:
git log --format="reference" --name-status --diff-filter=A "*:*"
# Empty result, so git filter-repo was successful, filenames with colon were removed!
评论
git ls-tree -r master --name-only | grep ":"
git ls-tree -r live_master --name-only | grep -v ":" | xargs git reset HEAD
error: unknown switch '/'
更好的方法可能是不在 Windows 上签出这些文件,查看稀疏的签出工具,或者用 Windows 可以处理的字符重命名它们,而是按照要求回答问题:
- 如何列出所有带有冒号的路径:在完整的 GIT 存储库历史记录中?
git log --all --name-only -m --pretty= -- '*:*' | sort -u
- 如何从 GIT 存储库历史记录中删除路径至少有一个冒号 : 的文件名?
git filter-branch --prune-empty --index-filter '
git ls-files "*:*" | git update-index --remove --stdin
' -- --all
这将从您必须更改的第一个提交开始重写您的整个历史记录。在临时克隆中执行此操作。
评论
git filter-repo --invert-path
命令。
git filter-branch --prune-empty --index-filter ' git ls-files "*:*" | git update-index --remove --stdin ' -- --all
use an alternative filtering tool such as 'git filter-repo' instead
git filter-branch ...
git filter-repo --invert-path command
Aborting: Refusing to destructively overwrite repo history since this does not look like a fresh clone. (expected freshly packed repo)
git filter-repo
filter-repo
评论