我正在编写的bash脚本有问题。我正在尝试从Github文档中应用此过程的步骤3,以从git历史记录中删除存储库历史记录中的所有文件。例如,如果.gitignore忽略.txt,我想从历史记录中删除所有.txt。对于每个.gitignore行,依此类推。
我可以在示例文件中使用通配符。因此,我可以运行以下命令删除所有.txt文件:
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch *.txt' --prune-empty --tag-name-filter cat -- --all
因此,我试图制作一个bash脚本来执行相同的操作。
我制作了一个简单的.gitignore文件进行测试,如下所示:
#foo
*.txt
*.docx
我的shell脚本如下所示:
#!/bin/bash
s1="#"
str1="'git rm --cached --ignore-unmatch "
str2="'"
cat .gitignore | while read line
do
if [[ $line == *"$s1"* ]]
then
echo #skip
else
str3=$str1$line$str2
git filter-branch --force --index-filter $str3 --prune-empty --tag-name-filter cat -- --all
fi
done
但是,这将导致以下输出:
fatal: bad revision 'rm'
fatal: bad revision 'rm'
(对于.gitignore文件的每一行一次)
我做错了什么?
我相信这可能会做您想要的。
#!/bin/bash
cat .gitignore | while read line
do
if [[ $line == *#* ]]
then
echo #skip
else
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch '"$line" --prune-empty --tag-name-filter cat -- --all
fi
done
我避免了所有只会使事情复杂化的毫无意义的中间变量。(虽然只是去除单引号str1
和下降str2
可能已经足够,这是理智的,据我很担心。)
过滤器只需要一个字符串,但是如何构造该字符串由您决定。
您可能还可以从gitignore收集所有模式,并只运行一次filter-branch(--force
此时不需要)。
#!/bin/bash
patts=()
while read -r line
do
if [[ $line != *#* ]]; then
patts+=("$line")
fi
done < .gitignore
git filter-branch --index-filter 'git rm --cached --ignore-unmatch '"${patts[*]}" --prune-empty --tag-name-filter cat -- --all
还要注意,您可能应该确保只在这里处理简单的模式,因为在我不认为的所有情况下rm
,.gitignore
对模式的理解和理解都不尽相同。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句