我在git中有以下过滤器(我已将它们扩展到行以获得更多可读性):
git config --global filter.lastcommit.smudge
'IFS="";
lastcommit=`git log -1 --format="%H" -- %f`;
filename=$(basename %f);
while read -r;
do
line="${REPLY//\$Revision\$/\$Revision: $lastcommit\$}";
line="${line//\$RCSfile\$/\$RCSfile: $filename\$}";
echo $line;
done'
git config --global filter.dater.smudge
'IFS=""; myDate=`git log --pretty=format:"%cI" -1 --format="%H" -- %f`;
while read -r;
do line="${REPLY//\$Date\$/\$Date: $myDate\$}";
echo $line;
done'
当我签出分支时,过滤器使用.gitattributes文件在三个目录中的大约~260 +文件上运行,但是每个文件可能需要几秒钟才能执行过滤:
Checking out files: 100% (6659/6659), done.
Branch ABC set up to track remote branch ABC from origin.
Switched to a new branch 'ABC'
real 4m42.334s
user 4m15.607s
sys 0m29.788s
有没有办法改善表现?
解决方案:我在阅读@torek回答后切换到使用sed。过滤器现在是:
git config --global filter.lastcommit.smudge
'lastcommit=`git log -1 --format="%H" -- %f`;
filename=$(basename %f);
sed -e "s/\\\$Revision\\\$/\$Revision: $lastcommit\$/"
-e "s/\\\$RCSfile\\\$/\$RCSfile: $filename\$/";'
git config --global filter.dater.smudge
'myDate=`git log --pretty=format:"%cI" -1 -- %f`;
sed -e "s/\\\$Date\\\$/\$Date: $myDate\$/";'
收益非常可观:
~/panos > time git checkout ABC
Checking out files: 100% (6659/6659), done.
Branch ABC set up to track remote branch ABC from origin.
Switched to a new branch 'ABC'
real 0m12.956s
user 0m10.417s
sys 0m2.452s
我的印象是,使用sed的叉子比使用纯粹的bash更昂贵。结果是sed对文本替换更有效。我今天学到了一些东西
答案 0 :(得分:3)
注意:我从未使用干净和涂抹过滤器,但这个概念看起来很简单。
您使用bash
完全在read -r
代码中进行涂抹操作。这是非常低效的(出于好的理由不适用于您的情况)并且可能是所有缓慢的原因。使用sed
代替应该大大加快速度。
-e s/regexp/replacement/
的{{1}}参数与此处的替换基本相同(您只需保护最终sed
与正则表达式匹配),因此切换应该非常简单。 / p>
答案 1 :(得分:0)
注意:请注意直接在您的(涂抹/干净)脚本中访问%f
文件内容。
commit 52db4b0见Joey Hess (joeyh
)(2016年8月3日)
(由Junio C Hamano -- gitster
--合并于commit 104985c,2016年8月8日)
现在.gitattributes
documentation(Git 2。10,2016年第3季度)包括:
[filter "p4"]
clean = git-p4-filter --clean %f
smudge = git-p4-filter --smudge %f
请注意"
%f
"是正在处理的路径的名称 根据要过滤的版本,磁盘上的相应文件可能不存在,或者可能具有不同的内容 因此,涂抹和清除命令不应该尝试访问磁盘上的文件,而只是作为标准输入上提供给它们的内容的过滤器。