git add * (asterisk) vs git add . (period)
Asked Answered
C

6

207

I have a question about adding files in git. I have found multiple stackoverflow questions about the difference between git add . and git add -a, git add --all, git add -A, etc. But I've been unable to find a place that explains what git add * does. I've even looked at the git add man page, but it didn't help. I've been using it in place of git add . and my co-worker asked me why. I didn't have an answer. I've just always used git add *.

Are git add . and git add * the same? Does one add changed files from the current directory only, while the other adds files from the current directory and subdirectories (recursively)?

There's a great chart listed on one of the other stack questions that shows the difference between git add -A git add . and git add -u, but it doesn't have git add *.

enter image description here

Note: I understand what it means to use the asterisk as a wildcard (add all files with a given extension). For example, git add *.html would add all files that have a .html extension (but ignore .css, .js, etc).

Thanks for the help!

Chattanooga answered 25/9, 2014 at 15:28 Comment(4)
Where's that chart from? I just tried git add . again, and it staged a deleted file no problem, unlike the X in that row would suggest.Vorticella
@Vorticella That image is from this answer and applies to older versions of git.Justiciary
Picture outdated! Git 2.x is different: i.stack.imgur.com/KwOLu.jpgOstracism
Note that if you use DOS-style CMD.EXE, you don't have a fancy shell that expands * for you, so this passes the literal * to Git. The result is slightly different than if you are using bash or some other Unix-like shell that does expand * for you.Bookstack
P
210

add * means add all files in the current directory, except for files whose name begin with a dot. This is your shell functionality and Git only ever receives a list of files.

add . has no special meaning in your shell, and thus Git adds the entire directory recursively, which is almost the same, but including files whose names begin with a dot.

Parable answered 25/9, 2014 at 15:37 Comment(11)
so git add . adds all files, folders, and subfolders, including .gitignore and anything else beginning with a dot, while git add * would add any files, folders, and subfolders, except those beginning with a dot? Is that accurate?Chattanooga
That is indeed correct. Also, git add * would still add files beginning with a dot if they are in a subdirectory.Parable
git add . also respects .gitignore, whereas git add * will throw an error if any non-dot-files are gitignored. Much better to use git add . than git add *.Eyeopener
Tested - not accurate in my case - git add * works for my .htacess files - any ideas why?Buxtehude
@Radmation, that's probably because you have no other files in the directory. Your shell does not expand '*' if there are no matching files. Then, git expands it on its own, with different rules, ignoring the leading dot.Parable
@Parable There are lots of files in that directory including an index.php page and many others as well as other directories.Buxtehude
@Radmation, then I have no further hypotheses without seeing your setup and investigating it manually. Sorry. :)Parable
Worth noting: if invoking Git on DOS/Windows from CMD.EXE, it's Git, not the shell, that expands the *. In this case Git will find dot-files.Bookstack
@Bookstack that's because Windows does not consider dot-files to be hidden. CMD will probably not include files with the hidden attribute, but I don't use it so I can't verify.Lassalle
@Thor84no: Git will find the dot-files even on a Linux system, if you quote the * to protect it from the shell. It's not a matter of the hidden bit, it's just that Git's compiled-in rules differ.Bookstack
The answer is a bit confusing, since the former method says "all files in the current directory" whereas the latter says "the entire directory recursively". One could think that the former (i.e. add * ) only adds files (not folders) in the first level, but not recursively.Hollar
P
44

* is not part of git - it's a wildcard interpreted by the shell. * expands to all the files in the current directory, and is only then passed to git, which adds them all. . is the current directory itself, and git adding it will add it and the all the files under it.

Pedanticism answered 25/9, 2014 at 15:34 Comment(4)
So would there every be a reason to use the asterisk? Is there any advantage to using it instead of a period? Or vice versa? I'm sure I saw it in a tutorial. I wouldn't have known to use it otherwise. I'm not much of a command line guy (as you've undoubtedly guessed).Chattanooga
* avoids hidden files (i.e., files that their name begins with a .). In any event, if you aren't adding specific files, I'd just use git add -u (or git add -A if you're creating new files).Pedanticism
Since you both answered my question I had trouble deciding who to give credit to. I chose Denis below because he has less rep than you. So I figured giving him the green check would benefit him more than it would benefit you. I hope that makes sense? But I really appreciate both explanations. Thanks!Chattanooga
for completeness, if you quote * it won't be expanded by the shell, but git will still interpret it and stage all files in current directory, including dot and deleted files.Adagietto
K
20
  • git add -A (--all) Adds everything, so that everything in your folder on disk is represented in the staging area

  • git add . Stages everything, but does not remove files that have been deleted from the disk

  • git add * Stages everything, but not files that begin with a dot & does not remove files that have been deleted from the disk

  • git add -u (--update) Stages only Modified Files, removes files that have been deleted from disk, does not add new

  • git add <file name 1> <file name 2> Adds only certain file(s)

Kaunas answered 23/5, 2020 at 6:47 Comment(1)
git add without flags does not ignore deleted files (anymore). This behavior changed quite a while ago. Also see here: git-scm.com/docs/git-add#Documentation/…Pangaro
C
11

For clarity, I put the answer in the table below:

enter image description here

Additional notes (inspired by the @reka18 comment):

Note 1. git add -A and git add -u commands performed without additional parameters would be additional refinement (subdirectory or mask indication for the file name) work in the range of the entire working directory (also if we execute the command in the working subdirectory of the directory).

Note 2. The . and * are respectively the directory path (current directory) and the wildcard, which clarify the path of the command. For example, if the git add . or git add * command is executed in some subdirectory of a working directory, then their action is only used within this subdirectory, not the entire working directory.

Note 3. The git add -A and git add -u commands can be further refined by adding a path or mask for files, for example, git add -A app/controllers or git add -u app\styles\*.

Classroom answered 16/3, 2018 at 20:20 Comment(3)
So as of Git v2.x git add -A and git add . are identical?Groyne
Thank you @reka18, for a very good question. It inspired me to complete my answer... The answer to your question: If you call it in the working directory, no, but if in a subdirectory, then yes (git add -A applies to the entire working directory and git add . always the current directory).Classroom
This is the best answer for me. The other ones are all a bit fuzzy, though boiling down to the same after all.Eponymy
R
8

Using the dot . in the shell usually means "the current directory".

When you use the asterisk * on a shell a feature called file-globbing is utilized. E.g. on bash the function glob() is doing just that. The manpage for glob (man 7 glob) states:

DESCRIPTION

Long ago, in UNIX V6, there was a program /etc/glob that would expand 
wildcard patterns.  Soon afterward this became a shell built-in.
These days there is also a library routine glob(3) that will perform this 
function for a user program.

Wildcard matching

A string is a wildcard pattern  if it contains one of the characters '?', '*' or '['. 

Globbing

Globbing is the operation that expands a wildcard pattern 
into the list of pathnames matching the pattern.

That means when you pass arguments to any program on the commandline that contain '?', '*'or '[', first globbing expands the wildcard pattern into a list of files and then gives these files as an argument to the program itself.

The difference in meaning between 'git add .' and 'git add *'is clearly described by Denis:

git add expects a list of files to be added. In the above example the shell expands * or . respectively and gives the result as a parameter to git add. Now the difference is that with git add . git will expand to the current directory whereas git add * triggers file globbing and such expands to all files and directories that do not start with a dot.

Rack answered 6/9, 2016 at 13:13 Comment(0)
H
6

In older versions of git, git add . did not remove deleted files from the index and therefore git add -A was recommended. This is NO LONGER THE CASE in recent versions of git. Now, so long as each commands is executed from the ROOT FOLDER of the working tree, git add . is EXACTLY THE SAME as git add -A. However, if git add . is run from a sub-folder then it ONLY updates the index for files in THAT folder and its subfolders recursively, whereas git add -A would still do ALL files in the working tree.

The documentation on this is not particularly clear, but I have validated the above information by experimenting directly with git version 2.42.0.windows.1.

Hutcheson answered 10/9, 2023 at 21:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.