Jak*_*ake 8 git bash sh git-bash
我写的这个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
Run Code Online (Sandbox Code Playgroud)
所以我试着制作一个bash脚本来做同样的事情.
我制作了一个简单的.gitignore文件来测试它,如下所示:
#foo
*.txt
*.docx
Run Code Online (Sandbox Code Playgroud)
我的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
Run Code Online (Sandbox Code Playgroud)
但是,这会产生以下输出:
fatal: bad revision 'rm'
fatal: bad revision 'rm'
Run Code Online (Sandbox Code Playgroud)
(对于.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
Run Code Online (Sandbox Code Playgroud)
我避免了所有那些只是复杂事情的无意义的中间变量.(虽然只是删除了单引号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
Run Code Online (Sandbox Code Playgroud)
另外请注意,你应该确保你只处理简单的在这里模式,因为rm和.gitignore模式的理解是不是在所有情况下,我不认为完全一样.
| 归档时间: |
|
| 查看次数: |
1110 次 |
| 最近记录: |