2017-10-20 242 views
0

我想为所有.cpp文件设置代码样式格式,然后它们被提交给git。使用过滤器污迹/干净的git属性通过shell脚本处理.cpp文件没有找到文件名

我做了小脚本(名为codeformat)要做到这一点,(还试图replaing以$ 1%F)

#! /bin/bash 
clang-format -style=file %f | diff %f -** 
if [ $? -ne 0 ]; then 
    echo "ERROR: codeformat not correct" 
    exit 1 
fi 

没有设置混帐配置,带*号的.cpp过滤= codeformat更新.gitattributes,

git config --global filter.codeformat.clean codeformat 
git config --global filter.codeformat.smudge codeformat 

看起来像脚本正在运行,但它没有获取文件名。为什么是这样?

回答

1

您在错误的地方有%f指令。

the gitattributes documentation所示(搜索%f):

Sequence "%f" on the filter command line is replaced with the name of the file the filter is working on. A filter might use this in keyword substitution. For example:

[filter "p4"] 
     clean = git-p4-filter --clean %f 
     smudge = git-p4-filter --smudge %f 

因此,要获得文件的路径名,您将需要filter.codeformat.clean设置,例如,以codeformat %f

此时你还需要修改你的bash脚本,因为语法参数替换确实$1。然而,读取来自gitattributes文档紧跟其后的段落:

Note that "%f" is the name of the path that is being worked on. Depending on the version that is being filtered, the corresponding file on disk may not exist, or may have different contents. So, smudge and clean commands should not try to access the file on disk, but only act as filters on the content provided to them on standard input.

这里要强调的是我的,但是这是告诉你,你不能简单地打开磁盘文件,读取它。您只能过滤标准输入,提供标准输出。

As it turns out, clang-format is designed to do just that.差异,但是,是不是。)


编辑补充工作示例:

$ cat ~/scripts/dotest 
#! /bin/sh 
echo "dotest run with $# arguments:" >>/tmp/dotest_log 
for i do 
    printf '%s\n' "$i" 
done >>/tmp/dotest_log 
cat 
$ which dotest 
[path edited]/scripts/dotest 
$ cat .git/config 
[core] 
     repositoryformatversion = 0 
     filemode = true 
     bare = false 
     logallrefupdates = true 
[filter "testfilter"] 
     clean = dotest %f 
     smudge = dotest %f 
$ cat .gitattributes 
*.test filter=testfilter 
$ echo 'bar.test' > bar.test 
$ git add bar.test 
$ cat /tmp/dotest_log 
dotest run with 1 arguments: 
bar.test 
+0

看到添加工作的例子。我不知道你做了什么不同,但我的脚本调用文件名称,如/ tmp中的日志文件所示。 – torek

+0

这有帮助,早些时候我错过了运行git config,我运行git config --global,但是我必须单独运行“git config”,而不需要全局性地在.git/config中更新它,否则它只会更新〜/。 gitconfig。现在,它打印文件名,我现在需要使用我的代码格式命令。 – Ramana

+0

我们可以写屏幕错误信息吗?让我们说从/ tmp/dotest_log的内容,wehn我触发git add?我有一些回声命令,而不是重定向到日志,它不写日志,它只给出消息错误过滤器...目标是给一些消息,所以用户可以遵循,此外,脚本退出内部脚本不退出Git操作,我的Git即使脚本失败,添加仍然成功 - 我们可以强制它失败git add直到它们修复吗? – Ramana

0

%fgit解释,并应在gitconfig。在shell脚本中使用$1

git config --global filter.codeformat.clean 'codeformat %f' 
git config --global filter.codeformat.smudge 'codeformat %f' 

#! /bin/bash 
clang-format -style=file $1 | diff $1 -** 
if [ $? -ne 0 ]; then 
    echo "ERROR: codeformat not correct" 
    exit 1 
fi 
+0

我也尝试过,没有帮助,请参阅下面的更多细节。 – Ramana

0

这意味着,我永远无法得到的文件名?我试过%F与混帐配置本身并改变脚本中使用$ 1,它仍然没有得到文件名。

cat ~/.gitconfig 

[filter "codeformat"] 
     clean = codeformat %f 
     smudge = codeformat %f 

cat .gitattributes 
    #clang code style format 
    *.cpp       filter=codeformat 

cat codeformat 
    #! /bin/bash 
    clang-format -i -style=file $1 - 
    echo "file/path accessed is _____ $1 ____" > log_output 2>&1 

git add src/sample.cpp 

    cat log_output 
    file/path accessed is _____ ____ 

相同的命令(下图),如果我在命令行中运行效果良好,

clang-format -i -style=file src/sample.cpp 

使用Git添加它不能获取文件名,因此其他错误与 错误:读取时无法使用-i来自stdin。

注意到这个时候,我删除diff命令,使用-i来代替直接的源文件”

相关问题