-1

I am reading the documentation for Git Add in Git Reference:

Adds content from all *.txt files under Documentation directory and its subdirectories:

$ git add Documentation/\*.txt

Note that the asterisk * is quoted from the shell in this example; this lets the command include the files from subdirectories of Documentation/ directory.

What I think is that backslash is a escape prefix, but the explanation said "* is quoted from the shell", can someone give me more clarifications for the usage of backslash here?

Josh Lee
  • 171,072
  • 38
  • 269
  • 275
IcyBrk
  • 1,090
  • 12
  • 21

2 Answers2

2

In the Bash manual, the exact behavior is described in 3.5.8 Filename Expansion and 3.5.8.1 Pattern Matching. (Be warned that bash is quite complicated and it processes command line arguments in a long sequence of steps.)

The word "quoting" is commonly used to say "remove the special meaning from". The command line git add Documentation/*.txt invokes special behavior in the shell: bash replaces the parameter with some filenames. If you instead write git add Documentation/\*.txt, you have quoted the *: this process doesn't happen, and the parameter is passed to the program unchanged.

Another way to write this command would be git add 'Documentation/*.txt', which might be more obvious why it's commonly called "quoting". Using a backslash (or other) character to alter the meaning of a following character is sometimes called an escape. (And this probably originates from the use of ascii character 27 and/or the Esc key.)

It goes both ways sometimes: \* might cause the * to be treated as an ordinary character, but \n might assign special meaning to an otherwise ordinary n. It depends on the particular program.

Josh Lee
  • 171,072
  • 38
  • 269
  • 275
  • Thank you for your clarification, so does "git add Documentation/\*.txt" mean: add just "*.txt" file under Documentation to the index? But I saw the explanation of the example say: add *.txt "Under Documentation and its subdirectories". In my opinion: it adds that pattern of file which is directly under Documentation folder, but not in Documentation's subdirectories. Is it right? – IcyBrk Mar 22 '17 at 18:15
  • Yes. git will treat it as a pathspec, which has certain differences from a shell glob. https://git-scm.com/docs/gitglossary#gitglossary-aiddefpathspecapathspec https://stackoverflow.com/questions/27711924/whats-a-pathspec-in-the-git-command – Josh Lee Mar 23 '17 at 14:12
  • When I read your reply, I inferred that the explanation in the original documentation is correct, because git treats that pattern(Documentation/*.txt) as pathspec, and according to the link(https://git-scm.com/docs/gitglossary#gitglossary-aiddefpathspecapathspec) you gave, it said: "* and ? can match directory separators", so "Documentation/*.txt" in git could match Docmentation/john.txt or Documentation/users/tom.txt file. Is my thinking right? – IcyBrk Mar 23 '17 at 21:52
1

If you write git add Documentation/*.txt, the asterisk (*) is expanded by the shell, as explained in Josh Lee's answer. If you write git add Documentation/\*.txt the asterisk is expanded by git. The result is usually the same, however there are some edge cases. For example, if you have too many files in Documentation folder, the former option might fail, but the latter option would work.

1615903
  • 32,635
  • 12
  • 70
  • 99