我有一个肮脏的工作树,脏,因为我对源文件进行了更改并修改了一些图像.我试图只将图像添加到索引中,所以我运行了这个命令:
git add *.png
Run Code Online (Sandbox Code Playgroud)
但是,这不会添加文件.添加了一些新的图像文件,但没有添加任何已修改/预先存在的图像文件.
是什么赋予了?
编辑:这是一些相关的终端输出
$ git status
# On branch master
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: src/main/java/net/plugins/analysis/FormMatcher.java
# modified: src/main/resources/icons/doctor_edit_male.png
# modified: src/main/resources/icons/doctor_female.png
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# src/main/resources/icons/arrow_up.png
# src/main/resources/icons/bullet_arrow_down.png
# src/main/resources/icons/bullet_arrow_up.png
no changes added to commit (use "git add" and/or "git commit -a")
Run Code Online (Sandbox Code Playgroud)
然后执行"git add*.png"(命令后无输出)
然后:
$ git status
# On branch master
#
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: src/main/resources/icons/arrow_up.png
# new file: src/main/resources/icons/bullet_arrow_down.png
# new file: src/main/resources/icons/bullet_arrow_up.png
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: src/main/java/net/plugins/analysis/FormMatcher.java
# modified: src/main/resources/icons/doctor_edit_female.png
# modified: src/main/resources/icons/doctor_edit_male.png
Run Code Online (Sandbox Code Playgroud)
Cas*_*bel 18
Michael Mrozek的评论基本上就是答案.*.png匹配当前目录中该名称的文件,而不是子目录中的文件.如果要在子目录中添加一个,请执行以下操作:
git add src/main/resources/icons/*.png
Run Code Online (Sandbox Code Playgroud)
或者,根据您的shell,您可以执行以下操作:
git add **/*.png
Run Code Online (Sandbox Code Playgroud)
关键是它是执行globbing的shell(将*.png扩展为文件名列表).Git与此无关; 它只需要shell提供的参数.
编辑:由于这设法被接受,我应该继续并指出其他人做的一些git命令在内部支持globbing(通过fnmatch),所以如果你引用一个glob模式,它将被shell通过未经修改的传递给git,将进行全球扩张.
Chr*_*sen 11
一些Git的命令(包括git add)可以自己处理文件名模式.但首先你必须确保模式到达Git.
通常,未加引号的模式可能不会使其成为调用的命令.作为一种特殊情况,如果模式不匹配任何文件(在当前目录中,如果模式中没有斜杠),bash会将未扩展模式传递给命令(除非nullglob设置了选项,在这种情况下模式参数将是从传递给命令的参数中删除).但是这种行为因壳而异.默认情况下,除非未设置选项(将未展开的模式作为参数传递)或设置选项(从参数列表中删除模式),否则zsh会发出"找不到匹配项"之类的错误.nomatchnull_glob
因此,如果您了解shell的行为并且您知道模式中指定的任何目录的内容(通常只是没有斜杠的模式的当前目录),那么使用不带引号的模式并期望它们到达底层命令是可靠的.
因此,为了获得最大的可靠性,如果您想git add将文字字符串*.png作为参数,那么您应该引用它.
git add \*.png
git add "*.png"
git add '*'.png
# etc.
Run Code Online (Sandbox Code Playgroud)
成功将文件名模式传递给Git后,您将遇到一些与shell处理它们的区别.
这个问题的主要区别在于匹配是由fnmatch(3) 完成的,没有设置FNM_PATHNAME.这意味着类似的模式*.png将匹配foo.png当前目录中的文件(就像shell一样),但它也会匹配dir/bar.png(因为没有FNM_PATHNAME *可以匹配斜杠).Git将其模式称为"pathspecs",以区别于shell"glob"模式.
不幸的是,git add处理pathspecs 的方式存在不一致.它总是将它们应用于未跟踪的文件,但它永远不会将它们应用于跟踪的文件(相反,只检查文件类型参数,例如pathspecs,以检查跟踪文件列表的完全匹配).这显然正是OP实际遇到的问题,因为它会添加与pathspec匹配的新文件,但无法更新(已经)跟踪的文件与pathspec匹配.
git add **/*.png只要你的shell支持**扩展模式(或等效的),Jefromi的workaround()就可以工作.
你实际上可以让Git完成工作,但是使用shell可能更容易(如果你的shell支持它).
# update all tracked files matching the Git pathspec *.png
git ls-files --cached -z \*.png | git update-index --add -z --stdin
Run Code Online (Sandbox Code Playgroud)
平滑Git的内部路径规范处理是一个"中期"目标,但没有任何有时间,兴趣和相关经验的人已经上前解决.
它被提出作为Google Summer of Code 2010的项目创意(没有被任何人接收),并且相关问题偶尔出现在邮件列表上(1月和2010年3月,有人报告的症状很像OP,Git的维护者解释了他希望长期看到的内容).