"git rm -r" 通配
"git rm -r" with globbing
我正在尝试使用 git rm
作为过滤器分支的一部分。我想删除目录 */*/dir1
但没有任何反应。
我使用的命令是:
git filter-branch --tag-name-filter cat --index-filter "git rm -r --cached --ignore-unmatch */*/dir1" --prune-empty -f -- --all
命令
find . -wholename "*/*/dir1"
显示了很多匹配项。
如何删除这些目录?
更新:我正在尝试从历史记录中删除这些文件夹。
解决方案:
结合@j6t 和@Sam Gleske 的回答,这是我的解决方案:
git filter-branch --tag-name-filter cat \
--index-filter 'git ls-files | grep -E "^([^/]+/){2,3}dir1" |
xargs -I {} --no-run-if-empty git rm -r --cached "{}"' \
--prune-empty -f -- --all
使用这个(完全相同的顺序):
git filter-branch --force --index-filter 'git rm --cached -r --ignore-unmatch */*/dir1' --prune-empty --tag-name-filter cat -- --all
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now
根据git rm
documentation, you can pass it one or more files or folders. Since that is the case you can take advantage of shell globbing。在 bash
中,您必须在引号外使用 glob。
git rm -r */*/dir1
但是,有可能点击 ARG_MAX
limit in Linux(即 getconf ARG_MAX
)并出现错误。您可以通过在原始查找命令中使用 xargs 来解决这个问题。
find . -wholename "*/*/dir1" -print0 | xargs -0 git rm -r
我还建议将 -type d
添加到您的查找命令中,因为其他文件类型可能具有与 dir1
.
相同的名称
这只会将那些目录作为新提交删除。
使用 xargs 清除所有历史记录
由于您的意图是清除所有历史记录,并且 git rm
无法按预期工作;你还有另一种选择。使用带有 xargs
的原始 find
命令,使用来自 find
的路径删除整个历史记录。方法如下:
find . -wholename "*/*/dir1" -print0 | xargs -0 -I '{}' -n10 -- git filter-branch --tag-name-filter cat --index-filter "git rm -r --cached --ignore-unmatch {}" --prune-empty -f -- --all
诀窍是注意xargs
的-I '{}'
选项,在命令xargs
中使用{}
将被执行。
另见
以下应该满足您的需要:
git filter-branch --tag-name-filter cat \
--index-filter 'git ls-files -z -- "*/*/dir1" |
xargs -0 --no-run-if-empty git rm -r --cached' \
--prune-empty -f -- --all
请注意,该命令确实会进入目录,即它会匹配 a/b/c/d/dir1
,即使 **
未在 git ls-files
的参数中使用。
结合@j6t 和@Sam Gleske 的回答,这是我的解决方案:
git filter-branch --tag-name-filter cat \
--index-filter 'git ls-files | grep -E "^([^/]+/){2,3}dir1" |
xargs -I {} --no-run-if-empty git rm -r --cached "{}"' \
--prune-empty -f -- --all
我正在尝试使用 git rm
作为过滤器分支的一部分。我想删除目录 */*/dir1
但没有任何反应。
我使用的命令是:
git filter-branch --tag-name-filter cat --index-filter "git rm -r --cached --ignore-unmatch */*/dir1" --prune-empty -f -- --all
命令
find . -wholename "*/*/dir1"
显示了很多匹配项。
如何删除这些目录?
更新:我正在尝试从历史记录中删除这些文件夹。
解决方案:
结合@j6t 和@Sam Gleske 的回答,这是我的解决方案:
git filter-branch --tag-name-filter cat \
--index-filter 'git ls-files | grep -E "^([^/]+/){2,3}dir1" |
xargs -I {} --no-run-if-empty git rm -r --cached "{}"' \
--prune-empty -f -- --all
使用这个(完全相同的顺序):
git filter-branch --force --index-filter 'git rm --cached -r --ignore-unmatch */*/dir1' --prune-empty --tag-name-filter cat -- --all
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now
根据git rm
documentation, you can pass it one or more files or folders. Since that is the case you can take advantage of shell globbing。在 bash
中,您必须在引号外使用 glob。
git rm -r */*/dir1
但是,有可能点击 ARG_MAX
limit in Linux(即 getconf ARG_MAX
)并出现错误。您可以通过在原始查找命令中使用 xargs 来解决这个问题。
find . -wholename "*/*/dir1" -print0 | xargs -0 git rm -r
我还建议将 -type d
添加到您的查找命令中,因为其他文件类型可能具有与 dir1
.
这只会将那些目录作为新提交删除。
使用 xargs 清除所有历史记录
由于您的意图是清除所有历史记录,并且 git rm
无法按预期工作;你还有另一种选择。使用带有 xargs
的原始 find
命令,使用来自 find
的路径删除整个历史记录。方法如下:
find . -wholename "*/*/dir1" -print0 | xargs -0 -I '{}' -n10 -- git filter-branch --tag-name-filter cat --index-filter "git rm -r --cached --ignore-unmatch {}" --prune-empty -f -- --all
诀窍是注意xargs
的-I '{}'
选项,在命令xargs
中使用{}
将被执行。
另见
以下应该满足您的需要:
git filter-branch --tag-name-filter cat \
--index-filter 'git ls-files -z -- "*/*/dir1" |
xargs -0 --no-run-if-empty git rm -r --cached' \
--prune-empty -f -- --all
请注意,该命令确实会进入目录,即它会匹配 a/b/c/d/dir1
,即使 **
未在 git ls-files
的参数中使用。
结合@j6t 和@Sam Gleske 的回答,这是我的解决方案:
git filter-branch --tag-name-filter cat \
--index-filter 'git ls-files | grep -E "^([^/]+/){2,3}dir1" |
xargs -I {} --no-run-if-empty git rm -r --cached "{}"' \
--prune-empty -f -- --all