如何判断文件是否被git跟踪(通过shell退出代码)?


357

是否可以通过运行某些git命令并检查其退出代码来判断是否正在跟踪文件?

换句话说:git是否跟踪文件?


我认为关键是,确定文件为已跟踪还是未跟踪的标准是什么。应该有某种跟踪的文件集合来搜索。
smwikipedia 2011年

Answers:


443

尝试:

git ls-files --error-unmatch <file name>

如果未跟踪文件,将以1退出


至少对于我的旧(1.6.0)版本的git,您需要将该--error-unmatch选项放在文件名之前,以获取错误。该选项仅以某种方式仅适用于其后的文件名。
亚历克斯·杜普

实际上,问题似乎在于未启用GNU getopt选项置换,并且当出现在文件名之后(或之后--)时,--error-unmatch它被视为仅另一个文件名(不在索引中),并且无效。
亚历克斯·杜普

29
git ls-files | grep <PATTERN>?例如:git ls-files | grep Main.h
gaussblurinc

1
[一种简单的方法]在文件中做一个小的更改(添加/删除空格)。并查看在键入“ git status”时是否正在列出文件。一种愚蠢的方式,但可以节省时间。
BraveNinja '16

但我说,用“混帐添加-A && git的承诺-m‘嗒嗒提交它混帐LS-树--name只-r SHA1‘命令’命令甚至可以看到与全文件。’
Dr.jacky

66

如果您不想在控制台上显示错误消息,也可以运行

git ls-files file_name

然后检查结果。如果git不返回任何内容,则不会跟踪该文件。如果被跟踪,git将返回文件路径。

如果您想将其组合到脚本中,例如PowerShell,这将很方便:

$gitResult = (git ls-files $_) | out-string
if ($gitResult.length -ne 0)
{
    ## do stuff with the tracked file
}

我认为file_name需要完全匹配(完整路径+文件名),但可以与通配符一起使用:git ls-files *foo.rb
dechimp

16

编辑

如果您需要从bash使用git,则可以--porcelain选择git status

- 瓷

以稳定,易于解析的格式为脚本输出。当前,这与--short输出相同,但是可以保证将来不会更改,从而使脚本安全。

输出看起来像这样:

> git status --porcelain
 M starthudson.sh
?? bla

或者,如果一次只执行一个文件:

> git status --porcelain bla
?? bla

原版的

做:

git status

您将看到报告,说明哪些文件已更新,哪些文件未跟踪。

您可以看到bla.sh已被跟踪和修改而newbla未被跟踪:

# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#
#       modified:   bla.sh
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       newbla
no changes added to commit (use "git add" and/or "git commit -a")

对不起,我应该更清楚了。状态还可以,但是我宁愿检查退出代码,也不愿解析输出。
Dale Forester 2010年

git status --porcelain是您的朋友,如果您需要按脚本解析输出,请查看链接的文档,它显示了其他有用的选项
stefanB 2010年

Hihi,不适用于非常老的Git:git status --porcelain error: unknown option 瓷器版本为1.6.0 :-)
Laryx Decidua,2014年

@ user465139是正确的...您需要git 1.7.0或更高版本(直到那时才添加ceramic选项)。
mason81 2014年

13

尝试git status在文件上运行。如果它没有被git跟踪,它将打印一个错误

PS$> git status foo.txt
error: pathspec 'foo.txt' did not match any file(s) known to git.

哇。我一定已经在目录上运行过它,并且它的行为就像正在检查整个仓库。谢谢。
Dale Forester 2010年

4
实际上,如果我运行,git status trackedfile我会得到退出代码1(预期为0很有用),但在输出中不会出现“错误:”。我宁愿解析退出代码,也不愿解析字符串输出。
Dale Forester 2010年

43
我发现如果我在git工作副本中存在但被.gitignore排除的文件上运行git status,不会引发任何错误。(即,这个答案不会。)
JellicleCat 2013年

请注意,如果文件位于忽略列表(即文件)中,则无法正常工作.gitignore
Robin Hsu 2015年

8
那不行 即使文件不存在,它也会始终打印相同的内容。$ git status notthereOn branch master nothing to commit, working directory clean
Chloe

6

我不知道任何提供“错误的”退出代码的git命令,但似乎一种简单的方法是使用git命令,该命令不会为未跟踪的文件提供任何输出,例如git-log或git-ls-files。这样,您实际上就不必进行任何解析,可以通过另一个简单的实用程序(例如grep)运行它,以查看是否有任何输出。

例如,

git-ls-files test_file.c | grep。

如果跟踪文件,将以零代码退出,如果不跟踪文件,则退出代码为一。


3

我提出一个自定义的别名.gitconfig

您必须这样做:

1)使用git命令:

git config --global alias.check-file <command>

2)编辑~/.gitconfig并在别名部分添加以下行:

[alias]
    check-file = "!f() { if [ $# -eq 0 ]; then echo 'Filename missing!'; else tracked=$(git ls-files ${1}); if [[ -z ${tracked} ]]; then echo 'File not tracked'; else echo 'File tracked'; fi; fi;  };  f"

一旦启动命令(1)或保存的文件(2),就可以在工作空间中对其进行测试:

$ git check-file
$ Filename missing 

$ git check-file README.md
$ File tracked 

$ git check-file foo
$ File not tracked

2

使用git log将提供有关此的信息。如果在git中跟踪该文件,该命令将显示一些结果(日志)。否则它是空的。

例如,如果文件是git跟踪的,

root@user-ubuntu:~/project-repo-directory# git log src/../somefile.js
commit ad9180b772d5c64dcd79a6cbb9487bd2ef08cbfc
Author: User <someone@somedomain.com>
Date:   Mon Feb 20 07:45:04 2017 -0600

    fix eslint indentation errors
....
....

如果未跟踪该文件,

root@user-ubuntu:~/project-repo-directory# git log src/../somefile.js
root@user-ubuntu:~/project-repo-directory#

1

只是我的两分钱:

git ls-files | grep -x relative/path

其中relative/path可通过按下容易地确定tab自动完成外壳内。添加一个附加值| wc -l 以获得1或0输出。


根据路径(例如,如果包含点),应添加grepoption --fixed-strings
EndlosSchleife
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.