Domanda

La soluzione migliore sarà uno script di shell che sostituisca i collegamenti simbolici con copie o esiste 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.

È stato utile?

Soluzione

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


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

Tuttavia, sono riuscito accidentalmente a far sì che aggiungesse file oltre il collegamento simbolico quando il collegamento simbolico è una directory.

Cioè.:

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

facendo

 git add /bar/foo/baz

sembrava funzionare quando l'ho provato.Tuttavia quel comportamento era da me indesiderato in quel momento, quindi non posso darti informazioni oltre a queste.

Altri suggerimenti

Cosa ho fatto per aggiungere i file all'interno di un collegamento simbolico in Git (non ho usato un collegamento simbolico ma):

sudo mount --bind SOURCEDIRECTORY TARGETDIRECTORY

Esegui questo comando nella directory gestita da Git. TARGETDIRECTORY deve essere creato prima del SOURCEDIRECTORY è montato al suo interno.

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, dove un webdesigner fa le sue cose.

Perché non creare collegamenti simbolici al contrario?Significa invece di collegarsi dal repository Git alla directory dell'applicazione, basta collegarsi al contrario.

Ad esempio, supponiamo 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 collegamento simbolico da ~/application correndo ln -s ~/repos/application/config.conf.

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

Utilizzare invece collegamenti reali.Questo differisce da un collegamento morbido (simbolico).Tutti i programmi, compresi git tratterà il file come un file normale.Tieni presente che il contenuto può essere modificato modificando O la fonte o la destinazione.

Su macOS (prima della 10.13 High Sierra)

Se hai già installato git e Xcode, installare il collegamento fisico.E' microscopico strumento per creare collegamenti reali.

Per creare il collegamento reale, semplicemente:

hln source destination

Aggiornamento macOS High Sierra

Apple File System supporta i collegamenti fisici alle directory?

I collegamenti reali alle directory non sono supportati dal file system Apple.Tutti i collegamenti reali alle directory vengono convertiti in collegamenti simbolici o alias quando esegui la conversione dai formati di volume HFS+ a APFS su macOS.

Da Domande frequenti su APFS su Developer.Apple.com

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

Su Linux e altre versioni di Unix

IL ln il comando può creare collegamenti fisici:

ln source destination

Su Windows (Vista, 7, 8, …)

Qualcuno ha suggerito di usarlo mklink creare una giunzione su Windows, ma non l'ho provato:

mklink /j "source" "destination"

Questo è un gancio pre-impegno che sostituisce i BLOB dei collegamenti simbolici nell'indice, con il contenuto di tali collegamenti simbolici.

Inserisci questo .git/hooks/pre-commit, e renderlo 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

Appunti

Utilizziamo il più possibile funzionalità conformi a POSIX;Tuttavia, diff -a non è conforme a POSIX, forse tra le altre cose.

Potrebbero esserci alcuni sbagli/errori in questo codice, anche se è stato in qualche modo testato.

È da un po' di tempo che aggiungo file oltre i collegamenti simbolici.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 git-add permettendogli di seguire nuovamente i collegamenti simbolici.

Mi sono stancato che ogni soluzione qui sia obsoleta o richieda il root, quindi Ho creato una soluzione basata su LD_PRELOAD (Solo Linux).

Si aggancia agli interni di Git, sovrascrivendo "è un collegamento simbolico?" funzione, consentendo i collegamenti simbine di essere trattati come il loro contenuto.Per impostazione predefinita, tutti i collegamenti all'esterno del repository sono incorporati;vedere il collegamento per i dettagli.

Con Git 2.3.2+ (Q1 2015), c'è un altro caso in cui Git non segui più il collegamento simbolico:Vedere commettere 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 qualche altra parte, sia all'interno che all'esterno dell'albero di lavoro) non può mai apparire in una patch validamente applicata, a meno che la stessa patch non rimuova prima il collegamento simbolico per consentire la creazione di una directory lì.

Rileva e rifiuta 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 errore senza effettivamente crearlo path/to/dir collegamento simbolico nel filesystem.

Invece, per qualsiasi patch nell'input che lascia un percorso (ad esempiouna mancata 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 dell'applicazione della patch (l'indice o l'albero di lavoro).

In questo modo:

  • cogliere un errore o un errore nell'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 simbolico link path/to/dir 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

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

Qualcuno ha un trucco che fa?

[modificato]

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

Creazione di collegamenti fisici alle directory in Mac OS X

Godere!

SU 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 <source_dir> local_copy_dir

È stato suggerito da altri commenti, ma non chiaramente fornito in altre risposte.Speriamo che questo faccia risparmiare tempo a qualcuno.

Sto usando Git 1.5.4.3 e segue il collegamento 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/

La conversione dai collegamenti simbolici potrebbe essere utile.Collegamento in una cartella Git anziché in un collegamento simbolico da una sceneggiatura.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top