pathpec应该如何工作?

时间:2012-07-03 15:37:19

标签: git git-status

我在使用带路径规范的git-status时观察到一种奇怪的行为。我希望你的意见是它是预期的行为,还是git中未定义的行为。

初始设置

$ mkdir main && cd main
$ git init .
Initialized empty Git repository in d:/temp/main/.git/
$ touch test[1].txt
$ touch test[2].txt

以下是可以理解的

$ # 1. escaped square brackets
$ git status test\[1\].txt --short        
?? test[1].txt

$ # 2. escaped square brackets with range
$ git status test\[[1-9]\].txt --short    
?? test[1].txt
?? test[2].txt

$ # 3. unmatched range, with what looks like a fallback to literal comparison
$ git status test[1].txt --short          
?? test[1].txt

意外行为的其他设置

$ touch test1.txt

意外行为

$ # 4. matched range, so no fallback to literal comparison (this one looks OK)
$ git status test[1].txt --short
?? test1.txt

$ # 5. escaped square brackets => I would expect only test[1].txt to be returned
$ git status test\[1\].txt --short
?? test1.txt
?? test[1].txt

$ # 6. escaped square brackets with range => I would expect only test[1].txt 
$ # and test[2].txt to be returned
$ git status test\[[1-9]\].txt --short
?? test1.txt
?? test[1].txt
?? test[2].txt

$ # 7. only escaping the last square bracket
$ # result looks similar to the 5th case
$ git status test[1\].txt --short
?? test1.txt
?? test[1].txt

更有趣的其他设置

$ git add test1.txt
$ rm test1.txt
$ touch test2.txt

更多意外行为

$ # 8. ???
$ git status test[1].txt --short
AD test1.txt
?? test[1].txt

$ # 9. We lost test1.txt ???
$ git status test[1-2].txt --short
?? test2.txt

$ # Woo... Should this really work?
$ git status test[*.txt --short
AD test1.txt
?? test2.txt
?? test[1].txt
?? test[2].txt
我在那里有点困惑。我已经阅读了与pathspec相关的Git文档,但这并不详细。

有人能帮我理解背后的逻辑吗?

1 个答案:

答案 0 :(得分:4)

这里有很多事情需要讨论,但我会尝试关注: 1。这背后的逻辑, 2。它如何修改行为。< / p>

逻辑

大多数路径扩展由shell完成(因此我的评论)。有些是由git完成的,当它具备所需的时候。

一些测试

设置

我用这个程序调查了这个问题:

include <stdio.h>

int
main(int argc, char **argv)
{
    int i;

    for (i = 1; i < argc; i++) {
            puts(argv[i]);
    }
}

我知道,这是非常高技能的编程。

测试

我们现在可以看看发生了什么,看看shell如何修改git收到的内容:

第1,2,3,4点:一切正常,运行小程序会给你一样的。

$ ./a.out test\[1\].txt test\[[1-9]\].txt test[1].txt
test[1].txt
test[1].txt
test[2].txt
test[1].txt

第5,6,7点:这次是由Git处理的,行为并不令人惊讶(同时进行全局和文字比较)

$ ./a.out test\[1\].txt test\[[1-9]\].txt test[1\].txt
test[1].txt
test[1].txt
test[2].txt
test[1].txt

第8,9,10点:根据我们之前看到的情况,它已经不再令人惊讶了。对于 9。,没有bash比较与test1.txt匹配(删除,因此,...已删除)

$ ./a.out test[1].txt                         
test[1].txt

$ ./a.out test[1-2].txt          
test2.txt

$ ./a.out test[*.txt
test[1].txt
test[2].txt

结论

如果你想测试Git处理pathspec的方式,你应该用双引号括起你的路径:

$ ./a.out "test[*.txt" "test[1\].txt"
test[*.txt
test[1\].txt

希望它有所帮助,