Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Some of Git's commands (including <code>git add</code>) can handle filename patterns themselves. But first you have to make sure the pattern gets to Git.</p> <p>In general, unquoted patterns may not make it to the invoked command. As a special case, if the pattern matches no files (in the current directory if there is no slash in the pattern), <em>bash</em> will pass the unexpanded pattern to the command (unless the <code>nullglob</code> option is set, in which case the pattern argument will be dropped from the arguments passed to the command). But the behavior varies among shells. By default, <em>zsh</em> issues an error like “no matches found” unless the <code>nomatch</code> option is unset (passes the unexpanded pattern as an argument) or the <code>null_glob</code> option is set (drops the pattern from the list of arguments).</p> <p>So using unquoted patterns and expecting them to get to the underlying command is only reliable if you know the behavior of your shell and you know the contents of any directories specified in the pattern (usually just the current directory for patterns without a slash).</p> <p>So, for maximum reliability, if you want <code>git add</code> to get the literal string <code>*.png</code> as an argument, then you should quote it.</p> <pre><code>git add \*.png git add "*.png" git add '*'.png # etc. </code></pre> <hr> <p>Once you have successfully passed a filename pattern to Git, you will encounter some differences from how shells handles them.</p> <p>The primary difference of concern in this question is that matching is done by <a href="http://www.opengroup.org/onlinepubs/000095399/functions/fnmatch.html" rel="noreferrer">fnmatch(3)</a> <em>without</em> FNM_PATHNAME set. This means that a pattern like <code>*.png</code> will match a file <code>foo.png</code> in the current directory (just like a shell), but it will also match <code>dir/bar.png</code> (because without FNM_PATHNAME the <code>*</code> can match against the slash). Git calls its patterns “pathspecs” to differentiate them from shell “glob” patterns.</p> <p>Unfortunately, there is an inconsistency in the way that <code>git add</code> handles pathspecs. It always applies them to untracked files, but it never applies them to tracked files (instead, filename-type arguments like pathspecs are only checked for exact matches against the list of tracked files). This is apparently exactly what the OP actually ran into, as it would add <em>new</em> files that match the pathspec, but would fail to update (already) tracked files that match the pathspec.</p> <p>Jefromi's workaround (<code>git add **/*.png</code>) works as long as your shell supports the <code>**</code> extended pattern (or an equivalent).</p> <p>You can actually make Git do the work, but using the shell is probably easier (if your shell supports it).</p> <pre><code># update all tracked files matching the Git pathspec *.png git ls-files --cached -z \*.png | git update-index --add -z --stdin </code></pre> <hr> <p>Smoothing out Git's internal pathspec handling is a “medium term” goal, but not one that anyone with the time, interest, and pertinent experience has stepped forward to fix.</p> <p>It was brought up as a <a href="https://git.wiki.kernel.org/index.php/SoC2010Ideas#Unify_Pathspec_Semantics" rel="noreferrer">project idea for Google Summer of Code 2010</a> (not picked up by anyone), and related issues come up on the mailing list once in a while (In January and again in March 2010 someone reported <a href="http://article.gmane.org/gmane.comp.version-control.git/142863" rel="noreferrer">a symptom much like the OP's</a>, <a href="http://article.gmane.org/gmane.comp.version-control.git/142880" rel="noreferrer">Git's maintainer explained what he would like to see in the long term</a>).</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload