2011-07-20 67 views
59

Estoy haciendo un git bisect y después de llegar al compromiso problemático, ahora estoy tratando de dar un paso adelante/atrás para asegurarme de que estoy en la correcta.¿Cómo puedo avanzar y retroceder entre commits en git?

sé de HEAD^ a ir hacia atrás en la historia, pero es que hay otro acceso directo para que me hacia delante (hacia cometer un específico en el futuro), así:

A - B - C(HEAD) - D - E - F 

Yo sé que mi objetivo es F y quiero pasar de C a D.


NOTA: esto no es un duplicado de Git: How to move back and forth between commits, mi pregunta es ligeramente diferente y no se contesta no

+1

http://stackoverflow.com/questions/2263674/ how-do-i-find-the-next-commit-in-git puede ayudar también. – VonC

+0

'git checkout -b new_branch HEAD ~ 4' para volver 4 commits desde HEAD como en https://stackoverflow.com/a/4940090/911945 –

Respuesta

39

he experimentado un poco y esto parece hacer el truco para navegar hacia delante:

git checkout $(git rev-list --topo-order HEAD..towards | tail -1) 

donde towards es una SHA1 de la confirmación o una etiqueta.

Explicación:

  • el comando dentro $() significa: obtener todas las confirmaciones entre corriente y HEADtowards Commit (excluyendo HEAD), y ordenarlos en el orden de precedencia (como en git log por defecto - en lugar de el orden cronológico que es extrañamente el predeterminado para rev-list), y luego tome el último (tail), es decir, el que queremos ir.
  • esto se evalúa en la subselda y se pasa al git checkout para realizar un pago.

Puede definir una función accesible como un alias de parámetro-esperando en su archivo .profile para navegar hacia adelante hacia la confirmación en concreto:

# Go forward in Git commit hierarchy, towards particular commit 
# Usage: 
# gofwd v1.2.7 
# Does nothing when the parameter is not specified. 
gofwd() { 
    git checkout $(git rev-list --topo-order HEAD.."$*" | tail -1) 
} 

# Go back in Git commit hierarchy 
# Usage: 
# goback 
alias goback='git checkout HEAD~' 
+2

Going forward funciona bien en partes rectos de la historia, pero entra en bucles cuando se encuentra con una combinación. – Kostas

+0

Sí, en realidad no lo he probado en las fusiones. Trataré de echar un vistazo en el tiempo libre, pero tengo poco incentivo temporal, ya que hemos aceptado tener una historia estrictamente lineal en nuestro proyecto;) –

+2

¡Gran respuesta! Modificado para especificar automáticamente la rama actual: http://stackoverflow.com/a/23172256/480608 –

3
Probablemente no

la mejor manera, pero se puede utilizar git log para ver la lista de confirmaciones y luego usar git checkout [sha1 of D] para mover a D.

+5

No lo entiendo, si está en C, entonces git log will solo muéstrale C, B y A. – Bilthon

+0

Ok, lo tengo, pero tendrás que hacer un git-log complicado como se indica en el enlace dado por VonC – Bilthon

10

digamos F es el más reciente informe de cambios en trunk (insertar su propio nombre de la sucursal aquí) ... se puede hacer referencia a ella como trunk~0 (o simplemente trunk), e como trunk~1, D, e trunk~2 tc.

Eche un vistazo a su reflog para conocer más formas de nombrar commits.

+0

~ vuelve, no adelante, trunk ~ 2 es A – EmmanuelMess

28

Creo que se puede hacer:

git checkout [email protected]{1} 

Para ir uno, comprométase en el tiempo. Para avanzar varias confirmaciones, use HEAD @ {2}, HEAD @ {3}, etc.

+14

simplemente agregando un punto para mayor claridad para la posteridad: esto definitivamente no funciona. crea un HEAD separado y no en la confirmación correcta de todos modos. –

+3

* git reset HEAD @ {1} – xavier

+1

Después de mover la cabeza en cualquier confirmación en particular (HEAD separado) a través de 'git checkout HEAD @ {num}' podemos hacer 'git checkout -b ' para crear una nueva sucursal desde ese punto y luego podemos continuar comprometiéndonos como de costumbre. –

23

Todo lo que necesita para obtener un estado de cabeza claro y no separado es reiniciar, no finalizar la compra.

git reset [email protected]{1} 
1

Como solución alternativa, sólo puede volver a cabeza con

git checkout <branch> 

y luego pasar a la de comprometerse desea, con

git checkout HEAD~<offset> 
2

que acabo de hacer una prueba en este. decir, por ejemplo, usted está en rama principal Luego hacer:

git checkout [email protected]{3} 

Así cabeza se quita y, a continuación, puede intentarlo de nuevo para ir a cualquier otro compromiso:

git checkout [email protected]{4} 

vez que haya terminado mirando a su alrededor, puede volver a su estado original simplemente visitando esa sucursal. En mi ejemplo: rama principal

git checkout master 

Si no quiere ir a su estado original, y desea a fin de mantener una de las confirmaciones como la cabeza y continuar a partir de ahí, entonces usted necesita para expandirse desde allí. por ejemplo después de "git checkout CABEZA @ {4}", puede emitir

git checkout -b MyNewBranch 
8

Esto es lo que estoy usando para navegar hacia atrás y hacia adelante.

en movimiento para cometer próxima

function n() { 
    git log --reverse --pretty=%H master | grep -A 1 $(git rev-parse HEAD) | tail -n1 | xargs git checkout 
} 

mover a la confirmación anterior

function p() { 
    git checkout HEAD^1 
} 
0

Atravesando hacia atrás es trivial, ya que se están moviendo hacia abajo del árbol, y siempre hay un camino a seguir

function git_down 
     git checkout HEAD^ 
    end 

cuando se atraviesa hacia adelante va a mover el árbol, por lo que necesita ser explícito qué rama que se dirigen:

function git_up 
     git log --reverse --pretty=%H $argv | grep -A 1 (git rev-parse HEAD) | tail -n1 | xargs git checkout 
    end 

Uso: , git up <branch-name>

Cuestiones relacionadas