web-dev-qa-db-fra.com

fichiers non suivis non affichés dans l'état git

J'ai un projet avec la structure de dossiers suivante:

Tous les fichiers du projet se trouvent dans le dossier base_fldr. J'ai également quelques dossiers à l'intérieur de base_fldr appelés sub_fldr1 et sub_fldr2. Ces sous-dossiers contiennent également certains fichiers.

Si je modifie l'un des fichiers à l'intérieur de mon base_fldr ou base_fldr\sub_fldr\alors l'état de git les montre comme modifiés. De plus, si j'ajoute un nouveau fichier à base_fldr, git status l'affichera comme fichier non suivi.

Mon problème est que si j'ajoute un nouveau fichier dans base_fldr\sub_fldr\alors l'état git n'affiche pas le fichier comme non suivi. Il ne donnera même aucune information sur le fichier.

Le fichier ou son extension n'est PAS dans ma liste .gitignore. J'ai également essayé git add sub_fldr\file_name mais ni cela n'a donné d'erreur ni l'ajout du fichier à l'index.

Une idée de ce qui se passe ici? Merci!

29
kriver

J'ai compris ce qui n'allait pas. Fondamentalement, la première ligne de mon fichier .gitignore est "* /". Cela provoque l'ignorance de tout fichier ajouté au sous-répertoire par la commande git status. Mais le plus drôle était que si je modifiais des fichiers dans le sous-dossier, l'état de git les montrait correctement comme modifiés car le fichier était déjà dans le référentiel git, mais ignorait les nouveaux fichiers dans le sous-dossier.

J'ai résolu mon problème en supprimant la ligne dans le fichier .gitignore pour ne pas ignorer les modifications dans les sous-dossiers, puis j'ai ajouté les nouveaux fichiers à indexer, puis j'ai à nouveau ajouté la ligne dans .gitignore afin qu'il ignore tous les fichiers générés dans les sous-dossiers.

Merci à tous pour les réponses.

23
kriver

Cela est probablement dû au fait que votre répertoire base_fldr\sub_fldr\n'est pas suivi, si vous exécutez:

git add base_fldr\sub_fldr\

À partir de votre racine de copie de travail, il ajoutera automatiquement le répertoire et les autres fichiers et répertoires de ce répertoire.

Par défaut, git n'affichera pas les fichiers dans les répertoires qui ne sont pas suivis.

15
Highway of Life

J'ai rencontré un problème similaire avec des fichiers suivis manquants. Tout en essayant de gérer des versions modifiées localement des fichiers suivis sans avoir à éviter constamment les validations accidentelles, j'ai exécuté ce qui suit:

git update-index --assume-unchanged my-tracked-file-that-is-awol

J'ai fini par abandonner cette idée, mais j'ai oublié d'annuler la commande, donc les modifications ultérieures de ce fichier et d'autres fichiers --assume-inchanged étaient complètement manquantes dans:

git status -u --ignored

Il m'a fallu un certain temps pour comprendre ce qui se passait, mais j'ai simplement dû inverser la commande avec:

git update-index --no-assume-unchanged my-tracked-file-that-is-awol
15
mveerman

As tu un .git sous-répertoire dans votre sub_fldr répertoire? Git peut penser que vous essayez d'utiliser les sous-modules .

8
Greg Hewgill

Pour déboguer un problème comme celui-ci, voyez si votre .gitignore le fichier est le coupable en observant les deux sorties suivantes

Voir https://git-scm.com/docs/git-ls-files

  1. git ls-files --other --directory --exclude-standard

Cela montrera tous les fichiers non suivis, tout en respectant le .gitignore fichier.

  1. git ls-files --other --directory

Cela montrera tous les fichiers non suivis, sans obéir au .gitignore fichier.

Quels que soient les fichiers présents dans la sortie de 2, mais ne sont pas présents dans la sortie de 1, ne sont pas affichés en mode non suivi en raison d'un indicateur dans votre .gitignore fichier

5
user13107

Voici une autre cause du comportement décrit dans cette question (la liste des fichiers non suivis de git status n'inclut pas de fichier non suivi dans un sous-dossier). Si le fichier n'est pas suivi à cause d'un fichier .gitignore dans le sous-dossier alors le fichier ne sera pas inclus dans la liste des fichiers non suivis de git status.

2
user969350

Depuis 2011, cela a été corrigé pour la première fois avec Git v1.8.3-rc0 (avril 2013).
Il corrige une poignée de problèmes dans le code pour parcourir l'arborescence de travail pour trouver des fichiers non suivis et/ou ignorés, nettoie et optimise le chemin de code en général.

Voir commit 0aaf62b , commit defd7c7 , commit 8aaf8d7 , commit b07bc8c , commit 95c6f27 , commit 6cd5c58 , commit 46aa2f9 , commit 5bd8e2d , commit be8a84c , commit c94ab01 , commit 184d2a8 , commit 0104c9e , commit 289ff55 , commit 560bb7a (15 avril 2013) par Karsten Blees (kblees) .
(Fusionné par Junio ​​C Hamano - gitster - in commit 7093d2c , 23 avril 2013)

dir.c : faire fonctionner 'git-status --ignored' dans les principaux répertoires

Signé par: Karsten Blees

' git status --ignored path/ ' ne répertorie pas les fichiers et répertoires ignorés dans 'path' si un composant de 'path' est classé comme non suivi.

Désactivez l'indicateur DIR_SHOW_OTHER_DIRECTORIES Lorsque vous parcourez les principaux répertoires. Cela empêche treat_leading_path() avec l'indicateur DIR_SHOW_IGNORED D'abandonner dans le répertoire non suivi de niveau supérieur.

En tant qu'effet secondaire, cela élimine également une analyse de répertoire récursive par niveau de répertoire principal, car treat_directory() ne peut plus appeler read_directory_recursive() lorsqu'elle est appelée à partir de treat_leading_path().


Mais, 6 ans plus tard (fin 2019), avec Git 2.25 (Q1 2020), un assortiment de correctifs pour l'API de traversée de répertoire ... revenez sur ce correctif vu ci-dessus et réinstallez-le.

Voir commit 6836d2f (20 décembre 2019) par Junio ​​C Hamano (gitster) .
Voir commit c847dfa , commit 777b42 , commit b9670c1 (19 décembre 2019), et commit c5c4edd =, commit 072a231 , commit 2f5d384 , commit a2b1336 , commit 452efd1 (10 décembre 2019) par Elijah Newren (newren) .
(Fusionné par Junio ​​C Hamano - gitster - in commit d2189a7 , 25 décembre 2019)

Revert "dir.c : faire fonctionner 'git-status --ignored' Dans les principaux répertoires "

Signé par: Elijah Newren

Valider be8a84c52669 ("[ Dir.c ](https: //Github.com/git/git/blob/a2b13367fe55bdeb10862f41aff3e2446b63e171/dir.c): faire 'git-status --ignored 'Travailler dans les principaux répertoires ", 2013-04-15, Git v1.8.3-rc0 - merge ) a noté que

git status --ignored <SOMEPATH>

ne répertorierait pas les fichiers et répertoires ignorés dans <SOMEPATH> si <SOMEPATH> n'était pas suivi, et modifiait le comportement pour le faire apparaître.

Cependant, il l'a fait via un hack qui a cassé la cohérence; il afficherait les chemins sous <SOMEPATH> différemment d'un simple

git status --ignored | grep <SOMEPATH>

leur montrerait.

Un correctif correct est légèrement plus impliqué et compliqué légèrement par ce piratage, nous revenons donc à ce commit (mais gardons les versions corrigées des testcases) et corrigerons plus tard le bogue d'origine avec un patch ultérieur.

Un peu d'histoire peut être utile:

Un cas très, très similaire au commit que nous rétablissons a été soulevé dans commit 48ffef966c76 ("ls-files: Correction de l'optimisation pathspec excessive", 2010-01-08, Git v1.7.0- rc0 - fusionner ); mais en fait, il est allé dans la direction opposée.

Dans cet engagement, il a mentionné comment

git ls-files -o --exclude-standard t/

utilisé pour afficher les fichiers non suivis sous t/ même lorsque t/ a été ignoré, puis a changé le comportement pour ne plus afficher les fichiers non suivis dans un répertoire ignoré.

Plus important encore, ce commit a envisagé de conserver ce comportement, mais a noté qu'il serait incompatible avec le comportement lorsque plusieurs spécifications de chemin d'accès étaient spécifiées et donc rejeté.

La raison de cette incohérence totale lorsqu'une spécification de chemin est spécifiée par rapport à zéro ou deux est parce que les préfixes communs de spécification de chemin sont envoyés via un ensemble de contrôles différent (dans treat_leading_path()) que la traversée normale de fichiers/répertoires (ceux qui passent par read_directory_recursive() et treat_path()).

En tant que tel, par souci de cohérence, il faut vérifier que les deux trajets codés produisent le même résultat.

Revert commit be8a84c526691667fc04a8241d93a3de1de298ab , sauf qu'au lieu de supprimer le cas de test qu'il a ajouté, modifiez-le pour vérifier le comportement correct et cohérent.

Et:

dir : correction des vérifications sur le répertoire de préfixe commun

Signé par: Elijah Newren

Il y a de nombreuses années, la logique de traversée de répertoire avait une optimisation qui serait toujours récursive dans n'importe quel répertoire qui était un préfixe commun de tous les pathspecs sans parcourir les répertoires de tête pour descendre dans le répertoire souhaité.

Donc,

git ls-files -o .git/                        # case A

remarquerait que .git/ était un préfixe commun de tous les pathspec (car c'est le seul pathspec répertorié), puis le traverser et commencer à afficher les fichiers inconnus dans ce répertoire.

Malheureusement, .git/ N'est pas un répertoire dans lequel nous devrions parcourir, ce qui a rendu cette optimisation problématique.

Cela a également affecté des cas tels que:

git ls-files -o --exclude-standard t/        # case B

t/ était dans le fichier .gitignore et n'est donc pas intéressant et ne devrait pas être récursif.

Elle a également affecté des cas tels que:

git ls-files -o --directory untracked_dir/   # case C

untracked_dir/ est en effet non suivi et donc intéressant, mais le drapeau --directory signifie que nous voulons seulement montrer le répertoire lui-même, ne pas y rentrer et commencer à lister les fichiers non suivis en dessous.

La classe B de bogues a été notée et corrigée dans les validations 16e2cfa9099("read_directory(): Division supplémentaire treat_path() ", 2010-01-08) et 48ffef966c76 ("ls-files: Correction de l'optimisation de pathspec excessive", 2010-01-08, Git v1.7.0-rc0 - fusion ), l'idée étant que nous voulions d'abord pour vérifier si le préfixe commun était intéressant.

L'ancien patch notait que treat_path() ne pouvait pas être utilisé lors de la vérification du préfixe commun car treat_path() nécessite un dir_entry() et nous n'avons pas lu de répertoires à ce stade nous vérifions le préfixe commun.

Ainsi, ce patch a divisé treat_one_path() en treat_path().

Ce dernier correctif a ensuite créé une nouvelle treat_leading_path() qui a dupliqué à la main les bits de treat_path() qui ne pouvaient pas être décomposés et a ensuite appelé treat_one_path() pour le reste.

Il y avait trois problèmes avec cette approche:

  • La logique dupliquée dans treat_leading_path() a accidentellement raté la vérification des chemins spéciaux (tels que is_dot_or_dotdot Et correspondant à ".git"), Ce qui fait que les types de bogues du cas A continuent d'être un problème.
  • La logique treat_leading_path() supposait que nous devions traverser n'importe quoi où path_treatment n'était pas path_none, c'est-à-dire qu'elle perpétuait les types de bogues de classe C.
  • Cela signifiait que nous avions une logique divisée qui devait rester synchronisée, ce qui risquait que les gens introduisent de nouvelles incohérences (comme dans commit be8a84c52669 , que nous avons inversé plus tôt dans cette série, ou dans commit df5bcdf83ae que nous corrigerons dans un commit ultérieur)

Corrigez la plupart de ces problèmes en faisant que treat_leading_path() non seulement boucle sur chaque composant de chemin principal, mais appelle treat_path() directement sur chacun.

Pour ce faire, nous devons créer un dir_entry, Synthétique mais qui ne prend que quelques lignes.

Ensuite, faites attention au résultat path_treatment Que nous obtenons de treat_path() et ne traitons pas tout de même path_excluded,path_untracked, Et path_recurse comme path_recurse.

0
VonC