如何从 GIT 仓库历史记录中删除路径中文件名带有冒号 : 的所有文件?

如何从 GIT 仓库历史记录中删除路径中文件名带有冒号 : 的所有文件?

我在 Debian 10 Linux 上的 GIT 存储库中存储了带冒号的 ISCSI 节点文件名。

例子:

'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(仅适用于命名的 repo master):

git ls-tree -r master --name-only | grep ":"

Works3:最后我用这个列出文件名中带有冒号的文件:

git log --format="reference" --name-status --diff-filter=A "*:*" >/opt/git_etc_repo_files_w_colons.txt

更新1针对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 为 2) :

git clone --no-local /源/repo/路径/ /目标/路径/到/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 似乎已执行,但日志仍然列出带有冒号的文件名:-(

答案1

用于查找已添加特定文件的所有提交 - 这将生成历史记录中git log名称匹配的所有文件的列表:*:*

git log --format="" --name-status --diff-filter=A "**/*:*"

--format=用于隐藏正常的日志输出;或者--oneline可能有用):

用于git filter-repo移除或重命名历史上有过这样的文件:

  • 去除:

    git filter-repo --invert-paths --path-match "*:*"
    
  • 重命名(例如更改:;):

    git filter-repo --filename-callback 'return filename.replace(b":", b";")'
    

git-filter-repo 需要与 git core 分开安装。

相关内容