Come posso ottenere git per seguire i link simbolici?

Ho avuto un google per come farlo, ma non ho avuto fortuna.

Il mio migliore sarà uno script di shell che sostituisce i collegamenti simbolici con le copie, o c’è un altro modo per dire a git di seguire i collegamenti simbolici?

PS: So che non è molto sicuro, ma voglio solo farlo in alcuni casi specifici.

NOTA: questo avviso è ormai obsoleto come da commento da git 1.6.1 . Git si comportava in questo modo, e non lo fa più.


Git di default tenta di memorizzare i collegamenti simbolici invece di seguirli (per compattezza, ed è generalmente ciò che le persone vogliono)

Tuttavia, ho accidentalmente riuscito a farlo aggiungere file oltre il link simbolico quando il link simbolico è una directory.

vale a dire:

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

facendo

  git add /bar/foo/baz 

sembrava funzionare quando ho provato, quel comportamento era comunque indesiderato da me al momento, quindi non posso darti informazioni oltre a questo.

Cosa ho fatto per aggiungere i file con un link simbolico a git (non ho usato un link simbolico ma):

 sudo mount --bind SOURCEDIRECTORY TARGETDIRECTORY 

fai questo comando nella directory gestita da git. TARGETDIRECTORY deve essere creato prima che venga montato SOURCEDIRECTORY .

Funziona bene su Linux ma non su OS X! quel trucco mi ha aiutato anche con la sovversione. Lo uso per includere file da un account Dropbox, in cui un webdesigner fa la sua roba.

Perché non creare collegamenti simbolici al contrario? Significa invece di colbind dal repository git alla directory dell’applicazione, basta colbind il contrario.

per esempio diciamo che sto configurando un’applicazione installata in ~/application che ha bisogno di un file di configurazione config.conf

  • Aggiungo config.conf al mio repository git ad esempio in ~/repos/application/config.conf
  • poi creo un link simbolico da ~/application eseguendo ln -s ~/repos/application/config.conf

Questo approccio potrebbe non funzionare sempre, ma ha funzionato bene per me finora.

Utilizzare invece i collegamenti fisici. Questo differisce da un collegamento (simbolico) morbido. Tutti i programmi, incluso git , tratteranno il file come un normale file. Si noti che il contenuto può essere modificato cambiando l’origine o la destinazione.

Su macOS (prima di 10.13 High Sierra)

Se hai già installato git e Xcode, installa hardlink . È uno strumento microscopico per creare collegamenti fisici .

Per creare il collegamento fisico, semplicemente:

 hln source destination 

aggiornamento macOS High Sierra

Apple File System supporta i collegamenti hardware delle directory?

I collegamenti hardware della directory non sono supportati da Apple File System. Tutti i collegamenti hardware delle directory vengono convertiti in collegamenti simbolici o alias quando si converte da HFS + in formati di volume APFS su macOS.

Dalle domande frequenti su APFS su developer.apple.com

Segui https://github.com/selkhateeb/hardlink/issues/31 per alternative future.

Su Linux e altri sapori Unix

Il comando ln può creare collegamenti fisici:

 ln source destination 

Su Windows (Vista, 7, 8, …)

Qualcuno ha suggerito di usare mklink per creare un nodo su Windows, ma non l’ho provato:

 mklink /j "source" "destination" 

Questo è un hook pre-commit che sostituisce i BLOB symlink nell’indice, con il contenuto di tali collegamenti simbolici.

Metti questo in .git/hooks/pre-commit e rendilo eseguibile:

 #!/bin/sh # (replace "find ." with "find ./" 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 

Gli appunti

Usiamo il più ansible le funzionalità conformi a POSIX; tuttavia, diff -a non è conforms a POSIX, probabilmente tra le altre cose.

Ci possono essere alcuni errori / errori in questo codice, anche se è stato testato un po ‘.

Ho usato per aggiungere file oltre i collegamenti simbolici per un bel po ‘di tempo. Questo funzionava perfettamente, senza prendere accordi particolari. Da quando ho aggiornato a git 1.6.1, questo non funziona più.

Potresti essere in grado di passare a git 1.6.0 per farlo funzionare. Spero che una versione futura di git abbia un flag per git-add che consenta di seguire nuovamente i link simbolici.

Con Git 2.3.2+ (1 ° trimestre 2015), c’è un altro caso in cui Git non seguirà più symlink: vedi commit e0d201b di Junio ​​C Hamano ( gitster ) (manutentore principale di Git)

apply : non toccare un file oltre un collegamento simbolico

Poiché Git tiene traccia dei collegamenti simbolici come collegamenti simbolici, un percorso che ha un collegamento simbolico nella sua parte principale (ad es. path/to/dir/file , dove path/to/dir è un collegamento simbolico a un’altra parte, sia all’interno che all’esterno del albero di lavoro) non può mai apparire in una patch che si applica validamente, a meno che la stessa patch rimuova prima il collegamento simbolico per consentire la creazione di una directory lì.

Rileva e respingi tale patch.

Allo stesso modo, quando un input crea un link simbolico path/to/dir e quindi crea un path/to/dir/file file path/to/dir/file , dobbiamo contrassegnarlo come un errore senza creare effettivamente un link simbolico path/to/dir nel filesystem.

Invece, per ogni patch nell’input che lascia un path (cioè una non eliminazione) nel risultato, controlliamo tutti i percorsi principali rispetto all’albero risultante che la patch creerebbe controllando tutte le patch nell’input e quindi la destinazione della patch applicazione (l’indice o l’albero di lavoro).

In questo modo, noi:

  • prendere un danno o un errore per aggiungere un path/to/dir simbolico di collegamento path/to/dir e un path/to/dir/file file path/to/dir/file allo stesso tempo,
  • pur consentendo una patch valida che rimuove un link path/to/dir simbolico link path/to/dir e quindi aggiunge un path/to/dir/file file path/to/dir/file .

Ciò significa che, in tal caso, il messaggio di errore non sarà generico come "%s: patch does not apply" , ma uno più specifico:

 affected file '%s' is beyond a symbolic link 

hmmm mount –bind non sembra funzionare su Darwin.

Qualcuno ha un trucco che fa?

[modificato]

OK ho trovato la risposta su OSX è di creare un collegamento. Tranne che l’API non è esposta tramite ln quindi devi usare il tuo piccolo programma per farlo. Ecco un link a quel programma:

Creazione di collegamenti hardware di directory in MacOS X?

Godere!

Mi sono stancato che ogni soluzione qui fosse obsoleta o richiedesse root, quindi ho creato una soluzione basata su LD_PRELOAD .

Sto usando git 1.5.4.3 e sta seguendo il link simbolico passato se ha una barra finale. Per esempio

 # adds the symlink itself $ git add symlink # follows symlink and adds denoted directory's contents $ git add symlink/ 

La conversione dai link simbolici sarebbe utile? collega nella cartella git invece un link simbolico, da uno script