Usando Git, muestre todas las confirmaciones que existen * solo * en una rama específica, y no * ninguna * otras

86

Dada una rama, me gustaría ver una lista de confirmaciones que existen solo en esa rama. En esta pregunta , discutimos formas de ver qué confirmaciones están en una rama pero no en una o más ramas especificadas.

Esto es ligeramente diferente. Me gustaría ver lo que cometa, está en una, pero no en las otras ramas.

El caso de uso se encuentra en una estrategia de ramificación en la que algunas ramas solo deben fusionarse y nunca comprometerse directamente. Esto se usaría para verificar si se han realizado confirmaciones directamente en una rama de "solo combinación".

EDITAR: A continuación se muestran los pasos para configurar un repositorio git ficticio para probar:

git init
echo foo1 >> foo.txt
git add foo.txt
git commit -am "initial valid commit"
git checkout -b merge-only
echo bar >> bar.txt
git add bar.txt
git commit -am "bad commit directly on merge-only"
git checkout master
echo foo2 >> foo.txt 
git commit -am "2nd valid commit on master"
git checkout merge-only 
git merge master

Solo debería aparecer la confirmación con el mensaje "confirmación incorrecta directamente en solo combinación", que se realizó directamente en la rama de solo combinación.

Jimmyorr
fuente
1
Esta pregunta supone que todas las ramas fusionadas están disponibles actualmente en el repositorio, nunca se eliminan una vez que se fusionan por completo y tal vez nunca se fusionan con un avance rápido. Avíseme si me falta algo, pero me parece que esto solo es viable para un conjunto relativamente pequeño de ramas de fusión permitidas, así que ¿por qué no usar la git log ^branch1 ^branch2 merge-only-branchsintaxis?
Karl Bielefeldt
1
El git log ^branch1 ^branch2 merge-only-branchrequiere enumerar cada rama. Eso se puede evitar con un uso inteligente de bash / grep (vea mi respuesta a continuación), pero espero que git tenga algún soporte incorporado para esto. Tiene razón en que supone que todas las ramas de fusión son remotas (solo las locales son tan buenas como inexistentes para otros desarrolladores). El uso --no-mergesomite todas las confirmaciones que se fusionaron y luego se eliminó la rama de fusión de origen original, por lo que se supone que las ramas de fusión de se mantienen hasta que se fusionan con una rama que no es de fusión solo (es decir, maestra).
jimmyorr

Respuestas:

75

Acabamos de encontrar esta elegante solución

git log --first-parent --no-merges

En su ejemplo, por supuesto, la confirmación inicial todavía aparece.

esta respuesta no responde exactamente a la pregunta, porque la confirmación inicial todavía aparece. Por otro lado, muchas personas que vienen aquí parecen encontrar la respuesta que buscan.

wrtsprt
fuente
1
Simple, efectivo, mejor.
Zabba
1
Dado que la confirmación inicial en el maestro todavía aparece, esto no responde a la pregunta.
jimmyorr
6
Esto por sí solo no satisface la condición de "confirmaciones que existen solo en esa rama"; muestra la initial valid commit, que es parte de ambasmerge-onlymaster ramas y . Sin embargo, si uno pasa por el esfuerzo de poner el nombre de la rama actual al final seguido de nombres de rama con prefijo ^ de los que se sabe que se originó la rama actual, resuelve la mitad de los problemas (excluyendo las cosas que se fusionaron). Ej .:git log --first-parent --no-merges merge-only ^master
Slipp D. Thompson
13
No estoy seguro de por qué se vota tanto, no parece ser pertinente para la pregunta en absoluto. Ciertamente no proporciona la información que buscaba el cartel.
Chris Rasys
2
Puede que esta respuesta no sea perfecta. Pero es simple y ciertamente funciona hasta cierto punto. Encuentro útil agregar el nombre de la rama, es decir, filtrar todas las confirmaciones pertenecen a una rama determinada:git log --first-parent --no-merges | grep <branch_name>
artm
29

Cortesía de mi querido amigo Redmumba :

git log --no-merges origin/merge-only \
    --not $(git for-each-ref --format="%(refname)" refs/remotes/origin |
    grep -Fv refs/remotes/origin/merge-only)

... dónde origin/merge-onlyestá el nombre de la rama de solo combinación remota. Si trabaja en un repositorio de git solo local, sustitúyalo refs/remotes/originpor refs/headsy sustituya el nombre de la rama remota origin/merge-onlycon el nombre de la rama local merge-only, es decir:

git log --no-merges merge-only \
    --not $(git for-each-ref --format="%(refname)" refs/heads |
    grep -Fv refs/heads/merge-only)
Jimmyorr
fuente
2
Espero que alguien más pueda proporcionar una solución sin grep usando solo git, pero si no, esto se siente bastante elegante.
jimmyorr
1
Sí, elegante. Úselo git for-each-refpara enumerar todos los nombres de referencia en el origen y grep -vpara omitir la rama de solo combinación. git logtoma una --notopción, a la que pasamos nuestra lista de todas las referencias (excepto la rama de solo fusión). Si tiene una respuesta más elegante al problema, escuchémosla.
jimmyorr
2
Oh, estoy seguro de que es la respuesta más elegante. Solo estoy argumentando que es un poco "prolijo / complejo" para la verdadera elegancia. :-) ¡No quise menospreciar su enfoque, señor!
Chris K
1
El final /*de los git for-each-refscomandos se basa en no coincidir con algún archivo existente y no tener failglobo nullglobestablecer (las opciones de bash , otras shells varían). Debe citar / escapar de los asteriscos o simplemente dejar el final /*(los git for-each-refpatrones pueden coincidir "desde el principio hasta una barra oblicua"). Tal vez use grep -Fv refs/remotes/origin/foo( refs/heads/foo) para ser más estricto sobre qué referencias se eliminan.
Chris Johnsen
3
Se puede simplificar si solo desea ver las confirmaciones presentes en una rama y no en otra:, git log --no-merges B1 --not B2donde B1 es la rama que le interesa y B2 es la rama con la que desea comparar B1. Tanto B1 como B2 pueden ser sucursales locales o remotas, por lo que puede especificar git log --no-merges master --not origin/master, o incluso especificar dos sucursales remotas.
Sr.b
21
git log origin/dev..HEAD

Esto le mostrará todas las confirmaciones realizadas en su rama.

Prakash
fuente
2
@Prakash origin/branchNameapuntará al jefe de la rama remota Y HEADapuntará al commitid de la última confirmación local en esa rama. Así que esto no funcionará cuando haya usado git push.
Bharat
Puede usar esto para comparar otra sucursal local. La bandera --no-merges también puede ser útil para abordar la pregunta original del OP.
Paul Whipp
15

La respuesta de @Prakash funciona. Solo por claridad ...

git checkout feature-branch
git log master..HEAD

enumera las confirmaciones en la rama de características pero no en la rama ascendente (normalmente su maestro).

Bryan
fuente
12

Quizás esto podría ayudar:

git show-branch

grzuy
fuente
2
Si bien esto puede responder teóricamente a la pregunta, sería preferible incluir aquí las partes esenciales de la respuesta y proporcionar el enlace como referencia.
Vladimir Panteleev
En realidad, esto es muy útil. Consulte stackoverflow.com/a/7623339/874188 para obtener un ejemplo más elaborado y algunas respuestas relacionadas.
tripleee
7

Prueba esto:

git rev-list --all --not $(git rev-list --all ^branch)

Básicamente, git rev-list --all ^branchobtiene todas las revisiones que no están en la rama y luego todas las revisiones en el repositorio y restan la lista anterior, que son solo las revisiones en la rama.

Después de los comentarios de @ Brian:

De la documentación de git rev-list:

List commits that are reachable by following the parent links from the given commit(s)

Entonces un comando como git rev-list A donde A es una confirmación enumerará las confirmaciones que son accesibles desde A, incluida A.

Con eso en mente, algo como

git rev-list --all ^A

enumerará las confirmaciones no accesibles desde A

Entonces git rev-list --all ^branch enumerará todas las confirmaciones no accesibles desde la punta de la rama. Lo que eliminará todas las confirmaciones en la rama, o en otras palabras, las confirmaciones que están solo en otras ramas.

Ahora vamos a git rev-list --all --not $(git rev-list --all ^branch)

Esto sera como git rev-list --all --not {commits only in other branches}

Así que queremos enumerar los allque no son accesibles desdeall commits only in other branches

Que es el conjunto de confirmaciones que solo están en la rama. Tomemos un ejemplo simple:

             master

             |

A------------B

  \

   \

    C--------D--------E

                      |

                      branch

Aquí el objetivo es obtener D y E, las confirmaciones no en ninguna otra rama.

git rev-list --all ^branch dar solo B

Ahora, git rev-list --all --not Bes a lo que llegamos. Lo que también es git rev-list -all ^B: queremos que no se pueda acceder a todas las confirmaciones desde B. En nuestro caso, son D y E. Que es lo que queremos.

Espero que esto explique cómo funciona correctamente el comando.

Editar después del comentario:

git init
echo foo1 >> foo.txt
git add foo.txt
git commit -am "initial valid commit"
git checkout -b merge-only
echo bar >> bar.txt
git add bar.txt
git commit -am "bad commit directly on merge-only"
git checkout master
echo foo2 >> foo.txt 
git commit -am "2nd valid commit on master"

Después de los pasos anteriores, si lo hace git rev-list --all --not $(git rev-list --all ^merge-only), obtendrá el compromiso que estaba buscando: el "bad commit directly on merge-only".

Pero una vez que realice el último paso en sus pasos, git merge masterel comando no dará el resultado esperado. Porque a partir de ahora no hay confirmación que no esté en merge-only ya que la confirmación adicional en master también se ha fusionado para merge-only. Entonces git rev-list --all ^branchda un resultado vacío y, por git rev-list -all --not $(git rev-list --all ^branch)lo tanto , dará todas las confirmaciones solo en combinación.

manojlds
fuente
1
Hm ... no estoy seguro de por qué, pero esto no funciona del todo. La canalización de la salida de su comando xargs -L 1 -t git branch -a --containsmuestra muchos falsos positivos (confirmaciones que, de hecho, están en otras ramas). Intenté con y sin --no-merges. ¡Gracias por responder!
jimmyorr
Parece que funciona bien para mí por lo que puedo ver en un repositorio de git ficticio.
manojlds
Agregué pasos para crear un repositorio git ficticio para ayudar a demostrar el problema con su respuesta.
jimmyorr
Ah, Ups. He votado a favor de esto antes de pensarlo bien. git rev-list --all ^branchle dará todas las confirmaciones que no están incluidas branch. Usted está restando después de que en la lista que están en branch; pero, por definición, todas las confirmaciones que no están incluidas no branchestán incluidas branch, por lo que no resta nada. Lo que jimmyorr busca son confirmaciones que estén en branchpero no master, ni en ninguna otra rama. No desea restar las confirmaciones que no están incluidas branch; desea restar las confirmaciones que están en cualquier otra rama.
Brian Campbell
1
@manojlds "(todas las revisiones) - (todas las revisiones no están en la rama) = revisión en la rama". Sí, eso funciona para obtener todas las revisiones branch, pero también lo hace git rev-list branch. Estás escribiendo git rev-list branchde una manera más complicada (y más lenta). No funciona responder a la pregunta, que es cómo encontrar todas las confirmaciones branch que no están en ninguna otra rama .
Brian Campbell
2

Otra variación de las respuestas aceptadas, para usar con master

git log origin/master --not $(git branch -a | grep -Fv master)

Filtra todas las confirmaciones que ocurren en cualquier rama que no sea la maestra.

JaimeJorge
fuente
0

Esta no es exactamente una respuesta real, pero necesito acceso al formato y mucho espacio. Intentaré describir la teoría detrás de lo que considero las dos mejores respuestas: la aceptada y la (al menos actualmente) mejor clasificada . Pero, de hecho, responden a diferentes preguntas .

Las confirmaciones en Git suelen estar "en" más de una rama a la vez. De hecho, de eso se trata la pregunta. Dado:

...--F--G--H   <-- master
         \
          I--J   <-- develop

donde las letras mayúsculas representan los ID de hash de Git reales, a menudo buscamos solo confirmacionesH o solo confirmacionesI-J en nuestra git logsalida. Las confirmaciones hasta Gestán en ambas ramas, por lo que nos gustaría excluirlas.

(Tenga en cuenta que en los gráficos dibujados como este, las confirmaciones más nuevas están hacia la derecha. Los nombres seleccionan la confirmación única más a la derecha en esa línea. Cada una de esas confirmaciones tiene una confirmación principal, que es la confirmación a su izquierda: el padre de Hes G, y el padre de Jes I. El padre de Ies de Gnuevo. El padre de Ges F, y Ftiene un padre que simplemente no se muestra aquí: es parte de la ...sección).

Para este caso particularmente simple, podemos usar:

git log master..develop    # note: two dots

para ver I-J, o:

git log develop..master    # note: two dots

para ver Hsolo. El nombre del lado derecho, después de los dos puntos, le dice a Git: sí, estas confirmaciones . El nombre del lado izquierdo, antes de los dos puntos, le dice a Git: no, no estas confirmaciones . Git comienza por el final , en la confirmación Ho confirmación, Jy funciona al revés . Para (mucho) más sobre esto, consulte Think Like (a) Git .

De la forma en que está redactada la pregunta original, el deseo es encontrar confirmaciones que sean accesibles desde un nombre en particular, pero no desde cualquier otro nombre en la misma categoría general. Es decir, si tenemos una gráfica más compleja:

               O--P   <-- name5
              /
             N   <-- name4
            /
...--F--G--H--I---M   <-- name1
         \       /
          J-----K   <-- name2
           \
            L   <-- name3

podríamos elegir uno de estos nombres, como name4 o name3, y preguntar: ¿ qué confirmaciones se pueden encontrar con ese nombre, pero no con los otros nombres? Si elegimos name3la respuesta es comprometerse L. Si elegimos name4, la respuesta es ningún compromiso: el compromiso de que los name4nombres es compromiso Npero compromiso Nse puede encontrar comenzando en name5y trabajando hacia atrás.

La respuesta aceptada funciona con nombres de seguimiento remoto, en lugar de nombres de sucursales, y le permite designar uno, el que está escrito, origin/merge-onlycomo el nombre seleccionado y mirar todos los demás nombres en ese espacio de nombres. También evita mostrar fusiones: si seleccionamos name1como el "nombre interesante" y decimos mostrarme confirmaciones que son accesibles desde name1pero no cualquier otro nombre , veremos la confirmación de fusión Masí como la confirmación regular I.

La respuesta más popular es bastante diferente. Se trata de atravesar el gráfico de confirmaciones sin seguir ambos tramos de una fusión y sin mostrar ninguna de las confirmaciones que son fusiones. Si comenzamos con name1, por ejemplo, no mostraremos M(es una fusión), pero asumiendo que el primer padre de la fusión Mes un compromiso I, ni siquiera veremos los compromisos JyK . Vamos a terminar mostrando cometer I, y también se compromete H, G, F, y así sucesivamente, ninguno de estos son confirmaciones de mezcla y todos son accesibles por a partir de My trabajando hacia atrás, visitando sólo el primero de los padres de cada combinación de comprometerse.

La respuesta más popular es bastante adecuada, por ejemplo, para ver mastercuándo masterse pretende que sea una rama de solo combinación. Si todo el "trabajo real" se realizó en las ramas laterales que posteriormente se fusionaron master, tendremos un patrón como este:

I---------M---------N   <-- master
 \       / \       /
  o--o--o   o--o--o

donde todos los nombres sin letra o confirmaciones sin son confirmaciones ordinarias (sin fusión) My Nson confirmaciones de fusión. Comprometerse Ies la inicial cometer: el primer cometer jamás se ha hecho, y el único que debería estar en la maestra que no es una fusión cometió. Si el git log --first-parent --no-merges masterprograma muestra algún compromiso diferente a I , tenemos una situación como esta:

I---------M----*----N   <-- master
 \       / \       /
  o--o--o   o--o--o

donde queremos ver la confirmación *que se realizó directamente master, no fusionando alguna rama de características.

En resumen, la respuesta popular es excelente para mirar master cuándo masterse debe combinar solo, pero no es tan buena para otras situaciones. La respuesta aceptada funciona para estas otras situaciones.

¿Son nombres de seguimiento remoto como origin/master nombres de sucursales ?

Algunas partes de Git dicen que no lo son:

git checkout master
...
git status

dice on branch master , pero:

git checkout origin/master
...
git status

dice HEAD detached at origin/master . Prefiero estar de acuerdo con git checkout/ git switch:origin/master no es un nombre de rama porque no se puede "acceder" a él.

La respuesta aceptada usa nombres de seguimiento remotoorigin/* como "nombres de sucursales":

git log --no-merges origin/merge-only \
    --not $(git for-each-ref --format="%(refname)" refs/remotes/origin |
    grep -Fv refs/remotes/origin/merge-only)

La línea media, que invoca git for-each-ref , itera sobre los nombres de seguimiento remoto para el control remoto nombrado origin.

La razón por la que esta es una buena solución al problema original es que aquí estamos interesados ​​en los nombres de las ramas de otra persona , en lugar de los nombres de nuestras ramas. Pero eso significa que hemos definido rama como algo diferente a nuestros nombres de rama . Eso está bien: solo tenga en cuenta que está haciendo esto, cuando lo haga.

git log atraviesa alguna (s) parte (s) del gráfico de confirmación

Lo que realmente estamos buscando aquí es una serie de lo que he llamado daglets: mira ¿Qué queremos decir exactamente con "rama"? Es decir, estamos buscando fragmentos dentro de algún subconjunto del gráfico de confirmación general .

Siempre que hagamos que Git mire un nombre de rama como master, un nombre de etiqueta como v2.1, o un nombre de seguimiento remoto comoorigin/master , tendemos a querer que Git nos diga sobre esa confirmación. y cada confirmación a la que podemos llegar desde esa confirmación: comenzando allí y trabajando al revés.

En matemáticas, esto se conoce como caminar por un gráfico . El gráfico de confirmación de Git es un gráfico acíclico dirigido o DAG , y este tipo de gráfico es especialmente adecuado para caminar. Al caminar por un gráfico de este tipo, se visitará cada vértice del gráfico al que se puede acceder a través del camino que se está utilizando. Los vértices en el gráfico de Git son las confirmaciones, y los bordes son arcos (enlaces unidireccionales) que van de cada hijo a cada padre. (Aquí es donde Think Like (a) Git entra . La naturaleza unidireccional de los arcos significa que Git debe funcionar al revés, de hijo a padre).

Los dos comandos principales de Git para recorrer gráficos son git logy git rev-list. Estos comandos son extremadamente similares, de hecho, en su mayoría están construidos a partir de los mismos archivos fuente, pero su salida es diferente: git logproduce una salida para que los humanos la lean, mientras que git rev-listproduce una salida para que la lean otros programas Git. 1 Ambos comandos realizan este tipo de recorrido gráfico.

El recorrido del gráfico que hacen es específicamente: dado un conjunto de confirmaciones de punto de partida (tal vez solo una confirmación, tal vez un montón de ID de hash, tal vez un montón de nombres que se resuelven en ID de hash), recorre el gráfico, visitando las confirmaciones . Directivas particulares, como --noto un prefijo ^, o --ancestry-path, o --first-parent, modifican el recorrido del gráfico de alguna manera.

A medida que recorren el gráfico, visitan cada confirmación. Pero solo imprimen algunos subconjuntos seleccionados de las confirmaciones caminadas. Directivas como --no-mergeso --before <date>indican el código que recorre el gráfico que se compromete a imprimir .

Para hacer esta visita, una confirmación a la vez, estos dos comandos usan una cola de prioridad . Ejecutas git logo git rev-listy le das algunas confirmaciones de punto de partida. Ponen esas confirmaciones en la cola de prioridad. Por ejemplo, un simple:

git log master

convierte el nombre masteren un ID de hash sin procesar y coloca ese ID de hash en la cola. O:

git log master develop

convierte ambos nombres en ID de hash y, asumiendo que se trata de dos ID de hash diferentes, coloca ambos en la cola.

La prioridad de las confirmaciones en esta cola está determinada por aún más argumentos. Por ejemplo, el argumento --author-date-orderle dice a git logo git rev-listque use la marca de tiempo del autor , en lugar de la marca de tiempo del confirmador. El valor predeterminado es usar la marca de tiempo del confirmador y elegir el compromiso más reciente por fecha: el que tiene la fecha numérica más alta. Entonces master develop, suponiendo que se resuelvan en dos confirmaciones diferentes, Git mostrará la que vino más tarde primero, porque estará al principio de la cola.

En cualquier caso, el código de revisión para caminar ahora se ejecuta en un bucle:

  • Mientras hay confirmaciones en la cola:
    • Elimina la primera entrada de la cola.
    • Decide si imprimir esta confirmación en absoluto. Por ejemplo --no-merges: no imprime nada si es una confirmación de fusión; --before: no imprime nada si su fecha no es anterior a la hora designada. Si no se suprime la impresión, imprima la confirmación: para git log, muestre su registro; paragit rev-list , imprime su ID de hash.
    • Ponga algunas o todas las confirmaciones principales de esta confirmación en la cola (siempre que no esté allí ahora y no se haya visitado ya 2 ). El valor predeterminado normal es poner todos los padres. El uso --first-parentsuprime todos menos el primer padre de cada combinación.

(Ambos git logy git rev-listpueden simplificar el historial con o sin reescritura de los padres en este punto también, pero lo omitiremos aquí).

Para una cadena simple, como comenzar en HEADy trabajar hacia atrás cuando no hay combinaciones de confirmaciones, la cola siempre tiene una confirmación en la parte superior del ciclo. Hay una confirmación, así que la sacamos, la imprimimos y ponemos su padre (único) en la cola y volvemos a dar la vuelta, y seguimos la cadena hacia atrás hasta que llegamos a la primera confirmación, o el usuario se cansa de la git logsalida y se cierra. el programa. En este caso, ninguna de las opciones de pedido importa: solo hay una confirmación para mostrar.

Cuando hay fusiones y seguimos a ambos padres, ambas "patas" de la fusión, o cuando otorgas git logo git rev-listmás de una confirmación inicial, las opciones de clasificación son importantes.

Por último, considere el efecto de un especificador de confirmación --noto ^delante de él. Estos tienen varias formas de escribirlos:

git log master --not develop

o:

git log ^develop master

o:

git log develop..master

todos significan lo mismo. El --notes como el prefijo ^excepto que se aplica a más de un nombre:

git log ^branch1 ^branch2 branch3

significa no branch1, no branch2, sí branch3; pero:

git log --not branch1 branch2 branch3

significa que no es branch1, no branch2, no branch3, y tienes que usar un segundo --notpara apagarlo:

git log --not branch1 branch2 --not branch3

lo cual es un poco incómodo. Las dos directivas "no" se combinan a través de XOR, por lo que si realmente lo desea, puede escribir:

git log --not branch1 branch2 ^branch3

para significar no branch1, no branch2, sí branch3 , si quieres ofuscar .

Todos estos funcionan al afectar el recorrido del gráfico. Como git logo git rev-listpaseos el gráfico, se asegura de no poner en la cola de prioridad ningún commit que es accesible desde cualquiera de los negados referencias. (De hecho, también afectan la configuración inicial: las confirmaciones negadas no pueden ir a la cola de prioridad directamente desde la línea de comando, por lo que git log master ^masterno muestra nada, por ejemplo).

Toda la elegante sintaxis descrita en la documentación de gitrevisions hace uso de esto, y puede exponerlo con una simple llamada a git rev-parse. Por ejemplo:

$ git rev-parse origin/pu...origin/master     # note: three dots
b34789c0b0d3b137f0bb516b417bd8d75e0cb306
fc307aa3771ece59e174157510c6db6f0d4b40ec
^b34789c0b0d3b137f0bb516b417bd8d75e0cb306

La sintaxis de tres puntos significa que las confirmaciones se pueden alcanzar desde el lado izquierdo o derecho, pero excluyendo las confirmaciones accesibles desde ambos . En este caso , se puede acceder a la origin/masterconfirmación b34789c0b,, desde origin/pu( fc307aa37...), por lo que el origin/masterhash aparece dos veces, una vez con una negación, pero de hecho Git logra la sintaxis de tres puntos colocando dos referencias positivas (las dos ID de hash no negadas) y uno negativo, representado por el ^prefijo.

Similarmente:

$ git rev-parse master^^@
2c42fb76531f4565b5434e46102e6d85a0861738
2f0a093dd640e0dad0b261dae2427f2541b5426c

La ^@sintaxis significa todos los padres de la confirmación dada , y él master^mismo, el primer padre de la confirmación seleccionado por nombre de rama, masteres una confirmación de fusión, por lo que tiene dos padres. Estos son los dos padres. Y:

$ git rev-parse master^^!
0b07eecf6ed9334f09d6624732a4af2da03e38eb
^2c42fb76531f4565b5434e46102e6d85a0861738
^2f0a093dd640e0dad0b261dae2427f2541b5426c

El ^!sufijo significa el compromiso en sí, pero ninguno de sus padres . En este caso, master^es 0b07eecf6.... Ya vimos a ambos padres con el ^@sufijo; aquí están de nuevo, pero esta vez, negadas.


1 Muchos programas de Git se ejecutan literalmente git rev-listcon varias opciones y leen su salida para saber qué confirmaciones y / u otros objetos de Git usar.

2 Debido a que el gráfico es acíclico , es posible garantizar que ninguno haya sido visitado ya, si agregamos la restricción nunca mostrar un padre antes de mostrar todos sus hijos a la prioridad. --date-order, --author-date-ordery --topo-orderagregue esta restricción. El orden de clasificación predeterminado, que no tiene nombre, no lo tiene. Si las marcas de tiempo de las confirmaciones son confusas, si, por ejemplo, algunas confirmaciones fueron realizadas "en el futuro" por una computadora cuyo reloj estaba apagado, esto podría en algunos casos conducir a resultados de apariencia extraña.


Si llegaste tan lejos, ahora sabes mucho sobre git log

Resumen:

  • git log se trata de mostrar algunas confirmaciones seleccionadas mientras se recorre parte o la totalidad de alguna parte del gráfico.
  • El --no-mergesargumento, que se encuentra tanto en las respuestas aceptadas como en las mejor clasificadas actualmente, suprime la visualización de algunas confirmaciones que se caminan.
  • El --first-parentargumento, de la respuesta actualmente mejor clasificada, suprime caminar algunas partes del gráfico, durante el recorrido del gráfico en sí.
  • El --notprefijo a los argumentos de la línea de comandos, como se usa en la respuesta aceptada, suprime la visita a algunas partes del gráfico, desde el principio.

Obtenemos las respuestas que nos gustan, a dos preguntas diferentes, utilizando estas funciones.

torek
fuente