Git Symlinks dans Windows

246

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

La solution ( mise à jour ) dont je dispose est la suivante:

  • Écrivez un script de post-paiement qui recherchera récursivement les fichiers texte "symlink".
  • Remplacez-les par un lien symbolique Windows (en utilisant mklink) avec le même nom et l'extension que le "lien symbolique" factice
  • 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 que c'est une approche solide de ce problème.

Des questions:

  1. Quels sont, le cas échéant, les inconvénients de cette approche?
  2. Ce script post-paiement est-il même implémentable? Est-ce que je peux récursivement trouver les fichiers factices "symlink" créés par git?
  3. Quelqu'un a-t-il déjà travaillé sur un tel script?
Ken Hirakawa
la source
3
Bien que Git supporte les liens symboliques, je vous déconseille fortement de les stocker en tant que liens dans votre référentiel, surtout si vous travaillez également avec ce code sous Windows.
Greg Hewgill
2
@Greg Hewgill - Je suis totalement 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.
Ken Hirakawa
12
Vous pouvez également demander sur la liste de diffusion msysgit pourquoi ils ne l'ont pas implémenté comme ça en premier lieu.
drizzd
8
@GregHewgill pourquoi pas? Windows prend en charge les liens symboliques et les jonctions - cela semble vraiment être une fonctionnalité manquante dans les versions Windows de Git ...
BrainSlugs83
6
Avec le "Mode développeur" activé dans Windows 10, la création de liens symboliques ne nécessite pas de droits d'administrateur! (D'autres ont commenté autant de réponses moins votées, mais je ne les ai pas vues. En espérant que ce commentaire soit plus visible pour les futurs lecteurs.)
Dave Pascua

Réponses:

105

Vous pouvez trouver les liens symboliques en recherchant des fichiers qui ont un mode de 120000, éventuellement avec cette commande:

git ls-files -s | awk '/120000/{print $4}'

Une fois que vous avez remplacé les liens, je recommanderais de les marquer comme inchangés git update-index --assume-unchanged, plutôt que de les répertorier .git/info/exclude.

Josh Lee
la source
2
J'ai dû remplacer awk par gawk pour msysgit, mais sinon cela a fonctionné parfaitement. Merci!
Ken Hirakawa
6
helo ken. Pourriez-vous partager votre script qui vérifie les fichiers texte de liens symboliques et les remplace par des liens symboliques sur les fenêtres utilisant mklink. alors que cela fonctionne pour nous, la partie --assume-unchanged ne fonctionne pas. lors du passage à une autre branche, git dit que les fichiers de liens symboliques sont modifiés et doivent être validés en premier, tandis que le statut de git indique qu'il n'y a pas de changement .. une idée?
joreg
6
Voici un PowerShell que je viens de mettre en place - gist.github.com/ferventcoder/7995025
ferventcoder
3
@flungo Il existe plus de façons portables d'imprimer la quatrième colonne que d'utiliser GNU awk. Par exemple: git ls-files -s | grep '^12' | cut -f2(deuxième colonne délimitée par des tabulations; d'autres colonnes sont délimitées par des espaces)
Zenexer
1
Un liner pour Cygwin / bash pour marquer tous les liens symboliques inchangés:for f in `git ls-files -s | awk '/120000/{print $4}'`; do git update-index --assume-unchanged $f; done
DaveAlden
187

Je posais cette même question il y a quelque temps (pas ici, juste en général) et j'ai fini par trouver une solution très similaire à la proposition de OP. Je vais d'abord répondre directement aux questions 1, 2 et 3, puis je publierai la solution que j'ai finalement utilisée.

  1. Il y a en effet quelques inconvénients à la solution proposée, principalement en ce qui concerne un potentiel accru de pollution du référentiel, ou l'ajout accidentel de fichiers en double alors qu'ils sont dans leur état "lien symbolique Windows". (Plus d'informations à ce sujet sous "limitations" ci-dessous.)
  2. Oui, un script de post-paiement est implémentable! Peut-être pas comme une post- git checkoutétape littérale , mais la solution ci-dessous a suffisamment bien répondu à mes besoins pour qu'un script de post-paiement littéral ne soit pas nécessaire.
  3. Oui!

La solution:

Nos développeurs sont à peu près dans la même situation que OP: un mélange d'hôtes, de référentiels et de sous-modules de type Windows et Unix avec de nombreux liens symboliques git, et aucun support natif (pour l'instant) dans la version finale de MsysGit pour gérer intelligemment ces liens symboliques sur les hôtes Windows. .

Merci à Josh Lee d'avoir souligné le fait que git valide les liens symboliques avec un mode de fichier spécial 120000. Avec ces informations, il est possible d'ajouter quelques alias git qui permettent la création et la manipulation de liens symboliques git sur les hôtes Windows.

  1. Création de liens symboliques git sous Windows

    git config --global alias.add-symlink '!'"$(cat <<'ETX'
    __git_add_symlink() {
      if [ $# -ne 2 ] || [ "$1" = "-h" ]; then
        printf '%b\n' \
            'usage: git add-symlink <source_file_or_dir> <target_symlink>\n' \
            'Create a symlink in a git repository on a Windows host.\n' \
            'Note: source MUST be a path relative to the location of target'
        [ "$1" = "-h" ] && return 0 || return 2
      fi
    
      source_file_or_dir=${1#./}
      source_file_or_dir=${source_file_or_dir%/}
    
      target_symlink=${2#./}
      target_symlink=${target_symlink%/}
      target_symlink="${GIT_PREFIX}${target_symlink}"
      target_symlink=${target_symlink%/.}
      : "${target_symlink:=.}"
    
      if [ -d "$target_symlink" ]; then
        target_symlink="${target_symlink%/}/${source_file_or_dir##*/}"
      fi
    
      case "$target_symlink" in
        (*/*) target_dir=${target_symlink%/*} ;;
        (*) target_dir=$GIT_PREFIX ;;
      esac
    
      target_dir=$(cd "$target_dir" && pwd)
    
      if [ ! -e "${target_dir}/${source_file_or_dir}" ]; then
        printf 'error: git-add-symlink: %s: No such file or directory\n' \
            "${target_dir}/${source_file_or_dir}" >&2
        printf '(Source MUST be a path relative to the location of target!)\n' >&2
        return 2
      fi
    
      git update-index --add --cacheinfo 120000 \
          "$(printf '%s' "$source_file_or_dir" | git hash-object -w --stdin)" \
          "${target_symlink}" \
        && git checkout -- "$target_symlink" \
        && printf '%s -> %s\n' "${target_symlink#$GIT_PREFIX}" "$source_file_or_dir" \
        || return $?
    }
    __git_add_symlink
    ETX
    )"
    

    Utilisation:, git add-symlink <source_file_or_dir> <target_symlink>où l'argument correspondant au fichier ou répertoire source doit prendre la forme d'un chemin relatif au lien symbolique cible. Vous pouvez utiliser cet alias de la même manière que vous le feriez normalement ln.

    Par exemple, l'arborescence du référentiel:

    dir/
    dir/foo/
    dir/foo/bar/
    dir/foo/bar/baz      (file containing "I am baz")
    dir/foo/bar/lnk_file (symlink to ../../../file)
    file                 (file containing "I am file")
    lnk_bar              (symlink to dir/foo/bar/)
    

    Peut être créé sous Windows comme suit:

    git init
    mkdir -p dir/foo/bar/
    echo "I am baz" > dir/foo/bar/baz
    echo "I am file" > file
    git add -A
    git commit -m "Add files"
    git add-symlink ../../../file dir/foo/bar/lnk_file
    git add-symlink dir/foo/bar/ lnk_bar
    git commit -m "Add symlinks"
    
  2. Remplacement des liens symboliques git par des liens durs + jonctions NTFS

    git config --global alias.rm-symlinks '!'"$(cat <<'ETX'
    __git_rm_symlinks() {
      case "$1" in (-h)
        printf 'usage: git rm-symlinks [symlink] [symlink] [...]\n'
        return 0
      esac
      ppid=$$
      case $# in
        (0) git ls-files -s | grep -E '^120000' | cut -f2 ;;
        (*) printf '%s\n' "$@" ;;
      esac | while IFS= read -r symlink; do
        case "$symlink" in
          (*/*) symdir=${symlink%/*} ;;
          (*) symdir=. ;;
        esac
    
        git checkout -- "$symlink"
        src="${symdir}/$(cat "$symlink")"
    
        posix_to_dos_sed='s_^/\([A-Za-z]\)_\1:_;s_/_\\\\_g'
        doslnk=$(printf '%s\n' "$symlink" | sed "$posix_to_dos_sed")
        dossrc=$(printf '%s\n' "$src" | sed "$posix_to_dos_sed")
    
        if [ -f "$src" ]; then
          rm -f "$symlink"
          cmd //C mklink //H "$doslnk" "$dossrc"
        elif [ -d "$src" ]; then
          rm -f "$symlink"
          cmd //C mklink //J "$doslnk" "$dossrc"
        else
          printf 'error: git-rm-symlink: Not a valid source\n' >&2
          printf '%s =/=> %s  (%s =/=> %s)...\n' \
              "$symlink" "$src" "$doslnk" "$dossrc" >&2
          false
        fi || printf 'ESC[%d]: %d\n' "$ppid" "$?"
    
        git update-index --assume-unchanged "$symlink"
      done | awk '
        BEGIN { status_code = 0 }
        /^ESC\['"$ppid"'\]: / { status_code = $2 ; next }
        { print }
        END { exit status_code }
      '
    }
    __git_rm_symlinks
    ETX
    )"
    
    git config --global alias.rm-symlink '!git rm-symlinks'  # for back-compat.
    

    Usage:

    git rm-symlinks [symlink] [symlink] [...]
    

    Cet alias peut supprimer les liens symboliques git un par un ou tout à la fois d'un seul coup. Les liens symboliques seront remplacés par des liens durs NTFS (dans le cas des fichiers) ou des jonctions NTFS (dans le cas des répertoires). L'avantage de l'utilisation de liens durs + jonctions par rapport aux "vrais" liens symboliques NTFS est que des autorisations UAC élevées ne sont pas nécessaires pour les créer.

    Pour supprimer les liens symboliques des sous-modules, utilisez simplement le support intégré de git pour les parcourir:

    git submodule foreach --recursive git rm-symlinks
    

    Mais, pour chaque action drastique comme celle-ci, une inversion est agréable d'avoir ...

  3. Restauration de liens symboliques git sous Windows

    git config --global alias.checkout-symlinks '!'"$(cat <<'ETX'
    __git_checkout_symlinks() {
      case "$1" in (-h)
        printf 'usage: git checkout-symlinks [symlink] [symlink] [...]\n'
        return 0
      esac
      case $# in
        (0) git ls-files -s | grep -E '^120000' | cut -f2 ;;
        (*) printf '%s\n' "$@" ;;
      esac | while IFS= read -r symlink; do
        git update-index --no-assume-unchanged "$symlink"
        rmdir "$symlink" >/dev/null 2>&1
        git checkout -- "$symlink"
        printf 'Restored git symlink: %s -> %s\n' "$symlink" "$(cat "$symlink")"
      done
    }
    __git_checkout_symlinks
    ETX
    )"
    
    git config --global alias.co-symlinks '!git checkout-symlinks'
    

    Utilisation git checkout-symlinks [symlink] [symlink] [...]:, qui annule git rm-symlinks, restaurer efficacement le référentiel à son état naturel (à l'exception de vos modifications, qui doivent rester intactes).

    Et pour les sous-modules:

    git submodule foreach --recursive git checkout-symlinks
    
  4. Limites:

    • Les répertoires / fichiers / liens symboliques avec des espaces dans leurs chemins devraient fonctionner. Mais onglets ou nouvelles lignes? YMMV… (J'entends par là: ne fais pas ça, car ça ne marchera pas .)

    • Si vous-même ou d'autres oubliez git checkout-symlinksavant de faire quelque chose avec des conséquences potentiellement étendues comme git add -A, le référentiel local pourrait se retrouver dans un état pollué.

      En utilisant notre "exemple de dépôt" d'avant:

      echo "I am nuthafile" > dir/foo/bar/nuthafile
      echo "Updating file" >> file
      git add -A
      git status
      # On branch master
      # Changes to be committed:
      #   (use "git reset HEAD <file>..." to unstage)
      #
      #       new file:   dir/foo/bar/nuthafile
      #       modified:   file
      #       deleted:    lnk_bar           # POLLUTION
      #       new file:   lnk_bar/baz       # POLLUTION
      #       new file:   lnk_bar/lnk_file  # POLLUTION
      #       new file:   lnk_bar/nuthafile # POLLUTION
      #
      

      Oups ...

      Pour cette raison, il est agréable d'inclure ces alias comme étapes à effectuer pour les utilisateurs Windows avant et après la création d'un projet, plutôt qu'après l'extraction ou avant de pousser. Mais chaque situation est différente. Ces alias m'ont été suffisamment utiles pour qu'une vraie solution post-paiement ne soit pas nécessaire.

J'espère que cela pourra aider!

Références:

http://git-scm.com/book/en/Git-Internals-Git-Objects

http://technet.microsoft.com/en-us/library/cc753194

Dernière mise à jour: 2019-03-13

  • Conformité POSIX (enfin, sauf pour ces mklinkappels, bien sûr) - plus de bashismes !
  • Les répertoires et les fichiers contenant des espaces sont pris en charge.
  • Les codes d'état de sortie zéro et non nul (pour communiquer le succès / l'échec de la commande demandée, respectivement) sont maintenant correctement conservés / renvoyés.
  • L' add-symlinkalias fonctionne désormais plus comme ln (1) et peut être utilisé à partir de n'importe quel répertoire du référentiel, pas seulement du répertoire racine du référentiel.
  • L' rm-symlinkalias (singulier) a été remplacé par l' rm-symlinksalias (pluriel), qui accepte désormais plusieurs arguments (ou aucun argument du tout, qui trouve tous les liens symboliques dans le référentiel, comme auparavant) pour transformer sélectivement les liens symboliques git en liens durs NTFS + jonctions .
  • L' checkout-symlinksalias a également été mis à jour pour accepter plusieurs arguments (ou aucun, == tout) pour une inversion sélective des transformations susmentionnées.

Remarque finale: Bien que j'ai testé le chargement et l'exécution de ces alias à l'aide de Bash 3.2 (et même 3.1) pour ceux qui peuvent encore être bloqués sur de telles versions anciennes pour un certain nombre de raisons, sachez que des versions aussi anciennes que celles-ci sont connues pour leur analyseur. Bugs. Si vous rencontrez des problèmes lors de l'installation de l'un de ces alias, la première chose à faire est de mettre à niveau votre shell (pour Bash, vérifiez la version avec CTRL + X, CTRL + V). Alternativement, si vous essayez de les installer en les collant dans votre émulateur de terminal, vous aurez peut-être plus de chance de les coller dans un fichier et de les sourcer à la place, par exemple en tant que

. ./git-win-symlinks.sh

Bonne chance!

Mark G.
la source
pouvez-vous s'il vous plaît jeter un oeil ici? stackoverflow.com/questions/21403772/…
Goofy
c'est un script génial et merveilleux, mais y a-t-il une raison pour laquelle cela devrait apposer le mot "git" au hasard à la fin de certains de mes fichiers que je crée avec git add-symlink?
Peter Turner
De plus, si votre nom de fichier contient "-h", vous obtenez l'utilisation. Encore un script très utile!
Peter Turner
Votre git add-symlinkrecette a été incroyablement précieuse pour moi. Merci beaucoup.
Dan Lenski
1
Existe-t-il un moyen d'exécuter automatiquement ces scripts à l'aide de hooks?
ARF
74

La version la plus récente de git scm (testet 2.11.1) permet d'activer les liens symboliques. Mais vous devez à nouveau cloner le référentiel avec les liens symboliques git clone -c core.symlinks=true <URL>. Vous devez exécuter cette commande avec des droits d'administrateur. Il est également possible de créer des liens symboliques sous Windows avec mklink. Consultez le wiki .

entrez la description de l'image ici

sirlunchalot
la source
1
Ça n'a pas marché pour moi. J'ai réinstallé git pour Windows, n'oubliez pas de cocher la case lien symbolique et de cloner à nouveau mon projet. Mon tslint.jsonfichier référençant le fichier dans le répertoire parent contient toujours ../tslint.json. Dommage, car cela ressemblait vraiment à la plus simple de toutes les solutions proposées.
Jan Aagaard
8
@JanAagaard Vous devez le cloner comme ceci: git clone -c core.symlinks=true <URL> Et sous Windows, vous devez l'exécuter avec des droits d'administrateur.
sirlunchalot
6
@ARF "Lancez gpedit.msc (c'est-à-dire l'éditeur de stratégie de groupe) et ajoutez le ou les comptes à Configuration ordinateur \ Paramètres Windows \ Paramètres de sécurité \ Stratégies locales \ Attribution des droits utilisateur \ Créer des liens symboliques."
sirlunchalot
2
@sirlunchalot Merci pour l'aide. Depuis, je me rends compte que mon problème est que mon utilisateur fait partie du groupe Administrateurs et que cette propriété n'a aucun effet pour ces utilisateurs. Ils nécessitent une élévation UAC, ce que git ne fait pas.
ARF
9
Les droits d'administrateur ne sont pas nécessaires en "Mode développeur" dans Windows 10 Creators Update. Merci @dennis dans son commentaire .
Dominik
16

Il devrait être implémenté dans msysgit, mais il y a deux inconvénients:

  • Les liens symboliques ne sont disponibles que dans Windows Vista et versions ultérieures (cela ne devrait pas être un problème en 2011, et pourtant c'est le cas ...), car les anciennes versions ne prennent en charge que les jonctions de répertoire.
  • (le grand) Microsoft considère les liens symboliques comme un risque pour la sécurité et donc seuls les administrateurs peuvent les créer par défaut. Vous devrez élever les privilèges du processus git ou utiliser fstool pour changer ce comportement sur chaque machine sur laquelle vous travaillez.

J'ai fait une recherche rapide et il y a un travail activement fait à ce sujet, voir le numéro 224 .

djs
la source
2
Mise à jour: pour les raisons ci-dessus, le problème a été résolu comme wontfix. La discussion indique qu'un correctif pourrait être accepté avec un peu plus de travail sur le correctif (par exemple, en utilisant des liens symboliques uniquement s'ils fonctionnent).
Blaisorblade
2
A.) actuellement msysgit ne prend pas du tout en charge les liens symboliques. permettez-moi d'utiliser ces ", ou" oh, vous êtes sur Windows 98 / fat32, permettez-moi de ne pas simplement avoir cette fonctionnalité et de vous donner un avertissement à la place! " et ensuite B.) Presque tout le développement de Microsoft. les outils ne fonctionnent pas correctement (du moins pas pour toutes leurs fonctionnalités) si vous ne les exécutez pas en tant qu'administrateur - tout le monde dans l'informatique sait que les développeurs doivent être des administrateurs sur leurs propres boîtes.
BrainSlugs83
1
Bien que j'exécute certaines machines dans le compte Admin, je ne respecte pas cette philosophie sur ma machine de développement. Je cours toujours en tant qu'utilisateur régulier avec UAC-enabled. Je garde une console distincte ouverte pour les opérations qui nécessitent des privilèges élevés. Quant à la mise en œuvre, cela revient à quelqu'un (comme vous) qui se porte volontaire pour la mettre en œuvre. Les développeurs de msysgit ne sont pas connus pour la charité ...
djs
@djs Un utilisateur doit ouvrir une invite de commande avec "Exécuter en tant qu'administrateur". Il fonctionne presque littéralement en tant qu'utilisateur administrateur, ce qui change complètement l'environnement. Il n'y a aucun moyen d'exécuter 'mklink / d' en tant qu'utilisateur qui fait également partie du groupe Admin. Il n'y aura pas d'invite UAC. Cela échouera toujours. Il fonctionne uniquement de deux manières: littéralement en tant qu'administrateur (RunAs Verb) ou en tant qu'utilisateur non administrateur avec un changement de stratégie de groupe. Les jonctions doivent être la valeur par défaut et doivent être reconnues par tous les outils. Le «risque de sécurité» est que les liens symboliques sous Windows peuvent «rediriger» les partages SMB. C'est douloureux et cruel.
Andrew T Finnell
8
Annoncé en décembre 2016, Symlinks dans Windows 10 n'est plus une action d'administrateur. blogs.windows.com/buildingapps/2016/12/02/symlinks-windows-10/…
Dennis
16

Donc, comme les choses ont changé avec GIT depuis que beaucoup de ces réponses ont été publiées, voici les instructions correctes pour que les liens symboliques fonctionnent correctement dans Windows à partir de

AOÛT 2018


1. Assurez-vous que git est installé avec le support de symlink

Lors de l'installation de git sur windows

2. Dites à Bash de créer des liens physiques au lieu de liens symboliques

EDIT - (dossier git) /etc/bash.bashrc

AJOUTER AU FOND - MSYS=winsymlinks:nativestrict

3. Définissez git config pour utiliser des liens symboliques

git config core.symlinks true

ou

git clone -c core.symlinks=true <URL>

REMARQUE: j'ai essayé d'ajouter ceci à la configuration globale de git et pour le moment cela ne fonctionne pas pour moi, donc je recommande d'ajouter ceci à chaque dépôt ...

4. tirez sur le repo

REMARQUE: sauf si vous avez activé le mode développeur dans la dernière version de Windows 10, vous devez exécuter bash en tant qu'administrateur pour créer des liens symboliques

5. Réinitialiser tous les liens symboliques (facultatif) Si vous avez un référentiel existant ou utilisez des sous-modules, vous pouvez constater que les liens symboliques ne sont pas créés correctement. Pour actualiser tous les liens symboliques du référentiel, vous pouvez exécuter ces commandes.

find -type l -delete
git reset --hard

REMARQUE: cela réinitialisera toutes les modifications depuis la dernière validation, assurez-vous donc que vous avez validé en premier

Simon
la source
15

Réponse courte: ils sont désormais bien pris en charge, si vous pouvez activer le mode développeur.

Depuis https://blogs.windows.com/buildingapps/2016/12/02/symlinks-windows-10/

Désormais, dans Windows 10 Creators Update, un utilisateur (avec des droits d'administrateur) peut d'abord activer le mode développeur, puis tout utilisateur de la machine peut exécuter la commande mklink sans élever une console de ligne de commande.

Qu'est-ce qui a motivé ce changement? La disponibilité et l'utilisation des liens symboliques sont très importantes pour les développeurs modernes:

De nombreux outils de développement populaires comme git et les gestionnaires de packages comme npm reconnaissent et conservent les liens symboliques lors de la création de référentiels ou de packages, respectivement. Lorsque ces dépôts ou packages sont ensuite restaurés ailleurs, les liens symboliques sont également restaurés, ce qui garantit que l'espace disque (et le temps de l'utilisateur) n'est pas perdu.

Facile à ignorer avec toutes les autres annonces de la "mise à jour du créateur", mais si vous activez le mode développeur, vous pouvez créer des liens symboliques sans privilèges élevés. Vous devrez peut-être réinstaller git et vous assurer que la prise en charge des liens symboliques est activée, car ce n'est pas le cas par défaut.

Les liens symboliques ne sont pas activés par défaut

Orangutech
la source
1
gpedit.msc-> Local Computer Policy-> Computer Configuration-> Windows Settings-> Security Settings-> Local Policies-> User Rights Assignmenta été la manière canonique d'attribuer des droits d'utilisateur comme SeCreateSymbolicLinket amis depuis des lustres. Autre que ntrights.exedu Kit de ressources ou du PowerShell ...
0xC0000022L
11

2020 Réponse

  1. Activer le "mode développeur" dans Windows 10 - donne des mklinkautorisations
  2. Assurez-vous que les liens symboliques sont activés dans git
    • git config --global core.symlinks true
    • ou cochez la case lors de l'installation de msysgit

Changer de branche forcera la recréation des liens symboliques manquants.

Attention, la prise en charge de Symlinks sous Windows avec certains autres clients Git n'est pas complète. Notamment GitKraken.

Cameron Tacklind
la source
Tous mes référentiels locaux ont core.symlinks = false qui remplacerait votre solution. Une idée de ce qui produit automatiquement cette configuration locale? Peut-être installer Git pour Windows sans cocher la case?
gravidThoughts
@gravidThoughts quel (s) client (s) git avez-vous installé? Peut-être que certains outils font cela? Est-ce vrai sur un clone frais?
Cameron Tacklind le
10

Je vous suggère de ne pas utiliser de liens symboliques dans le repo '. Stockez le contenu réel à l'intérieur du référentiel ', puis placez des liens symboliques à l'extérieur du référentiel' qui pointent vers le contenu.

Supposons donc que vous utilisez un référentiel pour comparer l'hébergement de votre site sur * nix avec l'hébergement sur win. Stockez le contenu dans votre repo ', disons /httpRepoContentet c:\httpRepoContentavec cela étant le dossier qui est synchronisé via GIT, SVN etc.

Ensuite, remplacez le dossier de contenu de votre serveur Web ( /var/wwwet c:\program files\web server\www{les noms n'ont pas vraiment d'importance, modifiez si vous devez}) par un lien symbolique vers le contenu de votre référentiel '. Les serveurs Web verront le contenu comme étant au bon endroit, mais vous pourrez utiliser votre contrôle de code source.

Cependant, si vous devez utiliser des liens symboliques avec dans le repo ', vous devrez examiner quelque chose comme une sorte de scripts de pré / post-commit. Je sais que vous pouvez les utiliser pour faire des choses, comme analyser des fichiers de code via un formateur par exemple, il devrait donc être possible de convertir les liens symboliques entre les plates-formes.

si quelqu'un connaît un bon endroit pour apprendre à faire ces scripts pour les contrôles de source communs, SVN GIT MG, alors veuillez ajouter un commentaire.

thecoshman
la source
En fin de compte, j'ai choisi cette approche pour créer un dossier de liens symboliques et créer les liens symboliques vers l'emplacement du fichier d'origine. L'autre approche n'a pas fonctionné même après avoir modifié le paramètre .git / config core.symlinks = true. Seul le fichier de lien symbolique a été enregistré dans le référentiel et non les données. A également eu des problèmes avec les horodatages du dossier sur le lien symbolique, donc git bash n'a jamais vu quand un fichier a changé dans le dossier.
Oeufs
@Eggs ce que vous avez pu voir, je suppose, c'est que le lien était dans le repo, et donc git l'a sauvé, simples. Le problème est cependant que la cible était en dehors du référentiel, et git ne suit pas le lien vers les données cibles. Sur Linux, vous avez un type de lien qui fonctionnerait pour cela, c'est fondamentalement vous permet d'avoir deux chemins vers les mêmes données stockées sur le disque; J'ai l'impression que de nouvelles fenêtres peuvent le faire maintenant. Quoi qu'il en soit, je ne pense toujours pas que cela fera ce que les gens veulent.
thecoshman
@thecoshman Ce n'est pas une solution, mais une solution de contournement. Cependant, parfois ce n'est pas une option. J'ai un dépôt avec git-annex et toutes ses œuvres d'architecture à cause de liens symboliques.
marcelo.guedes
8

Pour ceux qui utilisent CygWin sur Vista, Win7 ou supérieur, la gitcommande native peut créer des liens symboliques "appropriés" qui sont reconnus par les applications Windows telles que Android Studio . Il vous suffit de définir la CYGWINvariable d'environnement pour inclure winsymlinks:nativeou en winsymlinks:nativestricttant que telle:

export CYGWIN="$CYGWIN winsymlinks:native"

L'inconvénient de cela (et un aspect significatif à ce sujet) est que le shell CygWin doit être «Exécuter en tant qu'administrateur» pour qu'il dispose des autorisations du système d'exploitation requises pour créer ce type de liens symboliques. Une fois qu'ils sont créés, cependant, aucune autorisation spéciale n'est requise pour les utiliser . Tant qu'ils ne sont pas modifiés dans le référentiel par un autre développeur, gits'exécute ensuite correctement avec les autorisations utilisateur normales.

Personnellement, je l'utilise uniquement pour les liens symboliques qui sont parcourus par les applications Windows (c'est-à-dire non CygWin) en raison de cette difficulté supplémentaire.

Pour plus d'informations sur cette option, consultez cette question SO: Comment créer un lien symbolique avec cygwin dans Windows 7

Brian White
la source
6

Voici un script batch pour convertir les liens symboliques dans le référentiel, pour les fichiers uniquement, basé sur la réponse de Josh Lee. Le script avec une vérification supplémentaire des droits d'administrateur se trouve à https://gist.github.com/Quazistax/8daf09080bf54b4c7641 .

@echo off
pushd "%~dp0"
setlocal EnableDelayedExpansion

for /f "tokens=3,*" %%e in ('git ls-files -s ^| findstr /R /C:"^120000"') do (
     call :processFirstLine %%f
)
REM pause
goto :eof

:processFirstLine
@echo.
@echo FILE:    %1

dir "%~f1" | find "<SYMLINK>" >NUL && (
  @echo FILE already is a symlink
  goto :eof
)

for /f "usebackq tokens=*" %%l in ("%~f1") do (
  @echo LINK TO: %%l

  del "%~f1"
  if not !ERRORLEVEL! == 0 (
    @echo FAILED: del
    goto :eof
  )

  setlocal
  call :expandRelative linkto "%1" "%%l"
  mklink "%~f1" "!linkto!"
  endlocal
  if not !ERRORLEVEL! == 0 (
    @echo FAILED: mklink
    @echo reverting deletion...
    git checkout -- "%~f1"
    goto :eof
  )

  git update-index --assume-unchanged "%1"
  if not !ERRORLEVEL! == 0 (
    @echo FAILED: git update-index --assume-unchanged
    goto :eof
  )
  @echo SUCCESS
  goto :eof
)
goto :eof

:: param1 = result variable
:: param2 = reference path from which relative will be resolved
:: param3 = relative path
:expandRelative
  pushd .
  cd "%~dp2"
  set %1=%~f3
  popd
goto :eof
Quazistax
la source
Une réponse non documentée n'est vraiment pas très utile lorsqu'il existe déjà des réponses aussi longues et verbeuses.
Xennex81
4

J'utilise des liens sym tout le temps entre ma racine de document et mon répertoire git repo. J'aime les garder séparés. Sous Windows, j'utilise l'option mklink / j. La jonction semble laisser git 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

mmv_sat
la source
2
Soyez très prudent avec l'Explorateur Windows et les jonctions; il ne différencie pas les jonctions de l'emplacement de base et une suppression sera récursive dans la cible et supprimera son contenu, tandis que la suppression d'un lien symbolique supprimera simplement le lien symbolique. Juste un piège pour les imprudents.
Lawrence Dol
5
En fait, je viens de le tester sur la dernière version de Windows7, et il ne le fait plus, donc la gestion des jonctions a été améliorée au cours des dernières années.
Lawrence Dol
3

Je cherchais une solution simple pour gérer les liens symboliques Unix sur Windows. Merci beaucoup pour les alias Git ci-dessus. Il y a une petite optimisation qui peut être faite pour les liens rm-sym afin qu'il ne supprime pas les fichiers dans le dossier de destination au cas où l'alias serait exécuté une seconde 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 
prgrminglover
la source
2

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

Par exemple, nos appels de script de validation Windows 7:

$ 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 à certains de nos environnements hérités auxquels des liens symboliques ont été ajoutés.

Mike Panoff
la source