Git添加不使用.png文件?

DLa*_*Law 10 git

我有一个肮脏的工作树,脏,因为我对源文件进行了更改并修改了一些图像.我试图只将图像添加到索引中,所以我运行了这个命令:

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的维护者解释了他希望长期看到的内容).