¿Hay un resumen de `git log` que incluya fusiones (solo) y no fusionadas?

No me refiero simplemente a git log , sé que enumera todo. Estoy buscando un resumen.

No estoy seguro de si esta es la mejor práctica o no, pero utilizo los commit de fusión y estilo de estilo con git. Si un cambio es pequeño y directo, no veo por qué necesita una confirmación de fusión, la confirmación ya es atómica. Por otro lado, a veces agregar una function lógica al código consiste en múltiples pasos atómicos, y tiendo a usar fusionar en este caso, para evitar aplastar múltiples pasos juntos.

Lo que me pregunto es si hay una buena manera de resumir esto en el logging. Es decir, ¿puedo enumerar solo la confirmación de fusión (si y solo si se trata de una confirmación de fusión) y, de lo contrario, listr la confirmación de no fusión? Esto está relacionado con la edición de la confirmación de fusión, por lo que describe qué característica se agrega, por supuesto.

Parece que el git log --merges está cerca, pero no muestra las confirmaciones aplastadas, por lo que es un historial incompleto.

[editar basado en comentarios sobre rebase] Estaba pensando que mi pregunta se aplicaba tanto a git como a github, pero la pregunta de uno de los comentarios me hizo darme count de que no es exactamente así. Github te permite fusionar una request de extracción o aplastarla (también permite reescribir una confirmación, pero eso es fuera de tema, creo). Fusionar una request de extracción genera una confirmación de fusión con el set de confirmaciones en la request de extracción, mientras que una Squash commit es básicamente lo mismo que seleccionar la confirmación en la twig objective (o aplastar si hay más de una confirmación en el RP )

Dada la forma en que usas Git (que creo que es una muy buena manera, pero las opiniones están mal vistas aquí en StackOverflow :-)) puedes get justo lo que deseas usando la opción --first-parent .

Descripción larga

Como un recordatorio de resumen rápido, cuando usas git merge --squash (o el button clicky "fusionar mediante squash" en github ), lo que Git hace al final es hacer un commit ordinario que tiene, como su contenido, el mismo contenido que obtendrías para una verdadera fusión; pero este nuevo compromiso ordinario es solo eso, un compromiso ordinario, con solo un padre soltero, sin relación con los compromisos que se iban a fusionar.

Si fueras a hacer una fusión real, obtendrías esto:

 * a000000 (master) merge feature/tall |\ | * ccccccc (feature/tall) fixing something trivial | * bbbbbbb oops, forgot the cat | * aaaaaaa take a stab at implementing "tall" |/ * 9999999 some commit or another * 8888888 the history goes on ... 

y así. Pero toda la secuencia A + B + C de la function no necesita todos los elementos "oops" y "trivial fix" para savese de forma permanente, por lo que podríamos simplemente realizar la confirmación final:

 * a000001 (master) implement the "tall" feature | | * ccccccc (feature/tall) fixing something trivial | * bbbbbbb oops, forgot the cat | * aaaaaaa take a stab at implementing "tall" |/ * 9999999 some commit or another * 8888888 the history goes on ... 

y luego descartar feature/tall completo la feature/tall . Luego obtenemos esta secuencia agradable en la que aparece toda la function a la vez.

Pero, como dices en tu pregunta, a veces tiene mucho más sentido presentar una function en pasos:

 * f000000 (master) merge feature/short |\ | * eeeeeee (feature/short) use the new facility to implement feature | * ddddddd replace specific hack with new generic facility | * bcdefed clean up an earlier specific hack |/ * a000001 implement the "tall" feature * 9999999 some commit or another * 8888888 the history goes on ... 

Podemos hacer esto con una fusión --no-ff (o el button clicky correspondiente en GitHub – el mismo button, realmente, pero establecer en un modo diferente).

Como antes, podemos eliminar feature/short completo la feature/short la label feature/short porque ya está hecha (bueno, hecho hasta donde sabemos, tal vez necesite correcciones de errores en el futuro, pero eso será entonces, no ahora).

Al ver esta historia, supongamos que podemos decirle a Git: solo mira las confirmaciones yendo directamente hacia el lado izquierdo de la historia, por favor. Luego, veríamos la confirmación única que a000001 feature/tall (incluso si el nombre ya no existe), ya que es a000001 ; pero antes de eso, también veríamos, como una única confirmación, como si hubiera sido hecha por aplastamiento (solo que no fue así y los detalles completos todavía están allí en el repository si los queremos), la fusión de compromiso que trajo feature/short .

De hecho, hay una manera de decirle a git log (y a su command hermano orientado a scripts git rev-list ) que haga exactamente eso. La bandera del primer --first-parent le dice a Git que cuando encuentra un compromiso de fusión, debe, para fines de visualización y charts, quitar al segundo padre de cualquier fusión. 1 Esto deja al rest de Git tratando este compromiso, al less por el momento, como si fuera una combinación común. Eso es lo que también es una fusión de squash: una confirmación que se realizó mediante la acción de fusión, la parte de combinación de Git, pero se agregó al gráfico de confirmación como una confirmación ordinaria de padre único.

Por lo tanto, git log --first-parent (opcionalmente con -mp también: tenga en count que para los parches generalmente querrá -m para evitar el comportamiento combinado de diferencias) obtendrá lo que quiera aquí.


1 Un compromiso de fusión con más de dos padres -llamado fusión de pulpo- se elimina de todos less del primero , de ahí el nombre de la opción, "primer padre". Sin embargo, la mayoría de las fusiones solo tienen dos padres; GitHub en sí no puede hacer fusiones de pulpos.