Git Symlink in Windows


246

I nostri sviluppatori utilizzano un mix di sistemi operativi basati su Windows e Unix. Pertanto, i collegamenti simbolici creati su macchine Unix diventano un problema per gli sviluppatori Windows. In Windows (msysgit), il collegamento simbolico viene convertito in un file di testo con un percorso al file a cui punta. Invece, vorrei convertire il collegamento simbolico in un vero collegamento simbolico di Windows.

La soluzione ( aggiornata ) che devo fare è:

  • Scrivi uno script post-checkout che ricercherà ricorsivamente i file di testo "symlink".
  • Sostituiscili con symlink di Windows (usando mklink) con lo stesso nome ed estensione del "symlink" fittizio
  • Ignora questi collegamenti simbolici di Windows aggiungendo la voce in .git / info / exclude

Non l'ho implementato, ma credo che questo sia un approccio solido a questo problema.

Domande:

  1. Che aspetti negativi vedi di questo approccio?
  2. Questo script post-checkout è persino implementabile? cioè posso scoprire ricorsivamente i file fittizi "symlink" che git crea?
  3. Qualcuno ha già lavorato su tale sceneggiatura?

3
Sebbene Git supporti i collegamenti simbolici, raccomanderei caldamente di non archiviarli come collegamenti nel repository, specialmente se stai lavorando anche con quel codice su Windows.
Greg Hewgill,

2
@Greg Hewgill - Sono totalmente d'accordo con te. Sfortunatamente, la natura della nostra base di codice richiede collegamenti simbolici ... quindi rimuoverli non è un'opzione per noi.
Ken Hirakawa,

12
Potresti anche chiedere sulla mailing list di msysgit perché non l'hanno implementata in questo modo in primo luogo.
drizzd

8
@GregHewgill perché no? Windows supporta sia i collegamenti simbolici che le giunzioni - questa sembra davvero una caratteristica mancante nelle versioni Windows di Git per me ...
BrainSlugs83

6
Con la "Modalità sviluppatore" abilitata in Windows 10, la creazione di collegamenti simbolici non richiede i diritti di amministratore! (Altri hanno commentato altrettanto le risposte meno votate, ma io non le ho viste. Sperando che questo commento sia più visibile ai futuri lettori.)
Dave Pascua,

Risposte:


105

Puoi trovare i collegamenti simbolici cercando i file che hanno una modalità 120000, possibilmente con questo comando:

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

Dopo aver sostituito i collegamenti, consiglierei di contrassegnarli come invariati git update-index --assume-unchanged, piuttosto che elencarli .git/info/exclude.


2
Ho dovuto sostituire awk con gawk per msysgit, ma per il resto ha funzionato perfettamente. Grazie!
Ken Hirakawa,

6
helo ken. ti dispiacerebbe condividere il tuo script che controlla i file di testo del link simbolico e li sostituisce con i link simbolici su Windows usando mklink. mentre questo in realtà funziona per noi la parte --assume-immutata non lo fa. quando si passa a un altro ramo git dice che i file symlink sono cambiati e devono essere prima sottoposti a commit, mentre lo stato git dice che non ci sono cambiamenti..ogni idea?
joreg

6
Ecco un PowerShell che ho appena messo insieme - gist.github.com/ferventcoder/7995025
ferventcoder il

3
@flungo Ci sono modi più portatili per stampare la quarta colonna che usare GNU awk. Ad esempio: git ls-files -s | grep '^12' | cut -f2(seconda colonna delimitata da tabulazioni; altre colonne sono delimitate da spazi)
Zenexer

1
Un liner per Cygwin / bash per contrassegnare invariati tutti i for f in `git ls-files -s | awk '/120000/{print $4}'`; do git update-index --assume-unchanged $f; done
link

187

Stavo ponendo la stessa identica domanda qualche tempo fa (non qui, solo in generale) e alla fine ho trovato una soluzione molto simile alla proposta di OP. Per prima cosa fornirò le risposte dirette alle domande 1 2 e 3, quindi pubblicherò la soluzione che ho finito per usare.

  1. Esistono in effetti alcuni aspetti negativi della soluzione proposta, principalmente per quanto riguarda un maggiore potenziale di inquinamento del repository o l'aggiunta accidentale di file duplicati mentre si trovano nei loro stati "Windows symlink". (Maggiori informazioni al riguardo sotto "limitazioni" di seguito).
  2. Sì, è possibile implementare uno script post-checkout! Forse non come un post- git checkoutstep letterale , ma la soluzione di seguito ha soddisfatto i miei bisogni abbastanza bene che uno script post-checkout letterale non era necessario.
  3. Sì!

La soluzione:

I nostri sviluppatori si trovano nella stessa situazione degli OP: una combinazione di host Windows e Unix, repository e sottomoduli con molti collegamenti simbolici git e nessun supporto nativo (ancora) nella versione di rilascio di MsysGit per la gestione intelligente di questi collegamenti simbolici su host Windows .

Grazie a Josh Lee per aver sottolineato il fatto che git commette collegamenti simbolici con filemode speciale 120000. Con queste informazioni è possibile aggiungere alcuni alias git che consentono la creazione e la manipolazione di collegamenti simbolici git su host Windows.

  1. Creazione di collegamenti simbolici git su 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
    )"
    

    Utilizzo:, in git add-symlink <source_file_or_dir> <target_symlink>cui l'argomento corrispondente al file o alla directory di origine deve assumere la forma di un percorso relativo al collegamento simbolico di destinazione. Puoi usare questo alias come faresti normalmente ln.

    Ad esempio, l'albero del repository:

    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/)
    

    Può essere creato su Windows come segue:

    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. Sostituzione di symlink git con hardlink NTFS + giunzioni

    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.
    

    Uso:

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

    Questo alias può rimuovere git symlink uno alla volta o tutto in una volta in un colpo solo. I collegamenti simbolici verranno sostituiti con hardlink NTFS (nel caso dei file) o giunzioni NTFS (nel caso delle directory). Il vantaggio di utilizzare hardlink + giunzioni su "veri" symlink NTFS è che non sono richieste autorizzazioni UAC elevate per poter essere create.

    Per rimuovere i collegamenti simbolici dai sottomoduli, basta usare il supporto integrato di git per scorrere su di essi:

    git submodule foreach --recursive git rm-symlinks
    

    Ma, per ogni azione drastica come questa, è bello avere un'inversione ...

  3. Ripristino dei collegamenti simbolici git su 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'
    

    Utilizzo: git checkout-symlinks [symlink] [symlink] [...]che annulla git rm-symlinks, ripristinando efficacemente il repository al suo stato naturale (ad eccezione delle modifiche, che dovrebbero rimanere intatte).

    E per i sottomoduli:

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

    • Directory / file / symlink con spazi nei loro percorsi dovrebbero funzionare. Ma schede o newline? YMMV ... (Con questo voglio dire: non farlo, perché non funzionerà.)

    • Se te stesso o gli altri ti dimentichi di git checkout-symlinksfare qualcosa con conseguenze potenzialmente molto ampie come git add -A, il repository locale potrebbe finire in uno stato inquinato.

      Usando il nostro "esempio repo" di prima:

      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
      #
      

      Ops ...

      Per questo motivo, è bello includere questi alias come passaggi da eseguire per gli utenti di Windows prima e dopo la creazione di un progetto, piuttosto che dopo il checkout o prima di eseguire il push. Ma ogni situazione è diversa. Questi alias sono stati abbastanza utili per me che non è stata necessaria una vera soluzione post-checkout.

Spero che aiuti!

Riferimenti:

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

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

Ultimo aggiornamento: 13-03-2019

  • Conformità POSIX (beh, tranne quelle mklinkchiamate, ovviamente) - niente più Bashismi !
  • Sono supportate directory e file con spazi.
  • I codici di stato di uscita zero e diverso da zero (rispettivamente per comunicare l'esito positivo / negativo del comando richiesto) sono ora correttamente conservati / restituiti.
  • L' add-symlinkalias ora funziona più come ln (1) e può essere utilizzato da qualsiasi directory nel repository, non solo dalla directory principale del repository.
  • L' rm-symlinkalias (singolare) è stato sostituito rm-symlinksdall'alias (plurale), che ora accetta più argomenti (o nessun argomento, che trova tutti i collegamenti simbolici in tutto il repository, come prima) per trasformare selettivamente i collegamenti simbolici git in hardlink + NTFS + giunzioni .
  • L' checkout-symlinksalias è stato inoltre aggiornato per accettare più argomenti (o nessuno, == tutto) per l'inversione selettiva delle suddette trasformazioni.

Nota finale: mentre ho testato il caricamento e l'esecuzione di questi alias usando Bash 3.2 (e anche 3.1) per coloro che potrebbero essere ancora bloccati su versioni così antiche per qualsiasi numero di motivi, tieni presente che le versioni vecchie come queste sono famose per il loro parser bug. Se si verificano problemi durante il tentativo di installare uno di questi alias, la prima cosa da considerare è l'aggiornamento della shell (per Bash, controllare la versione con CTRL + X, CTRL + V). In alternativa, se stai cercando di installarli incollandoli nell'emulatore di terminale, potresti avere più fortuna incollandoli in un file e acquistandolo invece, ad esempio come

. ./git-win-symlinks.sh

In bocca al lupo!


puoi per favore dare un'occhiata qui? stackoverflow.com/questions/21403772/…
Pippo,

questo è uno script fantastico e meraviglioso, ma c'è qualche ragione per cui questo dovrebbe apporre casualmente la parola "git" alla fine di alcuni dei miei file che creo con git add-symlink?
Peter Turner,

Inoltre, se il nome del tuo file contiene "-h" ottieni l'utilizzo. Ancora una sceneggiatura molto utile!
Peter Turner,

La tua git add-symlinkricetta è stata straordinariamente preziosa per me. Grazie molto.
Dan Lenski,

1
Esiste un modo per eseguire automaticamente questi script utilizzando gli hook?
ARF

74

La versione più recente di git scm (testet 2.11.1) consente di abilitare i collegamenti simbolici. Ma devi clonare nuovamente il repository con i collegamenti simbolici git clone -c core.symlinks=true <URL>. È necessario eseguire questo comando con i diritti di amministratore. È anche possibile creare collegamenti simbolici su Windows con mklink. Dai un'occhiata al wiki .

inserisci qui la descrizione dell'immagine


1
Questo non ha funzionato per me. Ho reinstallato git per Windows, ricordati di selezionare la casella di controllo symlink e clonare di nuovo il mio progetto. Il mio tslint.jsonfile che fa riferimento al file nella directory principale contiene ancora ../tslint.json. Peccato, perché sembrava davvero la più semplice di tutte le soluzioni proposte.
Jan Aagaard,

8
@JanAagaard Devi clonarlo in questo modo: git clone -c core.symlinks=true <URL> E su Windows devi eseguirlo con i diritti di amministratore.
Sirlunchalot,

6
@ARF "Avvia gpedit.msc (ovvero l'editor dei criteri di gruppo) e aggiungi gli account alla Configurazione computer \ Impostazioni Windows \ Impostazioni sicurezza \ Criteri locali \ Assegnazione diritti utente \ Crea collegamenti simbolici."
Sirlunchalot,

2
@sirlunchalot Grazie per l'aiuto. Da allora ho capito che il mio problema è che il mio utente fa parte del gruppo Administrators e che questa proprietà non ha alcun effetto per questi utenti. Richiedono elevazione UAC che git non fa.
ARF

9
I diritti di amministratore non sono necessari in "Modalità sviluppatore" in Windows 10 Creators Update. Grazie @dennis nel suo commento .
Dominik,

16

Dovrebbe essere implementato in msysgit, ma ci sono due aspetti negativi:

  • I collegamenti simbolici sono disponibili solo in Windows Vista e versioni successive (non dovrebbe essere un problema nel 2011, eppure lo è ...), poiché le versioni precedenti supportano solo giunzioni di directory.
  • (quello grande) Microsoft considera i collegamenti simbolici un rischio per la sicurezza e quindi solo gli amministratori possono crearli per impostazione predefinita. Dovrai elevare i privilegi del processo git o usare fstool per cambiare questo comportamento su ogni macchina su cui lavori.

Ho fatto una rapida ricerca e si sta lavorando attivamente su questo, vedere il problema 224 .


2
Aggiornamento: per i motivi sopra indicati, il problema è stato chiuso come wontfix. La discussione indica che una correzione potrebbe essere accettata con qualche altro lavoro sulla patch (diciamo, usando i collegamenti simbolici solo se funzionano).
Blaisorblade,

2
R.) attualmente msysgit non supporta affatto i symlink - quindi perché non farlo rilevare "oh sei su Vista con NTFS fammi usare i symlink" o "oh, sei su un sistema operativo che supporta le giunzioni con NTFS, fammi usare quelli ", o" oh, sei su Windows 98 / fat32, lasciami fallire solo per non avere questa funzione e darti invece un avviso! " e poi B.) Praticamente tutti i dev di microsoft. gli strumenti non funzionano correttamente (almeno non per tutte le loro funzionalità) se non li esegui come amministratore - tutti gli addetti all'IT sanno che gli sviluppatori devono essere amministratori nelle proprie caselle.
BrainSlugs83

1
Mentre eseguo determinate macchine nell'account Admin, non seguo quella filosofia sulla mia macchina di sviluppo. Corro sempre come utente normale con UAC abilitato. Tengo aperta una console separata per le operazioni che richiedono privilegi elevati. Per quanto riguarda l'implementazione, dipende da qualcuno (come te) che si offre volontario per implementarlo. Gli sviluppatori di msysgit non sono noti per beneficenza ...
DJ

@djs Un utente deve aprire un prompt dei comandi con "Esegui come amministratore". È quasi letteralmente in esecuzione come Utente amministratore che cambia completamente l'ambiente. Non esiste un modo per eseguire 'mklink / d' come utente che appartiene anche al gruppo Admin. Non verrà richiesto il controllo dell'account utente. Fallirà, sempre. Funziona solo in due modi: letteralmente come l'utente amministratore (RunAs Verb) o un utente non amministratore con modifica dei criteri di gruppo. Le giunzioni dovrebbero essere predefinite e dovrebbero essere riconosciute da tutti gli strumenti. Il "rischio per la sicurezza" è che i collegamenti simbolici su Windows possono "reindirizzare" le condivisioni SMB. Questo è un dolore e crudele.
Andrew T Finnell,

8
Annunciato a dicembre 2016, Symlink in Windows 10 non è più un'azione dell'amministratore. blogs.windows.com/buildingapps/2016/12/02/symlinks-windows-10/…
Dennis

16

quindi poiché le cose sono cambiate con GIT poiché molte di queste risposte sono state pubblicate qui sono le istruzioni corrette per far funzionare correttamente i collegamenti simbolici in Windows a partire da

AGOSTO 2018


1.Assicurati che git sia installato con il supporto symlink

Durante l'installazione di git su windows

2. Di 'a Bash di creare hardlink invece di symlink

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

AGGIUNGI A FONDO - MSYS=winsymlinks:nativestrict

3. Impostare git config per utilizzare i collegamenti simbolici

git config core.symlinks true

o

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

NOTA: ho provato ad aggiungere questo alla configurazione globale di git e al momento non funziona per me, quindi consiglio di aggiungere questo ad ogni repository ...

4. tirare il repository

NOTA: a meno che non sia stata abilitata la modalità sviluppatore nell'ultima versione di Windows 10, è necessario eseguire bash come amministratore per creare collegamenti simbolici

5. Ripristina tutti i collegamenti simbolici (facoltativo) Se si dispone di un repository esistente o si utilizzano sottomoduli, è possibile che i collegamenti simbolici non vengano creati correttamente, quindi per aggiornare tutti i collegamenti simbolici nel repository è possibile eseguire questi comandi.

find -type l -delete
git reset --hard

NOTA: questo ripristinerà tutte le modifiche dall'ultimo commit, quindi assicurati di aver eseguito il commit per primo


15

Risposta breve: ora sono ben supportati se è possibile abilitare la modalità sviluppatore.

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

Ora in Windows 10 Creators Update, un utente (con diritti di amministratore) può prima abilitare la modalità sviluppatore e quindi qualsiasi utente sulla macchina può eseguire il comando mklink senza elevare una console della riga di comando.

Cosa ha guidato questo cambiamento? La disponibilità e l'uso di symlink è un grosso problema per gli sviluppatori moderni:

Molti strumenti di sviluppo popolari come git e gestori di pacchetti come npm riconoscono e persistono collegamenti simbolici durante la creazione di repository o pacchetti, rispettivamente. Quando tali repository o pacchetti vengono quindi ripristinati altrove, vengono ripristinati anche i collegamenti simbolici, garantendo che lo spazio su disco (e il tempo dell'utente) non venga sprecato.

Facile da trascurare con tutti gli altri annunci dell '"Aggiornamento del Creatore", ma se abiliti la Modalità sviluppatore, puoi creare collegamenti simbolici senza privilegi elevati. Potrebbe essere necessario reinstallare git e assicurarsi che il supporto per il collegamento simbolico sia abilitato, poiché non è predefinito.

I collegamenti simbolici non sono abilitati per impostazione predefinita


1
gpedit.msc-> Local Computer Policy-> Computer Configuration-> Windows Settings-> Security Settings-> Local Policies-> User Rights Assignmentè stato il modo canonico di assegnare diritti utente come SeCreateSymbolicLinke amici per anni. Altro che ntrights.exedal Resource Kit o PowerShell ...
0xC0000022L

11

2020 Risposta

  1. Abilita "Modalità sviluppatore" in Windows 10: fornisce mklinkautorizzazioni
  2. Assicurati che i collegamenti simbolici siano abilitati in git
    • git config --global core.symlinks true
    • oppure selezionare la casella di controllo durante l'installazione di msysgit

Il passaggio da una filiale all'altra forzerà la ricreazione di collegamenti simbolici mancanti.

Fai attenzione, il supporto per Symlink su Windows con alcuni altri client Git non è completo. In particolare GitKraken.


Tutti i miei repository locali hanno core.symlinks = false che sovrascriverebbe la tua soluzione. Qualche idea su cosa produca automaticamente questa configurazione locale? Possibilmente installare Git per Windows senza selezionare la casella?
gravid

@gravid Pensi quali client git hai installato? Forse alcuni strumenti stanno facendo questo? È vero su un nuovo clone?
Cameron Tacklind,

10

Suggerirei di non utilizzare i symlink all'interno del repo '. Conservare il contenuto effettivo all'interno del repository e quindi posizionare i collegamenti simbolici all'esterno del repository che puntano al contenuto.

Supponiamo quindi che tu stia utilizzando un repo 'per confrontare l'hosting del tuo sito su * nix con l'hosting su win. Memorizza il contenuto nel tuo repository ', diciamo /httpRepoContente c:\httpRepoContentcon questa è la cartella che è sincronizzata tramite GIT, SVN ecc.

Quindi, sostituisci la cartella del contenuto del tuo server web ( /var/wwwe c:\program files\web server\www{i nomi non contano davvero, modifica se devi}) con un link simbolico al contenuto nel tuo repository '. I server Web vedranno il contenuto come effettivamente nel posto "giusto", ma potrai usare il controllo del codice sorgente.

Tuttavia, se è necessario utilizzare i collegamenti simbolici con nel repository ', sarà necessario esaminare qualcosa come una sorta di script di commit pre / post. So che puoi usarli per fare cose, ad esempio analizzare i file di codice attraverso un formattatore, quindi dovrebbe essere possibile convertire i collegamenti simbolici tra piattaforme.

se qualcuno conosce un buon posto per imparare a fare questi script per i controlli dei sorgenti comuni, SVN GIT MG, quindi si prega di aggiungere un commento.


Alla fine, ho scelto questo approccio per creare una cartella di symlink-out e creare i collegamenti simbolici al punto in cui si trovava il file originale. L'altro approccio non ha funzionato anche dopo aver modificato l'impostazione .git / config core.symlinks = true. Solo il file di collegamento simbolico è stato salvato nel repository e non i dati. Inoltre, si sono verificati problemi con i timestamp della cartella sul collegamento simbolico, quindi git bash non ha mai visto quando un file è cambiato nella cartella.
Uova

@Eggs quello che potresti aver visto, suppongo, è che il link fosse all'interno del repository, e quindi Git lo ha salvato, semplice. Il problema però è che la destinazione era al di fuori del repository e git non segue il collegamento ai dati di destinazione. Su Linux hai un tipo di collegamento che funzionerebbe per questo, in pratica abbiamo due percorsi per gli stessi dati memorizzati sul disco; Ho la sensazione che windows newish possa farlo ora. In ogni caso, comunque, non penso che farà ciò che la gente vuole.
thecoshman,

@thecoshman Questa non è una soluzione, ma una soluzione alternativa. Tuttavia, a volte questa non è un'opzione. Ho un repository con git-annex e tutte le sue opere di architettura a causa di collegamenti simbolici.
marcelo.guedes,

8

Per coloro che utilizzano CygWin su Vista, Win7 o versioni successive, il gitcomando nativo può creare collegamenti simbolici "corretti" riconosciuti dalle app di Windows come Android Studio . Hai solo bisogno di impostare la CYGWINvariabile d'ambiente da includere winsymlinks:nativeo winsymlinks:nativestrictcome tale:

export CYGWIN="$CYGWIN winsymlinks:native"

L'aspetto negativo di questo (e di quello significativo) è che la shell CygWin deve essere "Esegui come amministratore" per avere le autorizzazioni del sistema operativo necessarie per creare quel tipo di symlink. Una volta che sono create, però, autorizzazioni speciali sono tenuti a utilizzare loro. Finché non vengono modificati nel repository da un altro sviluppatore, da quel momento in gitpoi funziona correttamente con le normali autorizzazioni dell'utente.

Personalmente, lo uso solo per i collegamenti simbolici navigati dalle app di Windows (ovvero non CygWin) a causa di questa ulteriore difficoltà.

Per ulteriori informazioni su questa opzione, vedere questa domanda SO: Come creare un collegamento simbolico con cygwin in Windows 7


6

Ecco uno script batch per convertire i collegamenti simbolici nel repository, solo per i file, basato sulla risposta di Josh Lee. Lo script con qualche controllo aggiuntivo per i diritti di amministratore è disponibile su 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

Una risposta non documentata non è davvero molto utile quando sono già presenti risposte così lunghe e dettagliate.
Xennex81,

4

Uso sempre i collegamenti sym tra il mio root del documento e la directory git repo. Mi piace tenerli separati. Su Windows utilizzo l'opzione mklink / j. La giunzione sembra consentire a git di comportarsi normalmente:

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

per esempio:

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


2
Prestare molta attenzione con Esplora risorse e giunzioni; non differenzia le giunzioni dalla posizione di base e un'eliminazione si ripeterà nella destinazione e ne eliminerà il contenuto, mentre l'eliminazione di un collegamento simbolico rimuoverà semplicemente il collegamento simbolico. Solo una trappola per gli incauti.
Lawrence Dol,

5
In realtà, ho appena provato questo sull'ultimo di Windows 7 e non lo fa più, quindi la gestione delle giunzioni è stata migliorata negli ultimi anni.
Lawrence Dol,

3

Stavo cercando una soluzione semplice per gestire i collegamenti simbolici unix su Windows. Grazie mille per i suddetti alias Git. C'è una piccola ottimizzazione che può essere fatta ai rm-symlink in modo che non elimini i file nella cartella di destinazione nel caso in cui l'alias venga eseguito accidentalmente una seconda volta. Si prega di osservare la nuova condizione if nel ciclo per assicurarsi che il file non sia già un collegamento a una directory prima dell'esecuzione della logica.

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 

2

Un semplice trucco che usiamo è semplicemente chiamare git add --alldue volte di seguito.

Ad esempio, le nostre chiamate di script di commit di Windows 7:

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

La prima aggiunta tratta il collegamento come testo e aggiunge le cartelle per l'eliminazione.

La seconda aggiunta attraversa correttamente il collegamento e annulla l'eliminazione ripristinando i file.

È meno elegante di alcune delle altre soluzioni proposte, ma è una semplice correzione per alcuni dei nostri ambienti legacy a cui sono stati aggiunti collegamenti simbolici.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.