it-swarm.it

Come posso convincere Git a seguire i collegamenti simbolici?

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.

174
Matt

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 in quel momento, quindi non posso darti informazioni al di là di questo.

37
Kent Fredric

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

Esegui questo comando nella directory gestita da Git. TARGETDIRECTORY deve essere creato prima che SOURCEDIRECTORY sia montato su di esso.

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.

124
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, diciamo che sto configurando un'applicazione installata in ~/application che necessita di un file di configurazione config.conf:

  • Aggiungo config.conf al mio repository Git, ad esempio, su ~/repos/application/config.conf.
  • Quindi 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.

65
spier

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

Su macOS (prima di 10.13 High Sierra)

Se hai già installato git e Xcode, installa hardlink . È un microscopico strumento 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 delle directory non sono supportati da Apple File System. Tutti i collegamenti hard di directory vengono convertiti in collegamenti simbolici o alias quando si converte da HFS + in formati di volume APFS su macOS.

From APFS FAQ 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 creare un bivio su Windows, ma non l'ho provato:

mklink /j "source" "destination"
41
bfred.it

Questo è un pre-commit hook 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 ./<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

Gli appunti

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

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

16
Abbafei

Ho usato per aggiungere file oltre i collegamenti simbolici per un bel po 'di tempo. Questo funzionava benissimo, 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 gli consenta di seguire nuovamente i link simbolici.

12
Erik Schnetter

Con Git 2.3.2+ (1 ° trimestre 2015), c'è un altro caso in cui Git seguirà not seguire symlink più: vedi commit e0d201b by 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 esempio path/to/dir/file, dove path/to/dir è un collegamento simbolico a qualche altra parte, sia all'interno che all'esterno dell'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 collegamento simbolico path/to/dir e quindi crea un file path/to/dir/file, dobbiamo contrassegnarlo come un errore senza creare effettivamente il 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 contro l'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 errore o un errore per aggiungere un collegamento simbolico path/to/dir e un file path/to/dir/file allo stesso tempo, 
  • pur consentendo una patch valida che rimuove un link path/to/dir simbolico e quindi aggiunge un 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
6
VonC

Mi sono stancato che ogni soluzione qui fosse obsoleta o richiedesse root, quindi Ho creato una soluzione basata su LD_PRELOAD (solo Linux).

Si aggancia agli interni di Git, ignorando il 'è questo un link simbolico?' funzione, consentendo ai link simbolici di essere trattati come i loro contenuti. Per impostazione predefinita, tutti i collegamenti all'esterno del repository sono in linea; vedi il link per i dettagli.

5
Alcaro

Hmmm, mount --bind non sembra funzionare su Darwin.

Qualcuno ha un trucco che fa?

[modificato]

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

Creazione di collegamenti hard di directory in Mac OS X

Godere!

4
J Chris A

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/
1
artistoex

Su MacOS, usa bindfs

brew install bindfs

cd /path/to/git_controlled_dir 

mkdir local_copy_dir

bindfs <source_dir> local_copy_dir

È stato suggerito da altri commenti, ma non è chiaramente fornito in altre risposte. Spero che questo salvi qualcuno da qualche tempo. 

0
ijoseph

La conversione da link simbolici potrebbe essere utile. Collega in una cartella Git invece di un link simbolico da uno script .

0
Yurij73