(Esto comenzó como una respuesta a una pregunta duplicada. He hecho un poco de edición ligera para limpiarlo).
Todas las flechas internas de Git son unidireccionales, apuntando hacia atrás. Por lo tanto, no hay una sintaxis corta y conveniente para avanzar: simplemente no es posible.
Que es posible "movimiento en contra de las flechas", pero la manera de hacerlo es sorprendente si no se ha visto antes, y luego obvia después. Digamos que tenemos:
A <-B <-C <-D <-E <-- last
^
|
\--------- middle
Usando middle~2sigue las flechas dos veces de Catrás a A. Entonces, ¿cómo nos movemos de Ca D? La respuesta es: comenzamos en E, usando el nombre last, y trabajamos hacia atrás hasta llegar middle, registrando los puntos que visitamos en el camino . Luego nos movemos tan lejos como queremos en la dirección de last: mover un paso a D, o dos a E.
Esto es particularmente importante cuando tenemos sucursales:
D--E <-- feature1
/
...--B--C <-- master
\
F--G <-- feature2
¿Qué commit es un paso después C? No hay una respuesta correcta hasta que agregue a la pregunta: en la dirección de la función___ (complete el espacio en blanco).
Para enumerar las confirmaciones entre C(excluyendo C) en sí y, por ejemplo, Gusamos:
git rev-list --topo-order --ancestry-path master..feature2
Esto --topo-orderse asegura de que incluso en presencia de complejas ramificaciones y fusiones, los commits salgan en orden topológico. Esto solo es necesario si la cadena no es lineal. La --ancestry-pathrestricción significa que cuando trabajamos desde atrás feature2, solo enumeramos los commits que tienen commit Ccomo uno de sus propios antepasados. Es decir, si el gráfico, o el fragmento relevante de todos modos, en realidad se ve así:
A--B--C <-- master
\ \
\ F--G--J <-- feature2
\ /
H-------I <-- feature3
una simple solicitud del formulario feature2..masterenumera commits J, Gy I, y Fy Hen algún orden. Con --ancestry-pathnoqueamos Hy I: no son descendientes de C, solo de A. Con --topo-ordernos aseguramos de que el orden de enumeración real sea J, entonces G, entonces F.
El git rev-listcomando derrama estas identificaciones hash en su salida estándar, una por línea. Para avanzar un paso en la dirección de feature2, entonces, solo queremos la última línea.
Es posible (y tentador y puede ser útil) agregar --reversepara que git rev-listimprima las confirmaciones en orden inverso después de generarlas. Esto funciona, pero si lo usa en una tubería como esta:
git rev-list --topo-order --ancestry-path --reverse <id1>...<id2> | head -1
solo para obtener el "próximo commit en la dirección de id2", y hay una lista muy larga de commits, el git rev-listcomando puede obtener una tubería rota cuando intenta escribir en el headque dejó de leer su entrada y salió. Dado que el shell normalmente ignora los errores de tubería rota, esto funciona principalmente. Solo asegúrate de que se ignoren en tu uso.
También es tentador agregar -n 1al git rev-listcomando, junto con --reverse. ¡No lo hagas! Eso hace que git rev-listpare después de caminar un paso atrás y luego revierta la lista de confirmaciones visitadas (una entrada). Entonces esto solo produce <id2>cada vez.
Nota al margen importante
Tenga en cuenta que con los fragmentos de gráfico "diamante" o "anillo de benceno":
I--J
/ \
...--H M--... <-- last
\ /
K--L
moviendo una cometen "hacia adelante" de Hhacia lastobtendrá ya sea I o K . No hay nada que pueda hacer al respecto: ¡ambas confirmaciones son un paso adelante! Si luego comienza desde la confirmación resultante y da otro paso, ahora está comprometido con cualquier ruta en la que comenzó.
La cura para esto es evitar moverse un paso a la vez y quedar encerrado en cadenas dependientes de la ruta. En cambio, si planea visitar una cadena completa de ruta de ascendencia, antes de hacer cualquier otra cosa , haga una lista completa de todas las confirmaciones en la cadena:
git rev-list --topo-order --reverse --ancestry-path A..B > /tmp/list-of-commits
Luego, visite cada confirmación en esta lista, una a la vez, y obtendrá toda la cadena. Se --topo-orderasegurará de que golpee I-y- Jen ese orden, y K-y- Len ese orden (aunque no hay una manera fácil de predecir si hará el par IJ antes o después del par KL).