2010-08-01 21 views
159

En Git, digamos que cometí errores en mis compromisos, y quiero hacer la versión 3 confirma como la nueva versión. Si hago git checkout xxxx, crea una nueva rama y parece que solo puedo fusionarla? ¿Podría hacer de esto la nueva "versión maestra"?Pagar la confirmación anterior y convertirla en una confirmación nueva

Quiero:

A-B-C-D-E 

para convertirse en

A-B-C-D-E-F 

donde F tiene exactamente el mismo contenido que C

Si uso git revert xxxx en cambio, parece que definitivamente tendrá conflictos y necesito resolverlo manualmente

Lo que realmente quiero es solo hacer la confirmación anterior en algún momento de la nueva confirmación, independientemente de lo que haya en mi directorio de trabajo o la última confirmación.

¿Cómo voy a hacer esto?

Respuesta

178
git rm -r . 
git checkout HEAD~3 . 
git commit 

Después de la confirmación, los archivos de la nueva HEAD serán los mismos que en la revisión HEAD~3.

+0

Esto parece hacer lo que quiero. Gracias. Si quiero referirme a la versión de SHA-1 hash, ¿debería estar haciendo git checkout HEAD ~ XXXXX? – huggie

+7

No, solo 'git checkout XXXXX'. 'rev ~ n' significa * n * revisiones antes de' rev'. – svick

+75

El punto después de HEAD ~ 3 es importante. – bbuser

27

Parece que solo quiere restablecer a C; es decir hacer que el árbol:

ABC

Usted puede hacer eso con reset:

git reset --hard HEAD~3 

(Nota: Usted dijo hace tres confirmaciones así que eso es lo que he escrito; en su el ejemplo C solo hace dos commits, por lo que es posible que desee utilizar HEAD~2)


También puede utilizar revert si lo desea, aunque por lo que yo sé que hay que hacer las revierte uno a la vez:

git revert HEAD  # Reverts E 
git revert HEAD~2 # Reverts D 

que va a crear un nuevo comprometerse F que es el mismo contenido que D, y G que es el mismo contenido que C. puede rebase para aplastar los juntos si usted quiere

+3

Hola gracias por la respuesta. Pero, ¿qué pasa si no quiero hacer el restablecimiento completo ya que ya está en un repositorio público? – huggie

+1

@huggie Ah. Entonces probablemente quiera usar el método de reversión –

+0

y luego git push -f para forzar push – radtek

2

Las otras respuestas hasta ahora crean nuevas confirmaciones que deshacen lo que está en las confirmaciones más antiguas. Es posible volver atrás y "cambiar el historial" por así decirlo, pero esto puede ser un poco peligroso. Debe solo hacer esto si la confirmación que está modificando no se ha enviado a otros repositorios.

El comando que estás buscando es git rebase --interactive

Si desea cambiar CABEZA ~ 3, el comando que desea emitir es git rebase --interactive HEAD~4. Esto abrirá un editor de texto y le permitirá especificar qué confirmaciones desea cambiar.

Practique en un repositorio diferente antes de intentar esto con algo importante. Las páginas de manual deberían proporcionarle todo el resto de la información que necesita.

+0

Vota abajo. 1. la pregunta pide explícitamente mantener confirmaciones más antiguas, por lo que podría ser una razón por la que otras respuestas intentan hacer eso. 2. Como dijiste, los commits podrían haberse publicado y no es necesario introducir comentarios sobre lo que eso significa con el rebasamiento. – tishma

5

git cherry-pick C

donde C es el hash comprometerse para C. Esto se aplica el viejo se comprometen en la parte superior de la más reciente.

+11

'git cherry-pick C' toma los * cambios * introducidos por C y los aplica encima de E. Esto no es lo que solicitó el OP. Quiere tener los archivos en el estado exacto en que estaban en C, lo que proporciona 'git checkout'. – gotgenes

13

Esto es exactamente lo que quería hacer. No estaba seguro del comando anterior git cherry-pick C, suena bien pero parece que haces esto para obtener cambios de otra rama pero no en la misma rama, ¿alguien lo ha intentado?

así lo hice otra cosa que también trabajó: tengo los archivos que quería desde el archivo cometer antiguo, utilizando el archivo de

git checkout <commit-hash> <filename> 

ejemplo: git checkout 08a6497b76ad098a5f7eda3e4ec89e8032a4da51 file.css

-> esto se lleva a los archivos como eran del antiguo commit

Luego hice mis cambios. Y me comprometí de nuevo.

git status (to check which files were modified) 
git diff (to check the changes you made) 
git add . 
git commit -m "my message" 

he comprobado mi historia con git log, y todavía tengo mi historia junto con mis nuevos cambios realizados a partir de los viejos archivos. Y yo podría empujar también.

Tenga en cuenta que para volver al estado que desea, debe colocar el hash de la confirmación antes de los cambios no deseados. También asegúrese de no tener cambios no confirmados antes de hacerlo.

6

eloone lo hizo archivo por archivo con

git checkout <commit-hash> <filename> 

pero se puede pago y envío todos los archivos más fácilmente haciendo

git checkout <commit-hash> . 
+0

Esto causa rechazo al empujar hacia el origen. – jtheletter

+0

Esto funciona para mí. Empujar hacia el origen no fue un problema. – Noffls

Cuestiones relacionadas