352 votes

Symlinks Git sous Windows

Nos développeurs utilisent un mélange de systèmes d'exploitation basés sur Windows et Unix. Par conséquent, les liens symboliques créés sur des machines Unix deviennent un problème pour les développeurs Windows. Dans Windows (msysgit), le lien symbolique est converti en un fichier texte avec un chemin vers le fichier vers lequel il pointe. J'aimerais plutôt convertir le lien symbolique en un véritable lien symbolique Windows.

Le ( actualisé ) La solution que j'ai à ce problème est la suivante :

  • Ecrire un script post-checkout qui recherchera récursivement les fichiers textes "symlink".
  • Remplacez-les par un lien symbolique Windows (en utilisant mklink) avec le même nom et la même extension que le lien symbolique fictif.
  • Ignorez ces liens symboliques Windows en ajoutant une entrée dans .git/info/exclude.

Je ne l'ai pas mis en œuvre, mais je pense qu'il s'agit d'une approche solide de ce problème.

Questions :

  1. Quels inconvénients voyez-vous, le cas échéant, à cette approche ?
  2. Est-ce que ce script post-checkout est même implémentable ? C'est-à-dire que je peux trouver récursivement les fichiers "symlink" factices que git crée ?
  3. Quelqu'un a-t-il déjà travaillé sur un tel script ?

7 votes

Bien que Git supporte les liens symboliques, je vous déconseille fortement de les stocker comme liens dans votre dépôt, notamment si vous travaillez aussi avec ce code sous Windows.

4 votes

@Greg Hewgill - Je suis tout à fait d'accord avec vous. Malheureusement, la nature de notre base de code nécessite des liens symboliques... donc les supprimer n'est pas une option pour nous.

13 votes

Vous pouvez également demander sur la liste de diffusion msysgit pourquoi ils ne l'ont pas implémenté de cette manière dès le départ.

8voto

StackzOfZtuff Points 1109

Je viens d'essayer avec Git 2.30.0 (publié en 2020-12-28).

Il ne s'agit pas d'une réponse complète, mais de quelques éléments utiles. (N'hésitez pas à les cannibaliser pour votre propre réponse).

Entrée dans le wiki Git

Il y a un lien vers la documentation lors de l'installation de Git pour Windows.

enter image description here

Ce lien vous conduit ici : https://github.com/git-for-Windows/git/wiki/Symbolic-Links -- Et c'est une discussion assez longue.

Pour info : il existe au moins trois "types de liens".

Et juste pour souligner un aspect important de cette entrée wiki : Je ne le savais pas, mais il existe plusieurs façons de faire, qui sont toutes des "sortes" de liens symboliques en surface, mais qui sont TRÈS DIFFÉRENTES sur le plan technique :

  • le "ln -s" de git bash
    Qui ne fait que copier les choses. Oh, bon sang. C'était inattendu pour moi.
    (FYI : Plain Cygwin ne fait PAS cela. Mobaxterm ne fait PAS cela. Au lieu de cela, ils créent tous deux quelque chose que leur stat reconnaît en fait un "lien symbolique").
  • La fonction intégrée de cmd.exe " mklink "avec la commande " /D "Paramètres
    Ce qui crée un lien symbolique de répertoire. (Voir MS Docs )
  • La fonction intégrée de cmd.exe " mklink "avec la commande " /J "Paramètres
    Ce qui crée une jonction de répertoire, c'est-à-dire un lien logiciel, c'est-à-dire un point de réparation. (Voir MS Docs )

Entrée des notes de version

De même, des liens symboliques continuent d'apparaître dans les notes de mise à jour . Depuis la version 2.30.0, ce problème est toujours répertorié comme un "problème connu" :

Sur Windows 10 avant 1703, ou lorsque le mode développeur est désactivé, des autorisations spéciales sont requises lors du clonage de référentiels avec des liens symboliques, c'est pourquoi la prise en charge des liens symboliques est désactivée par défaut. Utilisez git clone -c core.symlinks=true <URL> pour l'activer, voir les détails aquí .

4voto

mmv_sat Points 429

J'utilise tout le temps des liens sym entre le répertoire racine de mon document et le répertoire du dépôt git. J'aime les garder séparés. Sous Windows, j'utilise l'option mklink /j. La jonction semble permettre à git de se comporter normalement :

>mklink /j <location(path) of link> <source of link>

par exemple :

>mklink /j c:\gitRepos\Posts C:\Bitnami\wamp\apache2\htdocs\Posts

2 votes

Soyez très prudent avec l'Explorateur Windows et les jonctions ; il ne fait pas la différence entre les jonctions et l'emplacement de base et une suppression fera une récursion dans la cible et supprimera son contenu, alors que la suppression d'un lien symbolique ne fera que supprimer le lien symbolique. C'est un piège pour les personnes non averties.

6 votes

En fait, je viens de le tester sur la dernière version de Windows7, et il ne le fait plus, donc la gestion des carrefours a été améliorée au cours des dernières années.

4voto

prgrminglover Points 31

Je cherchais une solution simple pour gérer les liens symboliques Unix sous Windows. Merci beaucoup pour les alias Git ci-dessus. Il y a une petite optimisation qui peut être faite au rm-symlinks de sorte qu'il ne supprime pas les fichiers dans le dossier de destination au cas où l'alias est exécuté une deuxième fois accidentellement. Veuillez observer la nouvelle condition if dans la boucle pour vous assurer que le fichier n'est pas déjà un lien vers un répertoire avant l'exécution de la logique.

git config --global alias.rm-symlinks '!__git_rm_symlinks(){
for symlink in $(git ls-files -s | egrep "^120000" | cut -f2); do
    *if [ -d "$symlink" ]; then
      continue
    fi*
    git rm-symlink "$symlink"
    git update-index --assume-unchanged "$symlink"
done
}; __git_rm_symlinksenter

3voto

Mike Panoff Points 31

Une astuce simple que nous utilisons consiste à appeler git add --all deux fois de suite.

Par exemple, notre commit Windows 7 script appelle :

$ git add --all
$ git add --all

Le premier ajout traite le lien comme du texte et ajoute les dossiers à supprimer.

Le deuxième ajout traverse correctement le lien et annule la suppression en restaurant les fichiers.

C'est moins élégant que certaines des autres solutions proposées, mais c'est une solution simple pour certains de nos anciens environnements auxquels des liens symboliques ont été ajoutés.

1voto

Voici un script powershell pour remplacer les symlinks unix par des symlinks Windows

# This fixes Permission denied errors you might get when
#  there are git symlinks being used on repositories that
#  you share in both POSIX (usually the host) and Windows (VM).
#
# This is not an issue if you are checking out the same
#  repository separately in each platform. This is only an issue
#  when it's the same working set (aka make a change w/out
#  committing on OSX, go to Windows VM and git status would show
#  you that change).
#
# Based on this answer on stack overflow: http://stackoverflow.com/a/5930443/18475
#
# No warranties, good luck
#
# MUST BE RUN IN ELEVATED POWER SHELL

$ROOT = $PWD

$symlinks = &git ls-files -s | gawk '/120000/{print $4}'
foreach ($symlink in $symlinks) {
  $content = &Get-Content $symlink
  $content = $content.Replace("/", "\")
  $filename = $symlink.Split("/")[-1]
  cd (dirname $symlink)
  rm $filename
  echo Linking $content -> $filename
  New-Item -ItemType SymbolicLink -Path $filename -Target $content
  &git update-index --assume-unchanged $symlink
  cd $ROOT
}

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