Buscar..
Deshaciendo las fusiones
Deshacer una fusión que aún no se ha enviado a un control remoto
Si aún no ha enviado su combinación al repositorio remoto, puede seguir el mismo procedimiento que para deshacer la confirmación, aunque existen algunas diferencias sutiles.
Un restablecimiento es la opción más sencilla, ya que deshará el compromiso de fusión y cualquier compromiso agregado de la rama. Sin embargo, tendrá que saber a qué SHA restablecer, esto puede ser complicado ya que su git log
ahora mostrará confirmaciones de ambas ramas. Si restablece la confirmación incorrecta (por ejemplo, una en la otra rama) puede destruir el trabajo realizado.
> git reset --hard <last commit from the branch you are on>
O bien, suponiendo que la combinación fue su compromiso más reciente.
> git reset HEAD~
Una reversión es más segura, ya que no destruirá el trabajo comprometido, pero implica más trabajo, ya que tiene que revertir la reversión antes de poder volver a fusionar la rama (consulte la siguiente sección).
Deshacer una fusión empujada a un control remoto
Supongamos que se fusiona en una nueva característica (add-gremlins)
> git merge feature/add-gremlins
...
#Resolve any merge conflicts
> git commit #commit the merge
...
> git push
...
501b75d..17a51fd master -> master
Luego descubre que la función que acaba de fusionar rompió el sistema para otros desarrolladores, debe deshacerse de inmediato y arreglar la función en sí tomará demasiado tiempo, así que simplemente desea deshacer la fusión.
> git revert -m 1 17a51fd
...
> git push
...
17a51fd..e443799 master -> master
En este punto, los gremlins están fuera del sistema y tus compañeros desarrolladores han dejado de gritarte. Sin embargo, todavía no hemos terminado. Una vez que solucione el problema con la función add-gremlins, deberá deshacer esta reversión antes de poder volver a fusionarla.
> git checkout feature/add-gremlins
...
#Various commits to fix the bug.
> git checkout master
...
> git revert e443799
...
> git merge feature/add-gremlins
...
#Fix any merge conflicts introduced by the bug fix
> git commit #commit the merge
...
> git push
En este punto, su función ahora se ha añadido correctamente. Sin embargo, dado que los errores de este tipo a menudo se introducen mediante conflictos de combinación, un flujo de trabajo ligeramente diferente a veces es más útil ya que le permite corregir el conflicto de combinación en su rama.
> git checkout feature/add-gremlins
...
#Merge in master and revert the revert right away. This puts your branch in
#the same broken state that master was in before.
> git merge master
...
> git revert e443799
...
#Now go ahead and fix the bug (various commits go here)
> git checkout master
...
#Don't need to revert the revert at this point since it was done earlier
> git merge feature/add-gremlins
...
#Fix any merge conflicts introduced by the bug fix
> git commit #commit the merge
...
> git push
Utilizando reflog
Si arruinas una rebase, una opción para comenzar de nuevo es volver a la confirmación (pre rebase). Puede hacer esto utilizando reflog
(que tiene el historial de todo lo que ha hecho durante los últimos 90 días, esto se puede configurar):
$ git reflog
4a5cbb3 HEAD@{0}: rebase finished: returning to refs/heads/foo
4a5cbb3 HEAD@{1}: rebase: fixed such and such
904f7f0 HEAD@{2}: rebase: checkout upstream/master
3cbe20a HEAD@{3}: commit: fixed such and such
...
Puede ver que la confirmación antes de la rebase era HEAD@{3}
(también puede verificar el hash):
git checkout HEAD@{3}
Ahora creas una nueva rama / borra la antigua / prueba el rebase nuevamente.
También puede restablecer directamente a un punto en su reflog
, pero solo haga esto si está 100% seguro de que es lo que quiere hacer:
git reset --hard HEAD@{3}
Esto configurará su árbol de git actual para que coincida con la forma en que estaba en ese punto (consulte Deshacer cambios).
Esto se puede usar si está viendo temporalmente qué tan bien funciona una rama cuando se rebasa en otra, pero no desea conservar los resultados.
Volver a un commit anterior
Para volver a una confirmación anterior, primero encuentre el hash de confirmación utilizando git log
.
Para saltar temporalmente a ese compromiso, separe su cabeza con:
git checkout 789abcd
Esto te coloca en cometer 789abcd
. Ahora puedes hacer nuevos compromisos sobre este antiguo compromiso sin afectar la rama en la que se encuentra tu jefe. Cualquier cambio se puede hacer en una rama apropiada usando una branch
o un checkout -b
.
Para retroceder a un compromiso anterior manteniendo los cambios:
git reset --soft 789abcd
Para deshacer el último commit:
git reset --soft HEAD~
Para descartar permanentemente cualquier cambio realizado después de un compromiso específico, use:
git reset --hard 789abcd
Para descartar permanentemente cualquier cambio realizado después de la última confirmación:
git reset --hard HEAD~
Cuidado: si bien puede recuperar las confirmaciones descartadas utilizando la reflog
reset
y reset
, los cambios no confirmados no se pueden recuperar. Use git stash; git reset
de git reset --hard
lugar de git stash; git reset
de git reset --hard
estar seguro.
Deshaciendo cambios
Deshacer cambios en un archivo o directorio en la copia de trabajo .
git checkout -- file.txt
Utilizado en todas las rutas de archivo, recursivamente desde el directorio actual, deshará todos los cambios en la copia de trabajo.
git checkout -- .
Para deshacer solo partes de los cambios use --patch
. Se le pedirá, para cada cambio, si se debe deshacer o no.
git checkout --patch -- dir
Para deshacer los cambios añadidos al índice .
git reset --hard
Sin el indicador --hard
esto hará un reinicio suave.
Con confirmaciones locales que aún no hayas presionado a un control remoto, también puedes hacer un reinicio por software. Por lo tanto, puede volver a trabajar los archivos y luego los compromisos.
git reset HEAD~2
El ejemplo anterior desenrollaría sus dos últimas confirmaciones y devolvería los archivos a su copia de trabajo. A continuación, podría realizar más cambios y nuevos compromisos.
Cuidado: todas estas operaciones, aparte de los restablecimientos de software, eliminarán de forma permanente los cambios. Para una opción más segura, use git stash -p
o git stash
, respectivamente. Más tarde, puede deshacer con stash pop
o eliminar para siempre con stash drop
.
Revertir algunos compromisos existentes
Utilice git revert para revertir las confirmaciones existentes, especialmente cuando esas confirmaciones se han enviado a un repositorio remoto. Registra algunas confirmaciones nuevas para revertir el efecto de algunas confirmaciones anteriores, que puede presionar de forma segura sin tener que volver a escribir el historial.
No use git push --force
menos que desee derribar el oprobio de todos los demás usuarios de ese repositorio. Nunca reescriba la historia pública.
Si, por ejemplo, acaba de subir una confirmación que contiene un error y necesita hacer una copia de seguridad, haga lo siguiente:
git revert HEAD~1
git push
Ahora tiene la libertad de revertir el compromiso de revertir localmente, corregir su código y presionar el código correcto:
git revert HEAD~1
work .. work .. work ..
git add -A .
git commit -m "Update error code"
git push
Si el compromiso que desea revertir ya está más atrás en el historial, simplemente puede pasar el hash de compromiso. Git creará un contra-compromiso deshaciendo su compromiso original, que puede enviar a su control remoto de forma segura.
git revert 912aaf0228338d0c8fb8cca0a064b0161a451fdc
git push
Deshacer / Rehacer una serie de confirmaciones
Supongamos que desea deshacer una docena de confirmaciones y desea solo algunas de ellas.
git rebase -i <earlier SHA>
-i pone rebase en "modo interactivo". Comienza como la rebase discutida anteriormente, pero antes de volver a reproducir cualquier confirmación, se detiene y le permite modificar suavemente cada confirmación a medida que se reproduce. rebase -i
se abrirá en su editor de texto predeterminado, con una lista de confirmaciones aplicadas, como esta:
Para eliminar una confirmación, simplemente elimine esa línea en su editor. Si ya no desea las confirmaciones erróneas en su proyecto, puede eliminar las líneas 1 y 3-4 anteriores. Si desea combinar dos confirmaciones juntas, puede usar los comandos squash
o fixup