¿Será mejor que sea un script de shell que reemplace enlaces simbólicos con copias, o hay otra forma de decirle a Git que siga los enlaces simbólicos?
PD: Sé que no es muy seguro, pero solo quiero hacerlo en algunos casos específicos.
¿Será mejor que sea un script de shell que reemplace enlaces simbólicos con copias, o hay otra forma de decirle a Git que siga los enlaces simbólicos?
PD: Sé que no es muy seguro, pero solo quiero hacerlo en algunos casos específicos.
Respuestas:
NOTA: Este consejo ahora está desactualizado según el comentario desde Git 1.6.1. Git solía comportarse de esta manera, y ya no lo hace.
Git intenta de forma predeterminada almacenar enlaces simbólicos en lugar de seguirlos (por compacidad, y generalmente es lo que la gente quiere).
Sin embargo, accidentalmente logré agregar archivos más allá del enlace simbólico cuando el enlace simbólico es un directorio.
Es decir:
/foo/
/foo/baz
/bar/foo --> /foo
/bar/foo/baz
haciendo
git add /bar/foo/baz
parecía funcionar cuando lo probé. Sin embargo, ese comportamiento no era deseado por mí en ese momento, por lo que no puedo darle más información.
Lo que hice para agregar los archivos dentro de un enlace simbólico a Git (no usé un enlace simbólico pero):
sudo mount --bind SOURCEDIRECTORY TARGETDIRECTORY
Ejecute este comando en el directorio administrado por Git. TARGETDIRECTORY
tiene que ser creado antes de que SOURCEDIRECTORY
se monte en él.
¡Funciona bien en Linux, pero no en OS X! Ese truco también me ayudó con Subversion. Lo uso para incluir archivos de una cuenta de Dropbox, donde un diseñador web hace sus cosas.
umount [mydir]
. (+1 por tu gran consejo, @ user252400)
¿Por qué no crear enlaces simbólicos al revés? Es decir, en lugar de vincular desde el repositorio de Git al directorio de la aplicación, simplemente vincula al revés.
Por ejemplo, supongamos que estoy configurando una aplicación instalada ~/application
que necesita un archivo de configuración config.conf
:
config.conf
a mi repositorio Git, por ejemplo, en ~/repos/application/config.conf
.~/application
ejecutando ln -s ~/repos/application/config.conf
.Es posible que este enfoque no siempre funcione, pero hasta ahora funcionó bien para mí.
Use enlaces duros en su lugar. Esto difiere de un enlace suave (simbólico). Todos los programas, incluido git
, tratarán el archivo como un archivo normal. Tenga en cuenta que los contenidos pueden ser modificados por el cambio , ya sea el origen o el destino.
Si ya tiene instalado git y Xcode, instale hardlink . Es una herramienta microscópica para crear enlaces duros .
Para crear el enlace duro, simplemente:
hln source destination
¿Apple File System admite enlaces duros de directorio?
Los enlaces duros de directorio no son compatibles con Apple File System. Todos los enlaces duros de directorio se convierten en enlaces simbólicos o alias cuando convierte de HFS + a formatos de volumen APFS en macOS.
Siga https://github.com/selkhateeb/hardlink/issues/31 para futuras alternativas.
El ln
comando puede hacer enlaces duros:
ln source destination
Alguien sugirió usar mklink para crear una unión en Windows, pero no lo he probado:
mklink /j "source" "destination"
ln source destination
también funciona en OS X. Probado en El Capitan.
cp -al source destination
. `-l 'significa archivos de enlace duro en lugar de copiar.
Este es un enlace previo a la confirmación que reemplaza los blobs de enlaces simbólicos en el índice, con el contenido de esos enlaces simbólicos.
Pon esto en .git/hooks/pre-commit
y hazlo ejecutable:
#!/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
Utilizamos la funcionalidad compatible con POSIX tanto como sea posible; sin embargo, diff -a
no es compatible con POSIX, posiblemente entre otras cosas.
Puede haber algunos errores / errores en este código, aunque se haya probado un poco.
typechange
en git status
los archivos que en realidad son enlaces simbólicos aunque git ahora las cosas que no son.
process_links_to_nondir
?
argv[0]
que se utiliza como nombre de comando para el sh
proceso. (Me tomó un poco entenderlo, ya que tampoco recordaba lo que era ☺😃)
find: missing argument to -exec'
. Puede ser necesario ejecutar un comando paso a paso en lugar de canalizar y combinar todo en una sola línea.
typechange
gusta @DavidFraser, pero el archivo vinculado parece que ya no está en escena)
Encendido MacOS
(tengo Mojave / 10.14, git
versión 2.7.1), use 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>
Ha sido insinuado por otros comentarios, pero no se proporciona claramente en otras respuestas. Esperemos que esto ahorre algo de tiempo.
Failed to resolve
... No such file or directory
errores a menos que use nombres de ruta completos con el bindfs
comando.
Solía agregar archivos más allá de los enlaces simbólicos desde hace bastante tiempo. Esto solía funcionar bien, sin hacer ningún arreglo especial. Desde que actualicé a Git 1.6.1, esto ya no funciona.
Es posible que pueda cambiar a Git 1.6.0 para que esto funcione. Espero que una versión futura de Git tenga una bandera git-add
que le permita seguir enlaces simbólicos nuevamente.
Me cansé de que todas las soluciones aquí estuvieran desactualizadas o requirieran root, así que creé una solución basada en LD_PRELOAD (solo Linux).
Se engancha en las partes internas de Git, anulando el '¿es esto un enlace simbólico?' función, permitiendo que los enlaces simbólicos sean tratados como sus contenidos. Por defecto, todos los enlaces externos al repositorio están en línea; ver el enlace para más detalles.
LD_PRELOAD
para anular las funciones de la biblioteca.
Con Git 2.3.2+ (Q1 2015), hay otro caso en el que Git ya no seguirá el enlace simbólico: consulte commit e0d201b de Junio C Hamano ( gitster
) (principal mantenedor de Git)
apply
: no toque un archivo más allá de un enlace simbólicoDebido a que Git rastrea enlaces simbólicos como enlaces simbólicos, una ruta que tiene un enlace simbólico en su parte principal (por ejemplo
path/to/dir/file
, dondepath/to/dir
hay un enlace simbólico a otro lugar, ya sea dentro o fuera del árbol de trabajo) nunca puede aparecer en un parche que se aplique de manera válida , a menos que el mismo parche elimine primero el enlace simbólico para permitir que se cree un directorio allí.Detectar y rechazar tal parche.
Del mismo modo, cuando una entrada crea un enlace simbólico
path/to/dir
y luego crea un archivopath/to/dir/file
, debemos marcarlo como un error sin crear realmentepath/to/dir
un enlace simbólico en el sistema de archivos.En cambio, para cualquier parche en la entrada que deja una ruta (es decir, una no eliminación) en el resultado, verificamos todas las rutas principales contra el árbol resultante que el parche crearía al inspeccionar todos los parches en la entrada y luego el objetivo del parche aplicación (ya sea el índice o el árbol de trabajo).
De esta manera, nosotros:
- detectar una travesura o un error al agregar un enlace simbólico
path/to/dir
y un archivopath/to/dir/file
al mismo tiempo,- mientras permite un parche válido que elimina un símbolo
link path/to/dir
y luego agrega un archivopath/to/dir/file
.
Eso significa que, en ese caso, el mensaje de error no será genérico "%s: patch does not apply"
, sino más específico:
affected file '%s' is beyond a symbolic link
Hmmm, mount --bind
no parece funcionar en Darwin.
¿Alguien tiene un truco que tenga?
[editado]
OK, encontré que la respuesta en Mac OS X es hacer un enlace duro. Excepto que esa API no está expuesta a través de ln
, por lo que debe usar su propio pequeño programa para hacer esto. Aquí hay un enlace a ese programa:
Crear enlaces de directorio en Mac OS X
¡Disfrutar!
Estoy usando Git 1.5.4.3 y sigue el enlace simbólico pasado si tiene una barra inclinada final. P.ej
# 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 conversión de enlaces simbólicos podría ser útil. Enlace en una carpeta Git en lugar de un enlace simbólico mediante un script .