Pregunta

¿Lo mejor será un script de shell que reemplace los 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 sólo quiero hacerlo en algunos casos específicos.

¿Fue útil?

Solución

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.


De forma predeterminada, Git intenta almacenar enlaces simbólicos en lugar de seguirlos (por razones de compacidad, y generalmente es lo que la gente quiere).

Sin embargo, accidentalmente logré que agregara 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

pareció funcionar cuando lo probé.Sin embargo, ese comportamiento no fue deseado por mí en ese momento, por lo que no puedo brindarle información más allá de eso.

Otros consejos

Lo que hice para agregar para obtener los archivos dentro de un enlace simbólico en Git (pero no usé un enlace simbólico):

sudo mount --bind SOURCEDIRECTORY TARGETDIRECTORY

Realice este comando en el directorio administrado por Git. TARGETDIRECTORY tiene que ser creado antes de SOURCEDIRECTORY está montado 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.

¿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 vincule al revés.

Por ejemplo, digamos que estoy configurando una aplicación instalada en ~/application que necesita un archivo de configuración config.conf:

  • añado config.conf a mi repositorio Git, por ejemplo, en ~/repos/application/config.conf.
  • Luego creo un enlace simbólico desde ~/application mediante la ejecución ln -s ~/repos/application/config.conf.

Puede que este enfoque no siempre funcione, pero hasta ahora me ha funcionado bien.

Utilice enlaces físicos en su lugar.Esto difiere de un vínculo suave (simbólico).Todos los programas, incluidos git tratará el archivo como un archivo normal.Tenga en cuenta que el contenido se puede modificar cambiando cualquiera el origen o el destino.

En macOS (antes de 10.13 High Sierra)

Si ya tienes instalado git y Xcode, instalar enlace duro.es un microscópico herramienta para crear enlaces duros.

Para crear el enlace físico, simplemente:

hln source destination

Actualización de macOS High Sierra

¿Apple File System admite enlaces físicos de directorios?

Los enlaces físicos del directorio no son compatibles con el sistema de archivos de Apple.Todos los enlaces físicos del directorio se convierten en enlaces simbólicos o alias cuando convierte de formatos de volumen HFS+ a APFS en macOS.

De Preguntas frecuentes sobre APFS en desarrollador.apple.com

Seguir https://github.com/selkhateeb/hardlink/issues/31 para futuras alternativas.

En Linux y otras versiones de Unix

El ln El comando puede crear enlaces duros:

ln source destination

En Windows (Vista, 7, 8,…)

Alguien sugirió usar enlace mk cree una unión en Windows, pero no lo he probado:

mklink /j "source" "destination"

Esto es un gancho de precompromiso 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 hacerlo 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

Notas

Utilizamos 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 en este código, a pesar de que se probó un poco.

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 puedas cambiar a Git 1.6.0 para que esto funcione.Espero que una versión futura de Git tenga una bandera para git-add permitiéndole seguir enlaces simbólicos nuevamente.

Me cansé de que todas las soluciones aquí estuvieran desactualizadas o requirieran root, así que Hice una solución basada en LD_PRELOAD (Solo Linux).

Se conecta a las partes internas de Git, anulando el '¿Es esto un enlace simbólico?' función, permitiendo que los enlaces simbólicos se traten como su contenido.De forma predeterminada, todos los enlaces externos al repositorio están integrados;vea el enlace para más detalles.

Con Git 2.3.2+ (Q1 2015), hay otro caso en el que Git no seguir el enlace simbólico nunca más:ver cometer e0d201b por Junio ​​C Hamano (gitster) (mantenedor principal de Git)

apply:no toque un archivo más allá de un enlace simbólico

Debido a que Git rastrea enlaces simbólicos como enlaces simbólicos, una ruta que tiene un enlace simbólico en su parte inicial (p. ej. path/to/dir/file, dónde path/to/dir es 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 válidamente, a menos que el mismo parche elimine primero el enlace simbólico para permitir que se cree un directorio allí.

Detecte y rechace dicho parche.

De manera similar, cuando una entrada crea un enlace simbólico path/to/dir y luego crea un archivo path/to/dir/file, debemos marcarlo como un error sin crear realmente path/to/dir Enlace simbólico en el sistema de archivos.

En cambio, para cualquier parche en la entrada que deje una ruta (es decir,una no eliminación) en el resultado, verificamos todas las rutas principales con el árbol resultante que crearía el parche inspeccionando todos los parches en la entrada y luego el destino de la aplicación del parche (ya sea el índice o el árbol de trabajo).

De esta manera, nosotros:

  • detectar una travesura o un error para agregar un enlace simbólico path/to/dir y un archivo path/to/dir/file al mismo tiempo,
  • al mismo tiempo que permite un parche válido que elimina un símbolo link path/to/dir y luego agrega un archivo path/to/dir/file.

Eso significa que, en ese caso, el mensaje de error no será genérico como "%s: patch does not apply", pero uno más específico:

affected file '%s' is beyond a symbolic link

Mmm, mount --bind no parece funcionar en Darwin.

¿Alguien tiene un truco que lo haga?

[editado]

Bien, encontré que la respuesta en Mac OS X es crear un enlace físico.Excepto que esa API no está expuesta a través de ln, por lo que debes usar tu propio pequeño programa para hacer esto.Aquí hay un enlace a ese programa:

Crear enlaces duros de directorio en Mac OS X

¡Disfrutar!

En MacOS (Tengo Mojave/ 10.14, git versión 2.7.1), utilice bindfs.

brew install bindfs

cd /path/to/git_controlled_dir

mkdir local_copy_dir

bindfs <source_dir> local_copy_dir

Otros comentarios lo han insinuado, pero no se proporciona claramente en otras respuestas.Esperemos que esto le ahorre a alguien algo de tiempo.

Estoy usando Git 1.5.4.3 y sigo el enlace simbólico pasado si tiene una barra diagonal.P.ej.

# Adds the symlink itself
$ git add symlink

# Follows symlink and adds the denoted directory's contents
$ git add symlink/

La conversión a partir de enlaces simbólicos podría resultar útil.Enlace en una carpeta de Git en lugar de un enlace simbólico por un guión.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top