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!
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.
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.
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
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
git ls-files --other --directory --exclude-standard
Cela montrera tous les fichiers non suivis, tout en respectant le .gitignore
fichier.
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
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.
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épertoiresSigné 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êchetreat_leading_path()
avec l'indicateurDIR_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 appelerread_directory_recursive()
lorsqu'elle est appelée à partir detreat_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é quegit 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 simplegit 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 lorsquet/
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 parread_directory_recursive()
ettreat_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 communSigné 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
où
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
où
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émentairetreat_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 cartreat_path()
nécessite undir_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()
entreat_path()
.Ce dernier correctif a ensuite créé une nouvelle
treat_leading_path()
qui a dupliqué à la main les bits detreat_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 queis_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 appelletreat_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 detreat_path()
et ne traitons pas tout de mêmepath_excluded,
path_untracked,
Etpath_recurse
commepath_recurse
.