我编写了一个脚本来列出包含特定文件的repo中的提交。它工作得很好,但我不明白为什么我要写这个:
for c in $(git rev-list "$rev_list"); do
git ls-tree --name-only -r "$c" | grep -q "$file"
if [ $? -eq 0 ]; then
echo "Saw $file in $c"
fi
done
而我通常会写同样的事情:
[[ $(git ls-tree --name-only -r "$c" | grep -q "$file") ]] && echo "Saw $file in $c"
# or
[[ ! $(git ls-tree --name-only -r "$c" | grep -q "$file") ]] || echo "Saw $file in $c"
两个短版本都不起作用:它们不输出任何内容。当我写它以显示所有不包含该文件的提交时,我得到输出:
[[ $(git ls-tree --name-only -r "$c" | grep -q "$file") ]] || echo "Did not see $file in $c"
但是,如果我从输出中获取提交哈希并运行
git ls-tree -r <the hash> | grep file
我注意到树中的文件 用于某些提交,这让我相信它只是列出了脚本处理的所有提交。无论哪种方式,我可能都错过了一些东西,但我无法弄清楚它是什么
答案 0 :(得分:6)
您不需要在条件语句([[ $(command) ]]
)中包装该命令。实际上,这将无法与grep -q
一起使用,因为您实际上正在测试命令是否打印。你可以这样做:
git ls-tree --name-only -r "$c" | grep -q "$file" && echo "Saw $file in $c"
一般来说,任何代码块都是
foreground_command
if [ $? -eq 0 ]
then
bar
fi
可以替换为
if foreground_command
then
bar
fi
甚至
foreground_command && bar
您应该使用的三种替代方案中的哪一种取决于foreground_command
,bar
或两者是否为多行命令。
答案 1 :(得分:0)
awk
救援:
git ls-tree --name-only -r "$c" | awk "/$file/{printf '%s in %s\n', '$file', '$c'}"