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. TARGETDIRECTORY
deve essere creato prima del SOURCEDIRECTORY
montaggio.
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 ~/application
cui è necessario un file di configurazione config.conf
:
config.conf
al mio repository Git, ad esempio, su ~/repos/application/config.conf
.~/application
eseguendo 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 git
tratteranno 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 ln
comando 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 destination
funziona 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-commit
e 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 -a
non è conforme a POSIX, probabilmente tra le altre cose.
Potrebbero esserci alcuni errori / errori in questo codice, anche se è stato testato in qualche modo.
typechange
in git status
per 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 sh
processo. (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.
typechange
tipo @DavidFraser, ma il file collegato sembra non essere più messo in scena)
Sì MacOS
(ho Mojave / 10.14, git
versione 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 directory
errori a meno che non avessi usato i nomi di percorso completi con il bindfs
comando.
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-add
consenta 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_PRELOAD
per 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/dir
trova 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/dir
e quindi crea un filepath/to/dir/file
, dobbiamo contrassegnarlo come errore senza effettivamente crearepath/to/dir
un 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/dir
e un filepath/to/dir/file
,- pur consentendo una patch valida che rimuove un simbolico
link path/to/dir
e 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 --bind
non 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 .