Rsync incluye una opción ingeniosa --cvs-exclude
para "ignorar archivos de la misma manera que lo hace CVS", pero CVS ha estado obsoleto durante años. ¿Hay alguna forma de hacer que también excluya archivos que serían ignorados por los sistemas de control de versiones modernos (Git, Mercurial, Subversion)?
Por ejemplo, tengo muchos proyectos de Maven extraídos de GitHub. Por lo general, incluyen una .gitignore
lista al menos target
, el directorio de compilación predeterminado de Maven (que puede estar presente en el nivel superior o en submódulos). Dado que el contenido de estos directorios es completamente desechable y pueden ser mucho más grandes que el código fuente, me gustaría excluirlos al usar rsync para las copias de seguridad.
Por supuesto que puedo explícitamente, --exclude=target/
pero eso suprimirá accidentalmente directorios no relacionados que simplemente tienen un nombre target
y no se supone que deben ignorarse.
Y podría proporcionar una lista completa de rutas absolutas para todos los nombres de archivo y los patrones mencionadas en cualquiera de .gitignore
, .hgignore
o svn:ignore
la propiedad en mi disco, pero esto sería una lista enorme que tendría que ser producida por una especie de guión.
Dado que rsync no tiene soporte incorporado para las comprobaciones de VCS que no sean CVS, ¿hay algún buen truco para alimentarlo con sus patrones de ignorar? ¿O algún tipo de sistema de devolución de llamada mediante el cual se le puede preguntar a un script de usuario si un archivo / directorio determinado debe incluirse o no?
Actualización : --filter=':- .gitignore'
como sugiere LordJavac, parece funcionar tan bien para Git como --filter=:C
para CVS, al menos en los ejemplos que he encontrado, aunque no está claro si la sintaxis es una coincidencia exacta. --filter=':- .hgignore'
no funciona muy bien para Mercurial; por ejemplo, rsync no reconoce como expresión regular un que .hgignore
contenga una línea como ^target$
(el equivalente Mercurial de Git /target/
). Y nada parece funcionar para Subversion, para lo cual tendría que analizar .svn/dir-prop-base
una copia de trabajo 1.6 o anterior, y levantar las manos consternado por una copia de trabajo 1.7 o posterior.
:-
significa exactamente? ¿Qué significa el colon? ¿Qué diablos?check-ignore
subcomando que puede lidiar con el arduo trabajo de analizar los distintos archivos "ignorar", si desea utilizar la opción "generar una lista de todos los archivos no ignorados". Mi respuesta aquí da detalles de cómo hacer eso.Respuestas:
Como lo mencionó luksan, puede hacer esto con el
--filter
cambio arsync
.--filter=':- .gitignore'
Logré esto con (hay un espacio antes de ".gitignore") que dicersync
hacer una fusión de directorio con.gitignore
archivos y hacer que se excluyan según las reglas de git. Es posible que también desee agregar su archivo de ignorar global, si tiene uno. Para que sea más fácil de usar, creé un alias en elrsync
que se incluía el filtro.fuente
--exclude='/.git' --filter="dir-merge,- .gitignore"
rsync -rvv --exclude='.git*' --exclude='/rsync-to-dev.sh' --filter='dir-merge,-n /.gitignore' $DIR/ development.foobar.com:~/test/
.. pero aunque dice[sender] hiding file .gitignore because of pattern .git*
, el archivo todavía se envía a la destinación--delete
la opción, aquí está la línea de comandos de trabajo:rsync --delete-after --filter=":e- .gitignore" --filter "- .git/" -v -a ...
. Esto me tomó un tiempo ...e
en filtro y--delete-after
ambos son importantes. Sugiero leer el capítulo "REGLAS PER-DIRECTORIO Y ELIMINAR" de larsync
página de manual.--delete-after
a la versión del comando de @ VasiliNovikov. (Esto parece equivalente a la versión del comando de @ dboliton, excepto que @db usa: e, que creo que excluye los archivos .gitignore para que no se copien, que no es lo que yo quería.)Puede utilizar
git ls-files
para crear la lista de archivos excluidos por los archivos del repositorio.gitignore
. https://git-scm.com/docs/git-ls-filesOpciones:
--exclude-standard
Considere todos los.gitignore
archivos.-o
No ignore los cambios sin etapas.-i
Salida solo archivos ignorados.--directory
Solo muestre la ruta del directorio si se ignora todo el directorio.Lo único que dejé por ignorar fue
.git
.fuente
rsync -azP --exclude-from="$(git -C SRC ls-files --exclude-standard -oi --directory > /tmp/excludes; echo /tmp/excludes)" SRC DEST
.gitignore
(es decir, líneas que comienzan con!
). También rsyncs archivos que--force
agregó a su repositorio, lo que generalmente es algo bueno.¿qué tal
rsync --exclude-from='path/.gitignore' --exclude-from='path/myignore.txt' source destination
?Funcionó para mí.
Creo que también puedes tener más
--exclude-from
parámetros.fuente
.gitignore
archivos usen una sintaxis compatible conrsync
.Solución 2018 confirmada
Detalles:
--exclude-from
es obligatorio en lugar de --excluir porque el caso probable de que la lista de exclusión no se analizaría como argumento. Excluir de requiere un archivo y no puede funcionar con tuberías.La solución actual guarda el archivo de exclusión dentro de la carpeta .git para garantizar que no afecte
git status
mientras se mantiene autónomo. Si lo desea, puede utilizar / tmp.fuente
SRC
aquí, pero no para el problema original que mencioné, que es un directorio en expansión con miles de repositorios de Git como subdirectorios en varias profundidades, muchos de los cuales tienen idiosincrásico.gitignore
s.--exclude-from=<(git -C SRC ls-files --exclude-standard -oi --directory)
Para mercurial podrías usar
para recopilar la lista de archivos que NO están bajo control mercurial debido a restricciones .hgignore y luego ejecutar
para rsync todos los archivos excepto los ignorados. Observe el indicador -m en rsync que excluirá los directorios vacíos de la sincronización porque hg status -i solo enumeraría los archivos excluidos, no los directorios
fuente
Prueba esto:
rsync -azP --delete --filter=":- .gitignore" <SRC> <DEST>
Puede copiar todos los archivos al directorio remoto excluyendo los archivos en '.gitignore' y eliminar archivos que no estén en su directorio actual.
fuente
Según la
rsync
página del manual, además de la lista estándar de patrones de archivo:Entonces, mi archivo $ HOME / .cvsignore se ve así:
para excluir .git y los archivos generados por Sass .
fuente
.git/
directorios, quizás incluso con más fuerza que la copia de trabajo. Lo que quiero excluir son productos de construcción.rsync
página de manual citada en esta respuesta describe la--cvs-exclude
opción, por lo que debe usarla explícitamente. 2 / Puede crear.cvsignore
archivos en cualquier directorio para tener ignorados específicos del proyecto, esos también se leen. 3 /.git
ya se ignora cuando lo usa--cvs-exclude
, según el manual, por lo que tenerlo$HOME/.cvsignore
parece redundante.Tenía varios
.gitignore
archivos muy grandes y ninguna de las soluciones de "rsync puro" funcionó para mí. Escribí este script de envoltura rsync , respeta completamente las.gitignore
reglas (incluye!
excepciones de estilo y.gitignore
archivos en subdirectorios) y ha funcionado como un encanto para mí.fuente
locate -0e .gitignore | (while read -d '' x; do process_git_ignore "$x"; done)
, pero tiene muchos problemas. Archivos en el mismo directorio que.gitignore
no están separados correctamente del nombre del directorio con/
. Líneas en blanco y comentarios mal interpretados. Se ahoga en.gitignore
archivos en rutas con espacios (no importa el diabólico/opt/vagrant/embedded/gems/gems/rb-fsevent-0.9.4/spec/fixtures/custom 'path/.gitignore
delvagrant
paquete para Ubuntu). Quizás sea mejor hacerlo como un script de Perl.rsync
, por la razón específica de que el manejo de comillas / espacios en blanco es tan complicado. Si tiene un ejemplo de unagsync
línea de comando que está fallando y los.gitignore
archivos asociados con ella, me complacerá verla más de cerca.rsync
un sistema de archivos completo, con varios repositorios Git esparcidos a su alrededor. Quizás su script funcione bien para el caso de sincronizar un solo repositorio.Consulte la sección REGLAS DEL FILTRO DE FUSIÓN DE ARCHIVOS en rsync (1).
Parece que es posible crear una regla de filtro rsync que incluirá archivos .gitignore a medida que atraviesa la estructura del directorio.
fuente
En lugar de crear filtros de exclusión, puede usar
git ls-files
para seleccionar cada archivo para rsync:Esto funciona aunque
git ls-files
devuelve rutas separadas por saltos de línea. Probablemente no funcionará si ha versionado archivos con espacios en los nombres de archivo.fuente
Alternativas:
git ls-files -zi --exclude-standard |rsync -0 --exclude-from=- ...
git ls-files -zi --exclude-per-directory=".gitignore" |...
(rsync solo entiende parcialmente .gitignore)
fuente
Respuesta corta
Significado de los parámetros:
-r
: recursivo--info=...
: muestra el progreso--filter=...
: excluir según las reglas enumeradas en el archivo .gitignorefuente