git: Comment ignorer tous les fichiers non suivis présents?

131

Existe-t-il un moyen pratique d'ignorer tous les fichiers et dossiers non suivis dans un référentiel git?
(Je sais pour le .gitignore.)

Donc git status, fournirait à nouveau un résultat net.

sjas
la source
Ou vous pouvez ajouter un seul * à votre fichier .gitignore. :)
vilicvane
1
Juste un *ne sera probablement pas ce que vous voulez.
sjas
Surpris par tant de réponses incorrectes. -u noest faux. -unoest correct. -u noessaie de faire un état sur un fichier appelé no! Le non'est pas un argument pour -u. Pour forcer noà être interprété comme un argument de -u, il ne doit y avoir aucun espace. Pour tester cela, faites touch Invalidet comparez git status -uInvalidà git status -u Invalid.
Aaron McDaid

Réponses:

251

Comme déjà dit, pour exclure du statut il suffit d'utiliser:

git status -uno  # must be "-uno" , not "-u no"

Si vous souhaitez à la place ignorer définitivement les fichiers actuellement non suivis, vous pouvez, depuis la racine de votre projet, lancer:

git status --porcelain | grep '^??' | cut -c4- >> .gitignore

Chaque appel ultérieur à git statusignorera explicitement ces fichiers.

UPDATE : la commande ci-dessus a un inconvénient mineur: si vous n'avez pas .gitignoreencore de fichier, votre gitignore s'ignorera! Cela se produit car le fichier .gitignoreest créé avant l' git status --porcelainexécution de. Donc, si vous n'avez pas .gitignoreencore de fichier, je vous recommande d'utiliser:

echo "$(git status --porcelain | grep '^??' | cut -c4-)" > .gitignore

Cela crée un sous-shell qui se termine avant la création du .gitignorefichier.

EXPLICATION DE LA COMMANDE car je reçois beaucoup de votes (merci!) Je pense que je ferais mieux d'expliquer un peu la commande:

  • git status --porcelainest utilisé à la place de git status --shortparce que les états manuels "Donner la sortie dans un format facile à analyser pour les scripts. Ceci est similaire à la sortie courte, mais restera stable entre les versions de git et quelle que soit la configuration de l'utilisateur." Nous avons donc à la fois l'analyse et la stabilité;
  • grep '^??'filtre uniquement les lignes commençant par ??, qui, selon le manuel de l'état de git , correspondent aux fichiers non suivis;
  • cut -c4- supprime les 3 premiers caractères de chaque ligne, ce qui nous donne juste le chemin relatif vers le fichier non suivi;
  • les |symboles sont des tubes , qui passent la sortie de la commande précédente à l'entrée de la commande suivante;
  • les symboles >>et >sont des opérateurs de redirection , qui ajoutent la sortie de la commande précédente à un fichier ou écrasent / créent un nouveau fichier, respectivement.

UNE AUTRE VARIANTE pour ceux qui préfèrent utilisersed au lieu de grepet cut, voici une autre façon:

git status --porcelain | sed -n -e 's/^?? //p' >> .gitignore
Diego
la source
3
cut -c4- supprime les 4 premiers caractères de chaque ligne, ce qui nous donne juste le chemin relatif vers le fichier non suivi; No. -cmarque le début d'une liste de numéros de colonnes à couper. Et 4- sélectionne la ligne de la colonne 4 à la fin, ce qui coupe les colonnes 1 à 3. Ainsi, votre commande de coupe supprime en fait les 3 premiers caractères de chaque ligne. Si vous supprimez 4 caractères d'une ligne d'état git telle que celle de ce fichier ici:, ?? app/views/static_pages/contact.html.erbvous supprimez la première lettre de app. La commande est donc correcte, mais l'explication est erronée.
7
@ 7stud: merci, vous avez raison, j'en ai écrit 4 par erreur. J'ai corrigé la réponse.
Diego du
2
J'apprécie vraiment l'explication de la commande. Il est agréable de savoir ce que font les commandes aléatoires que j'ai copiées sur Internet et nous aide tous à apprendre à utiliser la ligne de commande et à mieux git.
Eric Fitting
1
-u none fonctionne pas pour moi. Mais le -unofait. J'ai mis à jour la réponse en conséquence. C'est une conception étrange pour git. Je suis sur git 1.7.1
Aaron McDaid
2
@AaronMcDaid: merci. Le changement est documenté ici et discuté ici
Diego
51

Si vous souhaitez ignorer définitivement ces fichiers, un moyen simple de les ajouter .gitignoreest:

  1. Passez à la racine de l'arbre git.
  2. git ls-files --others --exclude-standard >> .gitignore

Cela énumérera tous les fichiers dans des répertoires non suivis, ce qui peut ou non être ce que vous voulez.

poolie
la source
3
Pourquoi cela n'obtient-il pas autant de votes? Pas besoin de passer par 2 autres programmes!
JoelFan
4
@JoelFan: deux raisons: 1) celui-ci ne fonctionne qu'à partir de la racine du git , alors que celui qui est accepté fonctionne depuis chaque sous-répertoire, il vous suffit de modifier le .gitignorechemin de destination 2) si vous avez un répertoire non suivi, celui-ci liste chacun et chaque fichier qu'il contient, mais pas le répertoire non suivi lui-même (vous n'ignorerez donc pas le répertoire, et vous obtiendrez donc toujours des fichiers futurs signalés dans le répertoire comme non suivis, tandis que celui accepté ne répertorie que le répertoire, et non les fichiers non suivis à l'intérieur . C'est une question de ce que vous voulez faire, mais souvent vous voulez simplement ignorer tout le répertoire
Diego
1
Merci Poolie J'apprécie la différence de votre suggestion à cause des points mentionnés par @Diego J'ai commencé à travailler avec une bibliothèque de fichiers et de dossiers et je ne veux pas suivre / pousser les fichiers originaux. Je souhaite uniquement suivre les fichiers que j'ajoute ou reconstruit dans la bibliothèque. Ajouter les dossiers parents ignorerait tout. Cette / votre solution a ajouté les 1696 fichiers en un clin d'œil. xD
Chaos7703
Ceci peut également être réalisé en utilisant git config status.showUntrackedFiles no.
larsch
16

Je l'ai trouvé dans le manuel

Le paramètre mode est utilisé pour spécifier la gestion des fichiers non suivis. Il est facultatif: il vaut par défaut all, et s'il est spécifié, il doit être collé à l'option (par exemple -uno, mais pas -u no).

git status -uno

sjas
la source
39
Eh bien, si tout le monde voulait RTFM avant de publier, aucun de nous n'aurait jamais de représentant :-)
Jenny D
4

Deux manières:

utilisez l'argument "-uno" pour git-status. Voici un exemple:

[jenny@jenny_vmware:ft]$ git status
# On branch ft
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       foo
nothing added to commit but untracked files present (use "git add" to track)
[jenny@jenny_vmware:ft]$ git status -uno
# On branch ft
nothing to commit (working directory clean)

Ou vous pouvez ajouter les fichiers et les répertoires à .gitignore, auquel cas ils n'apparaîtront jamais.

Jenny D
la source
2
Une manière pratique d'éditer l' .gitignoreêtre git status | cat >> temp && vim temp. Ensuite, éditez le fichier afin que les premières lignes et la dernière ligne soient supprimées, ainsi que la fin #et l'espace blanc après. Alors cat temp >> .gitignore && rm temp. Dans le cas où aucun .gitignoren'était présent avant, mv temp .gitignorefera l'affaire. Des trucs moche mais mieux que de mettre à jour .gitignoremanuellement.
sjas
1
Cette réponse est incorrecte. La bonne réponse est -uno. Si vous utilisez -u no, cela équivaut à no -u- cela fera un état sur un fichier appelé no(qui n'existe probablement pas) et utilisera le -umode par défaut . c'est-à-dire qu'il équivaut àgit status no
Aaron McDaid
3

-u non'affiche pas non plus les fichiers non mis en scène. -unofonctionne comme vous le souhaitez et s'affiche sans mise en scène, mais se cache sans suivi.

Football
la source
1
Même ce n'est pas tout à fait correct. git status -u Xéquivaut à git status X -u( Xn'est pas un argument de -u). Ceci, à son tour, est équivalent à git status X(car -usans argument est la valeur par défaut -u). Par conséquent, il s'agit simplement d'un git-status sur fichier X. Donc, si Xest noil essaie simplement de faire un état git sur un fichier appelé no, que vous n'avez probablement pas
Aaron McDaid
2

Dans le cas où vous n'êtes pas sur Unix comme OS, cela fonctionne sur de Windows en utilisant PowerShell

git status --porcelain | ?{ $_ -match "^\?\? " }| %{$_ -replace "^\?\? ",""} | Add-Content .\.gitignore

Cependant, le .gitignorefichier doit avoir une nouvelle ligne vide, sinon il ajoutera du texte à la dernière ligne, peu importe s'il a du contenu.

Cela pourrait être une meilleure alternative:

$gi=gc .\.gitignore;$res=git status --porcelain|?{ $_ -match "^\?\? " }|%{ $_ -replace "^\?\? ", "" }; $res=$gi+$res; $res | Out-File .\.gitignore

vhanla
la source
1

Si vous avez beaucoup de fichiers non suivis et que vous ne voulez pas gitignoretous les " " tous, notez que, depuis git 1.8.3 (22 avril 2013) , git statusmentionnera le --untracked-files=nomême si vous n'avez pas ajouté cette option dans le première place!

" git status" suggère aux utilisateurs de se pencher sur l'utilisation de l' --untracked=nooption lorsque cela prend trop de temps.

VonC
la source
0

Je suis venu ici pour essayer de résoudre un problème légèrement différent. Peut-être que cela sera utile à quelqu'un d'autre:

Je crée une nouvelle branche feature-a. dans le cadre de cette branche, je crée de nouveaux répertoires et je dois modifier .gitignore pour supprimer certains d'entre eux. Cela se produit souvent lors de l'ajout de nouveaux outils à un projet qui créent divers dossiers de cache. .serverless, .terraformEtc.

Avant que je ne sois prêt à fusionner cela en maître, j'ai quelque chose d'autre à venir, alors je vérifie à masternouveau, mais je git statusrécupère maintenant ces dossiers supprimés, car le .gitignore n'a pas encore été fusionné.

La réponse ici est en fait simple, même si j'ai dû trouver ce blog pour la comprendre:

Extrayez simplement le fichier .gitignore de la feature-abranche

git checkout feature-a -- feature-a/.gitignore
git add .
git commit -m "update .gitignore from feature-a branch"
William George
la source