我在使用带路径规范的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文档,但这并不详细。
有人能帮我理解背后的逻辑吗?
答案 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
希望它有所帮助,