web-dev-qa-db-fra.com

Comment Git gère-t-il les liens symboliques?

Si j'ai un fichier ou un répertoire qui est un lien symbolique et que je l'envoie dans un référentiel Git, que se passe-t-il?

Je suppose qu’il reste en tant que lien symbolique jusqu’à ce que le fichier soit supprimé. Si vous extrayez le fichier d’une ancienne version, il crée simplement un fichier normal.

Que fait-il lorsque je supprime le fichier auquel il fait référence? Est-ce qu'il commet juste le lien qui pend?

1480
Alex

Git ne stocke que le contenu du lien (c'est-à-dire le chemin de l'objet du système de fichiers auquel il est lié) dans un "blob", comme il le ferait pour un fichier normal. Il enregistre ensuite le nom, le mode et le type (y compris le fait qu’il s’agit d’un lien symbolique) dans l’objet d’arborescence qui représente son répertoire contenant.

Lorsque vous extrayez une arborescence contenant le lien, l'objet est restauré sous la forme d'un lien symbolique, que l'objet du système de fichiers cible existe ou non.

Si vous supprimez le fichier référencé par le lien symbolique, cela n’affectera en aucune façon le lien symbolique contrôlé par Git. Vous aurez une référence en suspens. Il appartient à l'utilisateur de supprimer ou de modifier le lien pour indiquer un élément valide, le cas échéant.

1241
CB Bailey

TL; DR: les données référencées par le lien symbolique ne sont pas stockées dans le référentiel.


Pour savoir ce que fait Git avec un fichier, voyez ce que cela fait lorsque vous l'ajoutez à l'index. L'index est comme un pré-commit. Avec l'index validé, vous pouvez utiliser _git checkout_ pour ramener tout ce qui se trouvait dans l'index dans le répertoire de travail. Alors, que fait Git lorsque vous ajoutez un lien symbolique à l'index?

Pour le savoir, commencez par créer un lien symbolique:

_$ ln -s /path/referenced/by/symlink symlink
_

Git ne connaît pas encore ce fichier. _git ls-files_ vous permet d'inspecter votre index (_-s_ imprime stat- comme une sortie):

_$ git ls-files -s ./symlink
[nothing]
_

Ajoutez maintenant le contenu du lien symbolique au magasin d'objets Git en l'ajoutant à l'index. Lorsque vous ajoutez un fichier à l'index, Git en stocke le contenu dans le magasin d'objets Git.

_$ git add ./symlink
_

Alors, qu'est-ce qui a été ajouté?

_$ git ls-files -s ./symlink
120000 1596f9db1b9610f238b78dd168ae33faa2dec15c 0       symlink
_

Le hachage est une référence à l'objet compressé créé dans le magasin d'objets Git. Vous pouvez examiner cet objet si vous regardez dans _.git/objects/15/96f9db1b9610f238b78dd168ae33faa2dec15c_ à la racine de votre référentiel. Ceci est le fichier que Git stocke dans le référentiel, que vous pourrez extraire ultérieurement. Si vous examinez ce fichier, vous verrez qu'il est très petit. . Il ne stocke pas le contenu du fichier lié.

(Remarque: _120000_ est le mode répertorié dans la sortie _ls-files_. Ce serait quelque chose comme _100644_ pour un fichier normal.)

Mais que fait Git avec cet objet lorsque vous extrayez-le du référentiel dans votre système de fichiers? Cela dépend de la configuration _core.symlinks_. De man git-config :

core.symlinks

Si la valeur est false, les liens symboliques sont extraits en tant que petits fichiers simples contenant le texte du lien.

Ainsi, avec un lien symbolique dans le référentiel, lors de la validation, vous obtenez un fichier texte avec une référence à un chemin de système de fichiers complet ou un lien symbolique approprié, en fonction de la valeur de la configuration _core.symlinks_.

Dans tous les cas, les données référencées par le lien symbolique ne sont pas stockées dans le référentiel.

213
Dmitry Minkovsky

"Note de l'éditeur": Ce message peut contenir des informations obsolètes. S'il vous plaît voir les commentaires et cette question concernant les changements dans Git depuis 1.6.1.

Répertoires dont le lien est:

Il est important de noter ce qui se produit lorsqu'un répertoire est un lien symbolique. Toute extraction de Git avec une mise à jour supprime le lien et en fait un répertoire normal. C'est ce que j'ai appris de manière difficile. Quelques idées ici et ici.

Exemple

Avant

_ ls -l
 lrwxrwxrwx 1 admin adm   29 Sep 30 15:28 src/somedir -> /mnt/somedir
_

git add/commit/Push

_It remains the same
_

Après _git pull_ ET certaines mises à jour trouvées

_ drwxrwsr-x 2 admin adm 4096 Oct  2 05:54 src/somedir
_
146
Shekhar