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

Posted

技术标签:

【中文标题】如何判断文件是不是被 git 跟踪(通过 shell 退出代码)?【英文标题】:How to tell if a file is git tracked (by shell exit code)?如何判断文件是否被 git 跟踪(通过 shell 退出代码)? 【发布时间】:2011-01-25 04:57:43 【问题描述】:

有没有办法通过运行一些git 命令并检查其退出代码来判断文件是否正在被跟踪?

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

【问题讨论】:

我认为关键是,确定文件被跟踪或未跟踪的标准是什么。应该有某种跟踪的文件集合来搜索。 【参考方案1】:

尝试:

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

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

【讨论】:

至少对于我的旧 (1.6.0) 版本的 git,您需要将 --error-unmatch 选项放在文件名 之前 以获取错误。不知何故,该选项仅适用于它后面的文件名。 实际上,问题似乎是未启用 GNU getopt 选项置换,并且当出现在文件名之后(或 -- 之后)时,--error-unmatch 被视为另一个(不在index) 文件名,并且没有效果。 git ls-files | grep &lt;PATTERN&gt;?例如:git ls-files | grep Main.h 【一种天真的方式】在文件中做一点小改动(加/去掉一个空格)。并查看输入“git status”时是否列出了文件。一种愚蠢的方式,但可以节省时间。 -o | --others 选项将只在输出中未跟踪的文件。示例: $ git ls-files -o $ touch delete-me.sql $ git ls-files -o delete-me.sql【参考方案2】:

如果您不想让控制台出现错误消息,也可以运行

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【参考方案3】:

编辑

如果你需要在 bash 中使用 git,可以使用 --porcelain 选项到 git status

--瓷器

以稳定、易于解析的格式提供输出 脚本。目前这是相同的 to --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")

【讨论】:

对不起,我应该更清楚。状态还可以,但我宁愿检查退出代码而不是解析输出。 git status --porcelain 是您的朋友,如果您需要通过脚本解析输出,请查看链接的文档,它显示了一些其他有用的选项 Hihi,不适用于非常旧的 Git:git status --porcelain error: unknown option porcelain' 版本是 1.6.0 :-) @user465139 是正确的...您需要 git 1.7.0 或更高版本(直到那时才添加瓷器选项)。【参考方案4】:

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

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

【讨论】:

哇。我一定是在一个目录上运行它,它的行为就像是在检查整个 repo。谢谢。 实际上,如果我运行git status trackedfile,我会得到退出代码 1(预计 0 会有用),但它不会在输出中给我“错误:”。我宁愿解析退出代码而不是字符串输出。 我发现如果我在我的 git 工作副本中存在但被 .gitignore 排除的文件上运行 git status 不会引发错误。 (即这个答案不行。) 请注意,如果文件在忽略列表中,即在文件.gitignore中,则无法正常工作 那行不通。即使文件不存在,它也总是打印相同的内容。 $ git status notthere : On branch master nothing to commit, working directory clean【参考方案5】:

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

例如,

git-ls-files test_file.c | grep。

如果文件被跟踪,将以零代码退出,但如果文件未被跟踪,则退出代码为 1。

【讨论】:

【参考方案6】:

使用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
....
....

如果文件没有被 git 跟踪,

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

【讨论】:

【参考方案7】:

我建议您使用自定义 别名 .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

【讨论】:

【参考方案8】:

只要我的两分钱:

git ls-files | grep -x relative/path

relative/path 可以通过在自动完成 shell 中按 tab 轻松确定。添加额外的 | wc -l 以获得 1 或 0 输出。

【讨论】:

根据路径(例如,如果它包含一个点),您应该添加grep选项--fixed-strings【参考方案9】:

我更喜欢git log -1 --oneline 而不是git ls-files,因为 git log 命令不会遍历目录,因此无论检查的路径是文件还是目录,输出都是相似的。

这是git ls-files 的示例输出:

vinegupt@bhoscl88-04(/imsgit_local/work/vinegupt/ims_21.8/ims_oam/MT)$ git ls-files untracked-file # Untracked file shows no output
vinegupt@bhoscl88-04(/imsgit_local/work/vinegupt/ims_21.8/ims_oam/MT)$ git ls-files form/data.json # tracked file shows its name again
form/data.json
vinegupt@bhoscl88-04(/imsgit_local/work/vinegupt/ims_21.8/ims_oam/MT)$ git ls-files form # For directory entire directory is traveresed
form/Traffic_Params_2M_IS_cont_GVolte_EATF.xls
form/data.json

git log -1 --oneline 的示例输出:

vinegupt@bhoscl88-04(/imsgit_local/work/vinegupt/ims_21.8/ims_oam/MT)$ git log -1 --oneline untracked-file # Untracked file shows no output
vinegupt@bhoscl88-04(/imsgit_local/work/vinegupt/ims_21.8/ims_oam/MT)$ git log -1 --oneline form/data.json # tracked file shows one-line output
e8e9e0f CONTAINERS-767 MT and release change for 21.8
vinegupt@bhoscl88-04(/imsgit_local/work/vinegupt/ims_21.8/ims_oam/MT)$ git log -1 --oneline form # Only directory info is given no traversal
e8e9e0f CONTAINERS-767 MT and release change for 21.8

【讨论】:

以上是关于如何判断文件是不是被 git 跟踪(通过 shell 退出代码)?的主要内容,如果未能解决你的问题,请参考以下文章

第一章 Part 2/2 Git 一览

如何从 git 跟踪中删除文件? [复制]

如何使用 git 命令行区分两个未跟踪的文本文件 [重复]

Shell脚本判断文件是不是存在

20.5-20.9 shel:l脚本中的逻辑判断,文件目录属性判断,if特殊用法 ,case判断

xml .gitignore将阻止未跟踪文件被添加(没有添加-f)到git跟踪的文件集,但git将继续