2010-01-22 61 views
63

Tengo una pregunta de novato sobre Git:Git: Cómo moverse hacia atrás y hacia adelante entre confirmaciones

Tengo que moverme hacia adelante y hacia atrás en el historial de una sucursal. Eso significa que necesito poner todos los archivos en el estado en el que estaban en una revisión anterior, y luego tengo que volver al último estado en el repositorio. No necesito comprometerme.

con SVN, sería

svn up -r800 

para llegar a la revisión 800, y

svn up 

a ponerse en sintonía con el repositorio.

sé el hash del comprometo Quiero volver a, por lo que intentaron

git reset <hash> 

que parece conseguirme allí. Pero entonces traté

git pull 

pero que se queja de conflictos.

Entonces, ¿cuál es la forma correcta de recorrer el historial de la sucursal?

Estoy pensando en términos de SVN, así que no hezitate para señalarme un buen tutorial. Tenga en cuenta que ya he comprobado http://git.or.cz/course/svn.html y http://www.youtube.com/watch?v=8dhZ9BXQgc4.

Gracias, Ondra.

+1

Nota al margen: me acostumbré a evitar 'git pull' en conjunto. En su lugar, uso 'git fetch --all' aliased to' gu' en bash, y tengo 'gitk' abierto todo el tiempo, viendo todas las ramas - ver View -> edit -> check all 4 checkboxes. Luego me muevo usando 'git reset' o' gist stash' + 'git co', depende de lo que necesito. –

Respuesta

59

Bueno, también soy usuario de svn y ahora uso git para todos mis proyectos.

Al usar git, debe cambiar la forma de pensar de la arquitectura cliente-servidor que se usa en svn. En svn, cada cambio necesita una conexión con el servidor. Usando git, su repositorio está en el directorio de trabajo. No necesita una conexión para cada acción de repos.

Solo use git push y git pull para sincronizar con el repositorio. Piense en ello como usar rsync o cualquier solución de copia de seguridad, para hacer que dos lugares tengan exactamente el mismo contenido. Al igual que usted conecta el disco duro de respaldo externo, luego haga que el contenido sea igual al contenido en su main. Ese es el uso de git pull y git push.

Si solo desea ir y venir de la historia, hágalo usando git checkout. Consulte la id. De revisión usando git history. Si está utilizando Linux, use gitk para ver el árbol de revisiones. En Windows, tortuga git puede mostrarlo usando un gráfico de revisión.

Para volver a la última revisión, use git checkout master. Antes de hacer ningún comando, siempre hazte tú mismo git status. Este comando mostrará todo lo que necesita saber sobre la condición repo actual y qué acción debe hacer para corregirlo. Antes de git pull y git push, es mejor asegurarse de que el resultado git status contenga el texto working directory clean.

Si necesita revertir un archivo a su revisión anterior, puede hacerlo con git merge. Antes de hacerlo en un archivo, pruébelo primero con git diff. Ej .: git diff rev1:rev2 filename. Imprimirá cualquier diferente entre dos revisiones. El cambio en rev1 será reemplazado por los cambios en rev2. Entonces, para revertir, rev2 será más antiguo que rev1. Después de cumplir con el resultado diff, hágalo con git merge, simplemente reemplace diff con merge, todos los demás parámetros se mantienen igual.

Espero que esto te ayude. La clave principal es ver que su directorio de trabajo es su repositorio. Entender esto te ayudará a usar git para que tenga plena capacidad. Buena suerte.

37

Puede usar git checkout para pagar cualquier compromiso y luego usarlo con un nombre de rama para volver a una rama con nombre.

git checkout con un id. De confirmación y no un nombre de sucursal lo desplaza de una rama con nombre a la llamada cabeza separada.

Si usa git reset, su buzón volverá a su estado anterior y ordene las confirmaciones más recientes que probablemente no sean las deseadas.

+0

¿Qué hace el 'pago y envío' realmente? ¿Cambia los archivos al estado de la confirmación dada, aplicando de forma inversa los parches de las confirmaciones entre el estado actual y el estado de la confirmación dada? –

+0

He encontrado 'git reset' y' git reset origin'. No haré ningún commit, por lo que no importa si pierdo los commit recientes en cuanto a que sea fácilmente recuperable (lo que significa, con un solo comando). –

+1

git checkout no haga el cambio permanente. Para hacerlo, usa git merge. Ver mis respuestas –

6

A la caja una versión diferente de un archivo, utilice

git checkout rev -- filename 

Dónde rev puede ser el ID de un compromiso, el nombre de una rama, el nombre de una etiqueta, o una versión relativa.

Use git log, gitk para buscar versiones de examinar para ver qué versión del archivo desea.

Para hacer esta versión del archivo permanente, es necesario para cometer el archivo: git add filename; git commit filename

No recomendaría git pull para examinar las versiones, ya que hace un merge - potencialmente modifican su estado actual.

En este caso, no necesita usar git reset, a menos que tenga git add un archivo que decida no comprometer.

+0

jeebus dulce tenga cuidado al hacer esto. Mi compañero de trabajo hizo este comando para probar los cambios de mi sucursal, aniquiló aproximadamente una semana de mi trabajo y lo envió al repositorio al hacer esto ... – karina

+0

Mientras su compañero de trabajo no haya hecho un push -f, usted siempre podría revertir su compromiso y recuperar el trabajo perdido. Si tiene acceso al repositorio al que presionó, incluso un impulso de fuerza es recuperable a través de git reflog. Además, si todavía tiene su sucursal, es recuperable. Pero sí, debes tener cuidado. –

19

Las otras respuestas son informativos, pero creo que esto es más cercano a lo que el PO quiere:

Añadir estas dos funciones a su ~/.bashrc:

# checkout prev (older) revision 
git_prev() { 
    git checkout HEAD~ 
} 

# checkout next (newer) commit 
git_next() { 
    BRANCH=`git show-ref | grep $(git show-ref -s -- HEAD) | sed 's|.*/\(.*\)|\1|' | grep -v HEAD | sort | uniq` 
    HASH=`git rev-parse $BRANCH` 
    PREV=`git rev-list --topo-order HEAD..$HASH | tail -1` 
    git checkout $PREV 
} 

Uso:

$ git_prev 
Previous HEAD position was 7042c8a... Commit message2 
HEAD is now at d753ecc... Commit message1 

$ git_next 
Previous HEAD position was d753ecc... Commit message1 
HEAD is now at 7042c8a... Commit message2 

Nota: Estos comandos siempre ingresan al estado detached HEAD. Si git_prev luego git_next desde una sucursal actualmente desprotegida, terminará en la última revisión, pero estará en estado de HEAD separado. Haz git checkout BRANCH_NAME para volver a la normalidad.

+0

Una vez que esté haciendo tales cosas, echar un vistazo a git aliases puede valer la pena. – rethab

3

Pruebe git reflog, esta lista confirma los compromisos que ha realizado para alternar entre las confirmaciones, incluso las confirmaciones que ha perdido al finalizar una confirmación.

Luego puede probar git checkout <hash of a commit> para cambiar a esa confirmación.

Espero que esto ayude!

Cuestiones relacionadas