如何判断文件是不是被 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 <PATTERN>
?例如: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 退出代码)?的主要内容,如果未能解决你的问题,请参考以下文章