Excluir un directorio de git diff

179

Me pregunto cómo puedo excluir un directorio completo de mi Git diff. (En este caso / especificación). Estoy creando un diff para toda nuestra versión de software usando el comando git diff. Sin embargo, los cambios en las especificaciones son irrelevantes para este procedimiento y solo crean dolores de cabeza. ahora sé que puedo hacer

git diff previous_release..current_release app/

Esto crearía una diferencia para todos los cambios en el directorio de la aplicación, pero no, por ejemplo, en el directorio lib /. ¿Alguien sabe cómo realizar esta tarea? ¡Gracias!

Editar: solo quiero ser claro, sé que puedo encadenar los parámetros de todos mis directorios al final, menos / espec. Esperaba que hubiera una manera de excluir verdaderamente un solo directorio en el comando.

Mysrt
fuente
44
Encontré esta increíble pregunta porque tenía el objetivo de ignorar los submódulos . En este caso, si eres tan ingenuo como yo, esta pregunta puede ser más útil.
brandizzi
Es extraño que todavía no tengamos un interruptor Git nativo para hacer esto en septiembre de 2016
Michael Z

Respuestas:

138

Suponiendo que usa bash, y ha habilitado globbing extendido ( shopt -s extglob), podría manejar eso desde el lado de la carcasa:

git diff previous_release current_release !(spec)

Le ahorra tener que enumerar todas las demás cosas.

O agnóstico de concha:

git diff previous_release current_release --name-only | grep -v '^spec/' \
    | xargs git diff previous_release current_release --

Podría resumirlo en un script de shell de una línea para evitar tener que volver a escribir los argumentos.

Cascabel
fuente
1
PS globbing no coincide con los archivos ocultos, por lo que si eres obsesivo, es posible que desees agregar algo que .!(.|)comience con un .además .y ...
Cascabel
Esto no parece funcionar para archivos que son nuevos o eliminados en las sucursales. Recibo errores que detienen la ejecución del script, diciendo que no puede diferir en su contra.
Graham Christensen
2
@Graham: Creo que lo --que acabo de agregar debería arreglar eso.
Cascabel
1
Impresionante respuesta. Solo quería que se mostraran los nombres (no la diferencia real), así que también tuve que agregar --name-onlyal final.
ago
1
Después de jugar con él, solo quiero agregar que si cambias el nombre de un archivo, arrojará un error, pero todo lo que necesitas hacer es agregar -- path/of/new/filey lo resolverá :)
agosto
321

Según esta respuesta , también puede usar:

git diff previous_release..current_release -- . ':!spec'

Esta es una nueva característica de git que permite excluir ciertos caminos. Debería ser más confiable que varios forros de revestimiento.

Estoy publicando esto aquí porque esta pregunta sigue siendo el éxito número 1 para "git diff exclude path".

cdleonard
fuente
44
Amo esta respuesta. Si agrega opciones, hágalo antes del doble guión. Por ejemplo: git diff previous_release current_release --name-status -- . ':!spec'
liamvictor
No me di cuenta de que podía usar nombres de sucursal para el current_releasey previous_releaseme hizo sonreír cuando lo descubrí.
trueheart78
2
Lo que funcionó para mí git diff --stat dev -- . ':!/Mopy/Docs/*'. Lo que no funcionó para mí git diff dev --stat -- . ':!('Mopy/Docs/Wrye Bash General Readme.html'|'Mopy/Docs/Wrye Bash Advanced Readme.html')'y las variaciones
Mr_and_Mrs_D el
De mucha ayuda. Aquí está la sintaxis para ver si se cambia algún archivo, que no sea database.yml:git diff --check -- . ':!config/database.yml'
Dan Kohn
17
También puede excluir varios elementos de esta manera:git diff previous_release current_release -- . ':!file_a' ':!file_b'
PseudoNoise
37

Si desea especificar más de una ruta para excluir en un git diff, simplemente agregue parámetros de exclusión adicionales al final, por ejemplo, para excluir todo de los directorios de proveedores y bin de las estadísticas: -

git diff --stat previous_release..current_release -- . ':!vendor' ':!bin'
David Graham
fuente
33

Puede probar y deshabilitar el atributo diff para cualquier archivo dentro del directorio lib.
.gitattributes:

lib/* -diff

racl101 agrega en los comentarios :

Solo para agregar a esto, para aquellos de ustedes que desean limitar la git diffsalida de archivos de un tipo específico, dentro de un directorio específico y sus subdirectorios, como todos los JavaScript generados por el paquete de .jsarchivos de Webpack , por ejemplo, pueden agregar esto a .gitattributes:

dist/js/**/*.js -diff

Entonces no ves todo ese ruido en tu salida de git diff y solo se muestra como: lo Binary files ... differcual es más útil.

VonC
fuente
Sin embargo, esto eliminaría las especificaciones de todos mis diffs. Todavía quiero ver mis diferenciales en la carpeta de especificaciones normalmente, pero no cuando estoy ejecutando este 'lanzamiento' diff
Mysrt
2
@Mystr: Puede establecer ese .gitattributesarchivo en una rama especial hecha solo para este tipo de 'release' diff;) Rebase esa rama especial encima current_releasey haga su diff desde allí.
VonC
Esto tampoco parece funcionar para los archivos que se eliminan en las ramas. Los archivos que se eliminaron aún muestran la diferencia completa.
Graham Christensen el
No funciona para mi ¿Son _ los caminos especiales? _site/* -diff
Marius
@MariusAndreiana No, '_' no es especial. ¿Puede verificar qué regla de gitattributes se aplica para un archivo de esa carpeta con: git-scm.com/docs/git-check-attr
VonC
22

Git diff ahora acepta un formato de exclusión personalizado: git diff -- ':(exclude)lib/*'

Tenga cuidado si tiene muchos nombres de carpetas repetitivos ('/ app', '/ lib', etc.), ya que esto excluirá los archivos relativos al directorio de trabajo actual Y al directorio raíz de git.

MaxPRafferty
fuente
1
te estás perdiendo un punto, ¿no debería serlo git diff -- . ':(exclude)lib/*'?
Nicolas Dermine
1
@NicolasDermine No, aunque lo que escribiste es equivalente. La parte "incluye" de la ruta también es opcional. Es por eso que puede hacer git difftodo lo relacionado con su ruta actual, en lugar de exigirgit diff -- .
MaxPRafferty
Nota: en máquinas con Windows, use comillas dobles, comogit diff -- ":(exclude)lib/*"
cnlevy
No tengo idea de por qué, pero para mí solo funciona con el punto, como lo sugiere @NicolasDermine. Yo uso Cmder en win10.
Olivvv
3

Relativo al directorio raíz de git

git diff acepta una exclusión opcional

git diff -- ":(exclude)thingToExclude"

Es posible que desee agregar algunos comodines

git diff -- ":(exclude)*/thingToExclude/*"

Dirigirse a tipos de archivos específicos

git diff -- ":(exclude)*/$1/*.png"

Algún azúcar sintáctico aplicado

git diff -- ":!/\$1/"

O suelte un pequeño script para sus archivos de puntos

Tales como .bash_profileo.zshrc

gde() {
    : '
        git diff exclude files or folders
        usage:
        gde fileOrFolderNameToExclude
    '
    git diff -- ":!/\$1/"
}
jasonleonhard
fuente
-6
git diff app lib
Jed Schneider
fuente