109 votes

Git et hard links

Considérant que Git ne reconnaît pas les liens symboliques qui pointent en dehors du dépôt, y a-t-il un problème à utiliser des liens durs ?

Git pourrait-il les briser ? Pouvez-vous m'indiquer des informations détaillées ?

2 votes

Qu'essayez-vous de faire et pourquoi ? Un lien dur n'est pas différent d'un fichier normal. Si vous deviez tirer une nouvelle version d'un autre dépôt, elle écraserait celle que vous avez - quel est l'intérêt de faire un lien vers quelque chose en dehors du dépôt ?

3 votes

Git reconnaîtra les liens symboliques qui pointent vers un chemin en dehors du référentiel.

0 votes

Non mipadi, le seul moyen est de déplacer les fichiers dans le repo et les liens symjboliques dans leur emplacement "réel".

93voto

Jakub Narębski Points 87537

L'objet 'tree', qui représente les répertoires dans Git, stocke les noms de fichiers et (sous-ensemble de) permissions. Il ne stocke pas le numéro d'inode (ou tout autre type d'identifiant de fichier). Par conséquent, liens solides ne peut pas être représenté dans git du moins pas sans des outils tiers tels que métastore o git-cache-meta (et je ne suis pas sûr que ce soit possible même avec ces outils).

Git essaie de ne pas toucher aux fichiers qu'il n'a pas besoin de mettre à jour, mais vous devez prendre en compte le fait que git n'essaie pas de préserver les hardlinks, donc ils peuvent être cassés par git.


À propos de liens symboliques pointant en dehors du référentiel git n'a aucun problème avec eux et devrait préserver le contenu des liens symboliques... mais l'utilité de tels liens me semble douteuse, car le fait que ces liens symboliques soient rompus ou non dépend de la disposition du système de fichiers. à l'extérieur de dépôt git, et non sous le contrôle de git.

4 votes

Les liens symétriques vers des chemins en dehors du repo peuvent être utiles. Je les ai utilisés dans des applications web pour pointer vers des bases de données ou des fichiers multimédias non suivis par le dépôt. De cette façon, le fichier de configuration de l'application web peut pointer vers un chemin statique, mais l'emplacement réel de ce chemin peut varier entre les environnements de développement local et de serveur.

0 votes

@mipadi : BTW. Le gitweb moderne a un cas spécial pour afficher les liens symboliques menant à la normalisation en dehors du dépôt.

6 votes

Oui, les liens symboliques en dehors du dépôt sont corrects. Je les ai utilisés pour pointer vers un répertoire de données massif dont je n'avais pas besoin (ou que je ne voulais pas) versionner. En général, j'utilise des liens relatifs. Dans ce cas, le repo et le répertoire de données devaient être situés l'un à côté de l'autre dans un répertoire parent. Vous pouvez faire des trucs étonnants avec un lien symbolique vers ../foo.

23voto

Niloct Points 2290

J'ai découvert que, en utilisant des crochets, vous pouvez capturer le git pull événement (quand il y a quelque chose à tirer...) en écrivant le gestionnaire d'événement script pour .git/hooks/post-merge archivo.

D'abord, vous devez chmod +x il.

Ensuite, mettez le ln à l'intérieur pour recréer des liens durs à chaque tirage. Neat huh !

Ça marche, j'en avais juste besoin pour mon projet et ls -i montre que les fichiers ont été automatiquement liés après pull .


Mon exemple de .git/hooks/post-merge :

#!/bin/sh
ln -f $GIT_DIR/../apresentacao/apresentacao.pdf $GIT_DIR/../capa/apresentacao.pdf
ln -f $GIT_DIR/../avaliacoesMono/avaliacao_monografias_2011_Nilo.pdf $GIT_DIR/../capa/avaliacoes.pdf
ln -f $GIT_DIR/../posters/poster_Nilo_sci.pdf $GIT_DIR/../capa/poster.pdf
ln -f $GIT_DIR/../monografia/monografia_Nilo.pdf $GIT_DIR/../capa/monografia_Nilo.pdf

IMPORTANT : Comme vous pouvez le constater, le chemin d'accès à tout fichier de votre référentiel doit commencer par $GIT_DIR puis ajoutez le chemin relatif partiel au fichier.

Egalement important : -f est nécessaire, car vous recréez le fichier de destination.

EDITAR

Les clients git modernes semblent prendre en charge les liens symboliques et les liens durs à l'intérieur du dépôt de manière naturelle, même lorsqu'ils sont poussés vers un emplacement distant puis clonés à partir de celui-ci. Je n'ai plus jamais eu besoin de faire des liens en dehors d'un dépôt git cependant...

$ mkdir tmp
$ cd tmp
$ git --version
git version 2.24.3 (Apple Git-128)
$ git init .
Initialized empty Git repository in /Users/teixeira/tmp/.git/
$ mkdir x
$ cd x
$ echo 123 > original
$ cat original
123
$ cd ..
$ ln -s x/original symlink
$ cat symlink
123
$ ln x/original hardlink
$ cat hardlink
123
$ git add .
$ git commit -m 'Symlink and hardlink commit'
[master (root-commit) 8df3134] Symlink and hardlink commit
 3 files changed, 3 insertions(+)
 create mode 100644 hardlink
 create mode 120000 symlink
 create mode 100644 x/original

Clonage à partir du dépôt git local

$ cd
$ git clone tmp/ teste_tmp
Cloning into 'teste_tmp'...
done.
$ cd teste_tmp/
$ ls
hardlink  symlink  x
$ cat symlink
123
$ cat hardlink
123

Clonage à partir d'un référentiel distant

$ cd ~/tmp
$ git remote add origin https://github.com/myUser/myRepo.git
$ git push origin master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (5/5), 361 bytes | 361.00 KiB/s, done.
Total 5 (delta 0), reused 0 (delta 0)
To https://github.com/myUser/myRepo.git
 + 964dfce...8df3134 master -> master
$ cd ../
$ git clone https://github.com/myUser/myRepo.git
Cloning into 'myRepo'...
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 5 (delta 0), reused 5 (delta 0), pack-reused 0
Unpacking objects: 100% (5/5), done.
$ cd myRepo/
$ cat symlink
123
$ cat hardlink
123

https://github.com/mokacoding/symlinks souligne également une chose importante : les liens symboliques doivent être définis de manière relative.

12 votes

Il semble donc que chaque fois que vous ajoutez un lien dur à votre repo, vous devez également ajouter manuellement une ligne à votre crochet post-fusion script. Ce serait bien si votre hook pre-commit rendait cela entièrement automatique - en détectant les liens durs (et symboliques) dans votre commit et en écrivant les lignes appropriées dans votre fichier post-fusion. Git n'aurait pas à stocker les informations d'inode dans le repo, il en stockerait des morceaux dans les hooks ! Mais quel désordre si le fichier lié était suivi dans un autre repo git... une modification du fichier à un endroit se propagerait-elle sans problème à l'autre repo ? Des fusions perpétuelles avec une boucle circulaire de push/pull ?

0 votes

Une approche intelligente, mais il est regrettable que Git ne suive pas les liens durs, même en les représentant potentiellement comme des copies sur les systèmes de fichiers qui ne supportent pas les liens durs.

1 votes

@hobs désolé d'avoir mis 7 ans à répondre :) Vous avez raison. Si un fichier en dehors du référentiel était lié par 2 référentiels différents, je pense que changer un lien dans un référentiel ne serait tout simplement pas vu dans l'autre.

8voto

VonC Points 414372

De ce problème de msysgit

Les points de jonction ne sont pas des liens symboliques ; par conséquent, les liens symboliques ne sont tout simplement pas supportés dans msysGit. simplement non supportés dans msysGit.

Aussi, les liens durs n'ont jamais été suivis par Git .

La question était orientée vers Windows (puisqu'il s'agit de msysgit) et le débat sur le support potentiel de symlink.
Mais le commentaire sur la liaison dure concerne Git en général.

2voto

xce_git Points 11

Google "git preserve hard links" et il montre que git ne sait pas comment préserver la structure des liens durs (AFAIK), peut-être à dessein.

Mes projets Web utilisent les liens physiques comme suit :

www/products/index.php
www/products/dell_latitude_id577/index.php #(hard linked to above)
www/products/dell_inspiron_id323/index.php #(hard linked again to above)

me@server:www/products$ ls -l index.php
-rwxr-xr-x 3 me me 1958 Aug 22 22:10 index.php*

Si je veux apporter des modifications à index.php, je le modifie à un endroit et les liens directs (pages de détail des produits) pointent vers les modifications - sauf que git ne préserve pas cette relation lors du clonage et du transfert sur d'autres ordinateurs.

me@server:www$ git pull

sur une autre machine créera un nouvel index.php pour chaque lien dur.

7 votes

Vous devriez implémenter une sorte de routage dans votre application web. Le hard linking est bizarre.

5 votes

Oui, utilisez au moins des liens symboliques :)

3 votes

C'est en fait ce que je veux, je ne veux pas que git conserve les liens durs. J'ai un répertoire Jenkins avec des tonnes de répertoires d'espace de travail, et à cause des pipelines multibranches, il y a beaucoup de duplications. J'ai donc une tâche nocturne qui exécute hardlink --ignore-time en /var/lib/jenkins pour récupérer de l'espace disque. Au cours de la journée, certains fichiers sont à nouveau déréférencés après git pull o mvn compile mais c'est bon, je m'attends à ce que cela arrive. Si git devait préserver les liens durs, alors ma stratégie de recyclage de l'espace disque ne fonctionnerait pas.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X