web-dev-qa-db-fra.com

Comment puis-je obliger Git à suivre les liens symboliques?

Est-ce que je préférerais être un script Shell qui remplace les liens symboliques par des copies, ou existe-t-il un autre moyen de dire à Git de suivre les liens symboliques?

PS: Je sais que ce n'est pas très sécurisé, mais je ne veux le faire que dans quelques cas spécifiques.

174
Matt

NOTE: Cet avis est maintenant obsolète depuis le commentaire de Git 1.6.1. Git se comportait de cette façon et ne le fait plus.


Git par défaut tente de stocker les liens symboliques au lieu de les suivre (pour des raisons de compacité, et c'est généralement ce que les gens veulent).

Cependant, j'ai accidentellement réussi à le faire pour ajouter des fichiers au-delà du lien symbolique lorsque le lien symbolique est un répertoire.

C'est à dire.:

  /foo/
  /foo/baz
  /bar/foo --> /foo
  /bar/foo/baz

en faisant

 git add /bar/foo/baz

cela a semblé fonctionner quand je l'ai essayé. Ce comportement était cependant indésirable pour moi à l'époque, alors je ne peux pas vous donner d'informations au-delà de cela.

37
Kent Fredric

Ce que j'ai fait pour ajouter les fichiers d'un lien symbolique dans Git (je n'ai pas utilisé de lien symbolique, mais):

Sudo mount --bind SOURCEDIRECTORY TARGETDIRECTORY

Faites cette commande dans le répertoire géré par Git. TARGETDIRECTORY doit être créé avant que SOURCEDIRECTORY y soit monté.

Cela fonctionne bien sous Linux, mais pas sous OS X! Cette astuce m'a aussi aidé avec Subversion. Je l'utilise pour inclure des fichiers d'un compte Dropbox, où un webdesigner fait son travail.

124
user252400

Pourquoi ne pas créer des liens symboliques dans le sens inverse? Au lieu de créer un lien entre le référentiel Git et le répertoire de l'application, il vous suffit de créer un lien inverse.

Par exemple, disons que je configure une application installée dans ~/application qui nécessite un fichier de configuration config.conf:

  • J'ajoute config.conf à mon référentiel Git, par exemple, à ~/repos/application/config.conf.
  • Ensuite, je crée un lien symbolique à partir de ~/application en exécutant ln -s ~/repos/application/config.conf.

Cette approche ne fonctionne peut-être pas toujours, mais elle a bien fonctionné jusqu'à présent.

65
spier

Utilisez des liens durs à la place. Cela diffère d'un lien symbolique. Tous les programmes, y compris git, traiteront le fichier comme un fichier normal. Notez que le contenu peut être modifié en modifiant soit la source ou la destination.

Sur macOS (avant 10.13 High Sierra)

Si vous avez déjà installé git et Xcode, installer hardlink . C'est un outil pour créer des liens durs _ microscopique. 

Pour créer le lien dur, simplement:

hln source destination

mise à jour macOS High Sierra

Apple File System prend-il en charge les liens physiques de répertoire?

Les liens physiques d’annuaire ne sont pas pris en charge par Apple File System. Tous les liens physiques d’annuaire sont convertis en liens symboliques ou en alias lorsque vous convertissez des formats de volume HFS + vers APFS sous macOS.

De APFS FAQ sur developer.Apple.com

Suivez https://github.com/selkhateeb/hardlink/issues/31 pour des alternatives futures.

Sous Linux et autres variétés Unix

La commande ln peut créer des liens difficiles:

ln source destination

Sous Windows (Vista, 7, 8,…)

Quelqu'un a suggéré d'utiliser mklink pour créer une jonction sous Windows, mais je ne l'ai pas essayé:

mklink /j "source" "destination"
41
bfred.it

Ceci est un pre-commit hook qui remplace les blobs de lien symbolique dans l'index par le contenu de ces liens symboliques.

Mettez ceci dans .git/hooks/pre-commit, et rendez-le exécutable:

#!/bin/sh
# (replace "find ." with "find ./<path>" below, to work with only specific paths)

# (these lines are really all one line, on multiple lines for clarity)
# ...find symlinks which do not dereference to directories...
find . -type l -exec test '!' -d {} ';' -print -exec sh -c \
# ...remove the symlink blob, and add the content diff, to the index/cache
    'git rm --cached "$1"; diff -au /dev/null "$1" | git apply --cached -p1 -' \
# ...and call out to "sh".
    "process_links_to_nondir" {} ';'

# the end

Remarques

Nous utilisons autant que possible les fonctionnalités compatibles POSIX; Cependant, diff -a n'est pas compatible POSIX, peut-être entre autres choses.

Il peut y avoir des erreurs/erreurs dans ce code, même s'il a été testé quelque peu.

16
Abbafei

J'avais l'habitude d'ajouter des fichiers au-delà des liens symboliques pendant un certain temps maintenant. Cela fonctionnait très bien, sans prendre de dispositions spéciales. Depuis que j'ai mis à jour Git 1.6.1, cela ne fonctionne plus.

Vous pourrez peut-être passer à Git 1.6.0 pour que cela fonctionne. J'espère qu'une version future de Git aura un drapeau pour git-add lui permettant de suivre à nouveau les liens symboliques.

12
Erik Schnetter

J'en avais marre de voir que chaque solution ici était obsolète ou nécessitait un accès root. J'ai donc créé une solution basée sur LD_PRELOAD (Linux uniquement).

Il s'accroche aux éléments internes de Git, remplaçant ainsi le message "Est-ce un lien symbolique?" fonction, permettant aux liens symboliques d'être traités comme leur contenu. Par défaut, tous les liens hors du référentiel sont en ligne. voir le lien pour plus de détails.

5
Alcaro

Hmmm, mount --bind ne semble pas fonctionner sur Darwin.

Quelqu'un at-il un truc qui fait?

[édité]

OK, j'ai trouvé la réponse sur Mac OS X: créer un lien dur. Sauf que cette API n'est pas exposée via ln, vous devez donc utiliser votre propre petit programme pour le faire. Voici un lien vers ce programme:

Création de liens physiques dans les répertoires sous Mac OS X

Prendre plaisir!

4
J Chris A

J'utilise Git 1.5.4.3 et il suit le lien symbolique passé s'il est suivi d'une barre oblique. Par exemple.

# Adds the symlink itself
$ git add symlink

# Follows symlink and adds the denoted directory's contents
$ git add symlink/
1
artistoex

Sur MacOS, utilisez bindfs

brew install bindfs

cd /path/to/git_controlled_dir 

mkdir local_copy_dir

bindfs <source_dir> local_copy_dir

Cela a été suggéré par d'autres commentaires, mais pas clairement indiqué dans d'autres réponses. Espérons que cela économise du temps à quelqu'un. 

0
ijoseph

La conversion à partir de liens symboliques pourrait être utile. Lien dans un dossier Git au lieu d'un lien symbolique par un script .

0
Yurij73