Hacer que ‘git log’ ignore los cambios para ciertas rutas

9 minutos de lectura

Hacer que git log ignore los cambios para ciertas rutas
anonimo

como puedo hacer git log ¿Solo mostrar confirmaciones que cambiaron archivos distintos a los que especifico?

Con git log, puedo filtrar las confirmaciones que veo a aquellas que tocan un conjunto determinado de rutas. Lo que quiero es invertir ese filtro para que solo se enumeren las confirmaciones que tocan las rutas que no sean las especificadas.

Puedo conseguir lo que quiero con

git log --format="%n/%n%H" --name-only | ~/filter-log.pl | git log --stdin --no-walk

donde filter-log.pl es:

#!/usr/bin/perl
use strict;
use warnings;

$/ = "\n/\n";
<>;

while (<>) {
    my ($commit, @files) = split /\n/, $_;

    if (grep { $_ && $_ !~ m[^(/$|.etckeeper$|lvm/(archive|backup)/)] } @files) {
        print "$commit\n";
    }
}

excepto que quiero algo un poco más elegante que eso.

Tenga en cuenta que soy no preguntando cómo hacer que git ignore los archivos. estos archivos deberían ser rastreado y comprometido. Es solo que, la mayoría de las veces, no estoy interesado en verlos.

Pregunta relacionada: Cómo invertir `git log –grep=` o Cómo mostrar registros de git que no coinciden con un patrón Es la misma pregunta, excepto por los mensajes de confirmación en lugar de las rutas.

Foro de discusión sobre este tema de 2008: Re: Excluir archivos de git-diff Esto parecía prometedor pero el hilo parece haberse secado.

  • No estoy seguro de si hay una forma integrada, y su solución perl parece bastante decente. Si lo modifica para aceptar las rutas como argumentos de la línea de comandos, podría crear un alias algo así como !f() { git log ... | path/to/filter-log.pl "$@" | git log --stdin --no-walk; fo incluso incluir esa parte de la canalización en el script también.

    – Cascabel

    16 de abril de 2011 a las 17:25

  • Como solución alternativa, uso find para filtrar directorios cuyas confirmaciones no quiero ver. Si quisiera ignorar las entradas de registro de las confirmaciones realizadas en el directorio de nivel raíz SiteConfig entonces yo diría: git log `find . -type d -mindepth 1 -maxdepth 1 ! -name *SiteConfig`

    – Noah Susman

    10 de marzo de 2012 a las 16:30


  • Para Git 1.9/2.0 (Q1 2014), vea mi respuesta a continuación: git log --oneline --format=%s -- . ":!sub" funcionará (con el magia de ruta :(exclude) y su forma abreviada :!)

    – VoC

    12 de enero de 2014 a las 19:48

Hacer que git log ignore los cambios para ciertas rutas
VonC

Se implementa ahora (git 1.9/2.0, primer trimestre de 2014) con la introducción magia de ruta :(exclude) y su forma abreviada :! en cometer ef79b1f y cometer 1649612por
Nguyễn Thái Ngọc Duy (pclouds)la documentación se puede encontrar aquí.

Ahora puede registrar todo excepto el contenido de una subcarpeta:

git log -- . ':(exclude)sub'
git log -- . ':!sub'

O puede excluir elementos específicos dentro de esa subcarpeta

  • un archivo específico:

      git log -- . ':(exclude)sub/sub/file'
      git log -- . ':!sub/sub/file'
    
  • cualquier archivo dado dentro sub:

      git log -- . ':(exclude)sub/*file'
      git log -- . ':!sub/*file'
      git log -- . ':(exclude,glob)sub/*/file'
    

¡Puedes hacer que esa exclusión no distinga entre mayúsculas y minúsculas!

git log -- . ':(exclude,icase)SUB'

Como señaló Kenny Evitt

No olvide usar comillas simples o el escape apropiado entre comillas dobles si está ejecutando git en un bash concha, por ejemplo ':!sub' o ":\!sub". De lo contrario, te encontrarás bash: ... event not found errores


Nota: Git 2.13 (Q2 2017) agregará un sinónimo ^para !

Ver cometer 859b7f1, cometer 42ebeb9 (08 de febrero de 2017) por Linus Torvalds (torvalds).
(Combinado por Junio ​​C Hamano — gitster en cometer 015fba327 de febrero de 2017)

magia pathspec: agregar ‘^‘ como alias para ‘!

La elección de ‘!‘ para una especificación de ruta negativa termina no solo sin coincidir con lo que hacemos para las revisiones, sino que también es un carácter horrible para la expansión de shell, ya que necesita cotización.

Entonces agrega ‘^‘ como un alias alternativo para una entrada de ruta de acceso excluyente.


Tenga en cuenta que, antes de Git 2.28 (Q3 2020), se interrumpió el uso de pathspec negativo, al recopilar rutas, incluidas las no rastreadas en el árbol de trabajo.

Ver cometer f1f061e (05 jun 2020) por Elías Newren (newren).
(Combinado por Junio ​​C Hamano — gitster en cometer 64efa1118 de junio de 2020)

dir: corregir el tratamiento de pathspecs negados

Reportado por: John Millikin
Firmado por: Elijah Newren

do_match_pathspec() Comenzó la vida como match_pathspec_depth_1() y para la corrección se suponía que solo debía llamarse desde match_pathspec_depth(). match_pathspec_depth() más tarde fue rebautizado como match_pathspec()entonces el invariante que esperamos hoy es que do_match_pathspec() no tiene llamadas directas fuera de match_pathspec().

Desafortunadamente, esta intención se perdió con los cambios de nombre de las dos funciones y las llamadas adicionales a do_match_pathspec() se agregaron en confirmaciones 75a6315f74 (“ls-files: agregue coincidencia de especificación de ruta para submódulos”, 2016-10-07, Git v2.11.0-rc0 — unir listado en lote #11) y 89a1f4aaf7 (“dir: si nuestra especificación de ruta puede coincidir con archivos en un directorio, recurra a él”, 2019-09-17, Git v2.24.0-rc0).

Por supuesto, do_match_pathspec() tenía una ventaja importante sobre match_pathspec()match_pathspec() codificaría las banderas en uno de dos valores, y estas nuevas llamadas necesitaban pasar algún otro valor para las banderas.

Además, aunque llame do_match_pathspec() directamente era incorrecto, probablemente no había ninguna diferencia en el resultado final observable, porque el error solo significaba que fill_diretory() recurriría a directorios innecesarios.

Dado que las comprobaciones subsiguientes de coincidencia de ruta en rutas individuales en el directorio harían que esas rutas adicionales se filtraran, la única diferencia de usar la función incorrecta fue el cálculo innecesario.

La segunda de esas malas llamadas a do_match_pathspec() estuvo involucrado, ya sea a través del movimiento directo o mediante la copia y edición, en una serie de refactorizaciones posteriores.

Ver confirmaciones 777b420347 (“dir: sincronizar treat_leading_path() y read_directory_recursive()“, 2019-12-19, Git v2.25.0-rc0 — unir), 8d92fb2927 (“dir: reemplazar el algoritmo exponencial por uno lineal”, 2020-04-01, Git v2.27.0-rc0 — unir listado en lote #5), y 95c11ecc73 (“Reparar errores propensos fill_directory() API; haz que solo devuelva coincidencias”, 2020-04-01, Git v2.27.0-rc0 — unir listado en lote #5).

El último de ellos introdujo el uso de do_match_pathspec() en un archivo individual y, por lo tanto, resultó en la devolución de rutas individuales que no deberían ser.

El problema de llamar do_match_pathspec() en lugar de match_pathspec() es que cualquier patrón negado como ‘`:!unwanted_path“ será ignorado.

Agregar un nuevo match_pathspec_with_flags() función para cumplir con las necesidades de especificar banderas especiales mientras se verifican correctamente los patrones negados, agregue un gran comentario arriba do_match_pathspec() para evitar que otros hagan un mal uso de él y corrija a las personas que llaman actualmente de do_match_pathspec() para usar en su lugar cualquiera match_pathspec() o match_pathspec_with_flags().

Una nota final es que DO_MATCH_LEADING_PATHSPEC necesita una consideración especial cuando se trabaja con DO_MATCH_EXCLUDE.

El punto de DO_MATCH_LEADING_PATHSPEC es que si tenemos una especificación de ruta como

*/Makefile

y estamos comprobando una ruta de directorio como

src/module/component

que queremos considerarlo una coincidencia para que recurramos al directorio porque _might_ tener un archivo llamado Makefile en algún lugar debajo.

Sin embargo, cuando usamos un patrón de exclusión, es decir, tenemos una especificación de ruta como

:(exclude)*/Makefile

NO queremos decir que una ruta de directorio como

src/module/component

es una coincidencia (negativa).

Mientras que hay puede que ser un archivo llamado ‘Makefile’ en algún lugar debajo de ese directorio, también podría haber otros archivos y no podemos descartar de forma preventiva todos los archivos en ese directorio; necesitamos recurrir y luego verificar archivos individuales.

Ajustar el DO_MATCH_LEADING_PATHSPEC lógica para activarse solo para especificaciones de ruta positivas.

  • ¿Puedes hacer varios archivos?

    – Justin Thomas

    15 de marzo de 2014 a las 14:07

  • @JustinThomas Creo (aún no probado) que puede repetir ese patrón de exclusión de ruta varias veces ":(exclude)pathPattern1" ":(exclude)pathPattern2"por lo tanto, ignorando múltiples carpetas/archivos.

    – VoC

    15 de marzo de 2014 a las 15:16

  • Si está ejecutando Git en un shell Bash, use ':!sub' en vez de evitar bash: ... event not found errores. ":\!sub" no funciona

    – Kenny Evitt

    2 de febrero de 2017 a las 15:10


  • @KennyEvitt Gracias por su edición y comentario. He incluido este último en la respuesta para mayor visibilidad.

    – VoC

    2 de febrero de 2017 a las 15:14

  • Para aquellos que se preguntan dónde está la documentación oficial sobre esta funcionalidad, consulte git help glossary (que encontré listado en git help -g [which I found suggested in git help]).

    – ravron

    6 de noviembre de 2018 a las 1:49

tl; dr: shopt -s extglob && git log !(unwanted/glob|another/unwanted/glob)

si estás usando Intento deberías poder usar el englobamiento extendido función para obtener solo los archivos que necesita:

$ cd -- "$(mktemp --directory)" 
$ git init
Initialized empty Git repository in /tmp/tmp.cJm8k38G9y/.git/
$ mkdir aye bee
$ echo foo > aye/foo
$ git add aye/foo
$ git commit -m "First commit"
[master (root-commit) 46a028c] First commit
 0 files changed
 create mode 100644 aye/foo
$ echo foo > bee/foo
$ git add bee/foo
$ git commit -m "Second commit"
[master 30b3af2] Second commit
 1 file changed, 1 insertion(+)
 create mode 100644 bee/foo
$ shopt -s extglob
$ git log !(bee)
commit ec660acdb38ee288a9e771a2685fe3389bed01dd
Author: My Name <jdoe@example.org>
Date:   Wed Jun 5 10:58:45 2013 +0200

    First commit

Puedes combinar esto con globstar para la acción recursiva.

  • Esto no muestra confirmaciones que afecten a archivos que ya no existen. Hack muy cercano y agradable de todos modos.

    – Anónimo

    5 de junio de 2013 a las 20:32

Puede temporalmente ignorar los cambios en un archivo con:

git update-index --skip-worktree path/to/file

En el futuro, todos los cambios en esos archivos serán ignorados por git status, git commit -aetc. Cuando esté listo para confirmar esos archivos, simplemente inviértalo:

git update-index --no-skip-worktree path/to/file

y cometer como de costumbre.

  • Esto parece abordar una situación ligeramente diferente. git update-index --skip-worktree no causa git log para filtrar las confirmaciones que ya se han realizado.

    – Anónimo

    7 de julio de 2011 a las 19:58

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad