Il mio meglio sarà uno script di shell che sostituisca 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 farlo solo in alcuni casi specifici.
Il mio meglio sarà uno script di shell che sostituisca 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 farlo solo in alcuni casi specifici.
Risposte:
NOTA: questo consiglio è ora obsoleto come da commento da Git 1.6.1. Git si comportava in questo modo e non lo fa più.
Git cerca di default di memorizzare i collegamenti simbolici invece di seguirli (per compattezza, ed è generalmente ciò che la gente vuole).
Tuttavia, sono riuscito accidentalmente a convincerlo ad aggiungere file oltre il collegamento simbolico quando il collegamento simbolico è una directory.
Vale a dire:
/foo/
/foo/baz
/bar/foo --> /foo
/bar/foo/baz
facendo
git add /bar/foo/baz
sembrava funzionare quando l'ho provato. Quel comportamento era comunque indesiderato da me in quel momento, quindi non posso darti informazioni oltre a ciò.
Cosa ho fatto per aggiungere i file all'interno di un collegamento simbolico in Git (ma non ho usato un collegamento simbolico):
sudo mount --bind SOURCEDIRECTORY TARGETDIRECTORY
Esegui questo comando nella directory gestita da Git. TARGETDIRECTORYdeve essere creato prima del SOURCEDIRECTORYmontaggio.
Funziona bene su Linux, ma non su OS X! Quel trucco mi ha aiutato anche con Subversion. Lo uso per includere file da un account Dropbox, in cui un webdesigner fa le sue cose.
umount [mydir]. (+1 per il tuo fantastico suggerimento, @ user252400)
Perché non creare collegamenti simbolici al contrario? Significa invece di collegare dal repository Git alla directory dell'applicazione, basta collegare il contrario.
Ad esempio, supponiamo che sto configurando un'applicazione installata in ~/applicationcui è necessario un file di configurazione config.conf:
config.confal mio repository Git, ad esempio, su ~/repos/application/config.conf.~/applicationeseguendo ln -s ~/repos/application/config.conf.Questo approccio potrebbe non funzionare sempre, ma finora ha funzionato bene per me.
Utilizzare invece i collegamenti reali. Ciò differisce da un collegamento soft (simbolico). Tutti i programmi, incluso gittratteranno il file come un file normale. Si noti che i contenuti possono essere modificati cambiando sia l'origine o la destinazione.
Se hai già installato git e Xcode, installa hardlink . È uno strumento microscopico per creare collegamenti reali .
Per creare il collegamento reale, semplicemente:
hln source destination
Il file system Apple supporta i collegamenti hard della directory?
I collegamenti diretti alle directory non sono supportati dal file system Apple. Tutti i collegamenti diretti alla directory vengono convertiti in collegamenti simbolici o alias quando si converte da HFS + in formati di volume APFS su macOS.
Segui https://github.com/selkhateeb/hardlink/issues/31 per alternative future.
Il lncomando può creare collegamenti reali:
ln source destination
Qualcuno ha suggerito di usare mklink per creare un nodo su Windows, ma non l'ho provato:
mklink /j "source" "destination"
ln source destinationfunziona anche in OS X. Testato su El Capitan.
cp -al source destination. `-l 'significa file con collegamento reale anziché copia.
Questo è un hook pre-commit che sostituisce i BLOB di link simbolici nell'indice, con il contenuto di tali link simbolici.
Inseriscilo .git/hooks/pre-commite rendilo eseguibile:
#!/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
Utilizziamo la funzionalità conforme POSIX il più possibile; tuttavia, diff -anon è conforme a POSIX, probabilmente tra le altre cose.
Potrebbero esserci alcuni errori / errori in questo codice, anche se è stato testato in qualche modo.
typechangein git statusper i file che sono in realtà i collegamenti simbolici se git ora le cose non lo sono.
process_links_to_nondir?
argv[0]che viene utilizzato come nome-comando per il shprocesso. (Mi ha preso un po 'per capirlo, dal momento che non ricordavo nemmeno cosa fosse ☺😃)
find: missing argument to -exec'. Potrebbe essere necessaria l'esecuzione di un comando passo dopo passo invece di eseguire il piping e combinare tutto in un'unica riga.
typechangetipo @DavidFraser, ma il file collegato sembra non essere più messo in scena)
Sì MacOS(ho Mojave / 10.14, gitversione 2.7.1), utilizzare bindfs.
brew install bindfs
cd /path/to/git_controlled_dir
mkdir local_copy_dir
bindfs </full/path/to/source_dir> </full/path/to/local_copy_dir>
È stato suggerito da altri commenti, ma non è stato chiaramente fornito in altre risposte. Spero che questo faccia risparmiare tempo a qualcuno.
Failed to resolve... No such file or directoryerrori a meno che non avessi usato i nomi di percorso completi con il bindfscomando.
Da un po 'di tempo aggiungevo file oltre i link simbolici. In passato funzionava perfettamente, senza prendere accordi speciali. 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 una bandiera che git-addconsenta di seguire di nuovo i symlink.
Mi sono stancato di ogni soluzione qui obsoleta o che richiedeva root, quindi ho creato una soluzione basata su LD_PRELOAD (solo Linux).
Si aggancia agli interni di Git, sovrascrivendo "è questo un link simbolico?" funzione, che consente ai symlink di essere trattati come i loro contenuti. Per impostazione predefinita, tutti i collegamenti all'esterno del repository sono in linea; vedere il link per i dettagli.
LD_PRELOADper sovrascrivere le funzioni di libreria!
Con Git 2.3.2+ (Q1 2015), c'è un altro caso in cui Git non seguirà più il collegamento simbolico: vedi commit e0d201b di Junio C Hamano ( gitster) (manutentore principale di Git)
apply: non toccare un file oltre un collegamento simbolicoPoiché Git tiene traccia dei collegamenti simbolici come collegamenti simbolici, un percorso che ha un collegamento simbolico nella sua parte principale (ad esempio
path/to/dir/file, dove sipath/to/dirtrova un collegamento simbolico verso un altro luogo, all'interno o all'esterno dell'albero di lavoro) non può mai apparire in una patch che si applica validamente , a meno che la stessa patch non rimuova prima il collegamento simbolico per consentire la creazione di una directory lì.Rileva e rifiuta una tale patch.
Allo stesso modo, quando un input crea un collegamento simbolico
path/to/dire quindi crea un filepath/to/dir/file, dobbiamo contrassegnarlo come errore senza effettivamente crearepath/to/dirun collegamento simbolico nel filesystem.Invece, per qualsiasi patch nell'input che lascia un percorso (cioè una non cancellazione) 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:
- intercettare un errore o un errore per aggiungere contemporaneamente un collegamento simbolico
path/to/dire un filepath/to/dir/file,- pur consentendo una patch valida che rimuove un simbolico
link path/to/dire quindi aggiunge un filepath/to/dir/file.
Ciò significa che, in tal caso, il messaggio di errore non sarà simile a un generico "%s: patch does not apply", ma più specifico:
affected file '%s' is beyond a symbolic link
Hmmm, mount --bindnon sembra funzionare su Darwin.
Qualcuno ha un trucco che ha?
[modificato]
OK, ho trovato la risposta su Mac OS X è quella di creare un collegamento reale. Solo 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 hard directory in Mac OS X.
Godere!
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 the denoted directory's contents
$ git add symlink/
fatal: 'src/' is beyond a symbolic link
La conversione da symlink potrebbe essere utile. Collegamento in una cartella Git invece di un collegamento simbolico di uno script .