git add * (astérisque) vs git add. (période)

130

Je suis nouveau dans git et j'ai une question sur l'ajout de fichiers dans git. J'ai trouvé plusieurs questions stackoverflow sur la différence entre git add .et git add -a, git add --all, git add -A, etc. Mais j'ai été incapable de trouver un endroit qui explique ce git add *fait. J'ai même regardé la page de manuel de git add , mais cela n'a pas aidé. Je l'ai utilisé à la place de git add .et mon collègue m'a demandé pourquoi. Je n'avais pas de réponse. J'ai juste toujours utilisé git add *.

Sont git add .et git add *les mêmes? Est-ce que l'un ajoute uniquement les fichiers modifiés du répertoire courant, tandis que l'autre ajoute des fichiers du répertoire courant et des sous-répertoires (récursivement)?

Il existe un excellent graphique répertorié sur l'une des autres questions de la pile qui montre la différence entre git add -A git add .et git add -u, mais ce n'est pas le cas git add *.

entrez la description de l'image ici

Remarque: je comprends ce que signifie utiliser l'astérisque comme caractère générique (ajouter tous les fichiers avec une extension donnée). Par exemple, git add *.htmlajouterait tous les fichiers qui ont une .htmlextension (mais ne tiennent pas compte .css, .jsetc.).

Merci pour l'aide!

Tyler Youngblood
la source
1
D'où vient ce graphique? J'ai juste essayé à git add .nouveau, et il a mis en scène un fichier supprimé sans problème, contrairement Xà ce que suggère cette ligne.
David
@David Cette image provient de cette réponse et s'applique aux anciennes versions de git.
jerry
4
Image dépassée! Git 2.x est différent: i.stack.imgur.com/KwOLu.jpg
Hannes Schneidermayer

Réponses:

132

add *signifie ajouter tous les fichiers dans le répertoire courant, à l'exception des fichiers dont le nom commence par un point. Il s'agit de votre fonctionnalité shell et Git ne reçoit jamais qu'une liste de fichiers.

add . n'a pas de signification particulière dans votre shell, et donc Git ajoute le répertoire entier de manière récursive, ce qui est presque le même, mais y compris les fichiers dont les noms commencent par un point.

Denis
la source
6
git add .ajoute donc tous les fichiers, dossiers et sous-dossiers, y compris .gitignore et tout ce qui commence par un point, tandis git add *que ajouterait tous les fichiers, dossiers et sous-dossiers, sauf ceux commençant par un point? Est-ce exact?
Tyler Youngblood
9
C'est en effet correct. De plus, git add *ajouterait toujours des fichiers commençant par un point s'ils se trouvent dans un sous-répertoire.
Denis
4
git add .respecte également .gitignore, alors que générera git add *une erreur si des fichiers non-point sont gitignored. Bien mieux utiliser git add .que git add *.
rosuav
2
À noter: si vous invoquez Git sous DOS / Windows à partir de CMD.EXE, c'est Git , pas le shell, qui étend le fichier *. Dans ce cas, Git trouvera des fichiers dot.
torek
2
@ Thor84no: Git trouvera les fichiers dot même sur un système Linux, si vous citez le *pour le protéger du shell. Ce n'est pas une question de partie cachée, c'est juste que les règles compilées de Git diffèrent.
torek
30

*ne fait pas partie de git - c'est un caractère générique interprété par le shell. *s'étend à tous les fichiers du répertoire courant, et n'est ensuite passé à git, qui addles tous. .est le répertoire courant lui-même, et git addil l'ajoutera ainsi que tous les fichiers qu'il contient.

Mureinik
la source
1
Y aurait-il donc une raison d'utiliser l'astérisque? Y a-t-il un avantage à l'utiliser au lieu d'une période? Ou vice versa? Je suis sûr que je l'ai vu dans un tutoriel. Je n'aurais pas su l'utiliser autrement. Je ne suis pas vraiment un gars de la ligne de commande (comme vous l'avez sans doute deviné).
Tyler Youngblood
5
*évite les fichiers cachés (c'est-à-dire les fichiers dont le nom commence par a .). Dans tous les cas, si vous n'ajoutez pas de fichiers spécifiques, j'utiliserais simplement git add -u(ou git add -Asi vous créez de nouveaux fichiers).
Mureinik
3
Puisque vous avez tous les deux répondu à ma question, j'ai eu du mal à décider à qui donner du crédit. J'ai choisi Denis ci-dessous car il a moins de représentants que vous. J'ai donc pensé que lui donner le chèque vert lui profiterait plus que vous. J'espère que cela à du sens? Mais j'apprécie vraiment les deux explications. Merci!
Tyler Youngblood
7

Utiliser le point . dans le shell signifie généralement "le répertoire courant".

Lorsque vous utilisez l'astérisque *sur un shell, une fonction appelée file-globbingest utilisée. Par exemple, sur bash, la fonction glob()fait exactement cela. La page de manuel de glob ( man 7 glob) indique:

LA 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.

Correspondance générique

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.

Cela signifie que lorsque vous transmettez des arguments à n'importe quel programme sur la ligne de commande qui contient '?', '*'ou '[', le premier globbing développe le modèle générique dans une liste de fichiers, puis donne ces fichiers comme argument au programme lui-même.

La différence de sens entre 'git add .'et 'git add *'est clairement décrite par Denis :

git adds'attend à ce qu'une liste de fichiers soit ajoutée. Dans l'exemple ci-dessus, le shell se développe *ou .respectivement et donne le résultat en tant que paramètre à git add. Maintenant, la différence est qu'avec git add .git s'étendra vers le répertoire courant alors que git add *déclenche la globalisation des fichiers et que cela s'étend à tous les fichiers et répertoires qui ne commencent pas par un point.

codage
la source
5

Pour plus de clarté, j'ai mis la réponse dans le tableau ci-dessous:

entrez la description de l'image ici

Notes supplémentaires (inspirées du commentaire @ reka18):

Remarque 1. git add -A et les git add -ucommandes exécutées sans paramètres supplémentaires seraient un raffinement supplémentaire (sous-répertoire ou indication de masque pour le nom de fichier) dans la plage de tout le répertoire de travail (également si nous exécutons la commande dans le sous-répertoire de travail du répertoire).

Remarque 2. Les .et *sont respectivement le chemin du répertoire (répertoire courant) et le caractère générique, qui clarifient le chemin de la commande. Par exemple, si la commande git add .ou git add *est exécutée dans un sous-répertoire d'un répertoire de travail, alors leur action n'est utilisée que dans ce sous-répertoire, pas dans tout le répertoire de travail.

Remarque 3. Les commandes git add -Aet git add -upeuvent être affinées davantage en ajoutant un chemin ou un masque pour les fichiers, par exemple, git add -A app/controllersou git add -u app\styles\*.

simhumileco
la source
2
Donc, à partir de Git v2.x git add -Aet git add .sont identiques?
reka18
Merci @ reka18, pour une très bonne question. Cela m'a inspiré pour compléter ma réponse ... La réponse à votre question: si vous l'appelez dans le répertoire de travail, non, mais si dans un sous-répertoire, alors oui ( git add -As'applique à tout le répertoire de travail et git add .toujours au répertoire courant).
simhumileco
2
  • git add -A (--all) Ajoute tout, de sorte que tout ce qui se trouve dans votre dossier sur le disque soit représenté dans la zone de préparation

  • git add . Met tout en scène, mais ne supprime pas les fichiers qui ont été supprimés du disque

  • git add * Met tout en scène, mais pas les fichiers qui commencent par un point et ne supprime pas les fichiers qui ont été supprimés du disque

  • git add -u (--update) Étapes uniquement les fichiers modifiés, supprime les fichiers qui ont été supprimés du disque, n'ajoute pas de nouveaux

  • git add <file name 1> <file name 2> Ajoute uniquement certains fichiers

Steffen
la source