2011-04-28 12 views
363

Deseo descartar todos los cambios realizados después de confirmar <commit-hash>. Así que lo hice:Restablecer el control remoto a una determinada confirmación

git reset --hard <commit-hash> 

Ahora quiero hacer lo mismo con mi control remoto. ¿Cómo puedo hacer esto? He hecho algunos commits (y push) después de <commit-hash> y solo quiero descartarlos a todos. Es solo que algo fue terriblemente mal en el camino y no quiero empeorarlo de lo que ya es. ; (

Básicamente quiero rebobinar mi origin/master a <commit-hash>

+2

¿Estás seguro de que el 'origin/master' no ha sido extraído y presionado por otros usuarios?Cambiar la historia de un repositorio público (es decir, no local) es algo que desea evitar en todo momento. – vindia

Respuesta

638

Suponiendo que su rama se llama master tanto aquí como en forma remota, y que el mando a distancia se llama origin que podría hacer:

git reset --hard <commit-hash> 
git push -f origin master 

Sin embargo , debe evitar hacer esto si alguien más está trabajando con su repositorio remoto y ha retirado sus cambios. En ese caso, sería mejor que revert las confirmaciones que no desea, y luego presionar de manera normal.

Actualización: ha explicado a continuación que otras personas han retirado los cambios que ha realizado, por lo que es mejor crear una nueva confirmación que revierte todos esos cambios. Hay una buena explicación de sus opciones para hacer esto en this answer from Jakub Narębski. Cuál es el más conveniente depende de cuántas confirmaciones desea revertir y qué método tiene más sentido para usted.

Desde de su pregunta, está claro que ya ha utilizado git reset --hard para restablecer la rama master, puede que tenga que empezar usando git reset --hard ORIG_HEAD para mover su rama de vuelta a donde estaba antes. (Como siempre con git reset --hard, asegúrese de que git status esté limpio, que se encuentre en la rama derecha y que esté al tanto de git reflog como una herramienta para recuperar confirmaciones aparentemente perdidas). También debe verificar que ORIG_HEAD apunten hacia la derecha , con git show ORIG_HEAD.

+8

Peligro de peligro: este restablecimiento asume que la rama correspondiente (_tracking_) está actualmente desprotegida _y_ no hay cambios no comprometidos que desea mantener. ** Use 'git update-ref' en lugar de' reset --hard' **; le permitirá hacer lo mismo sin tener un árbol de trabajo/rama de verificación – sehe

+1

Veo. Ha sido empujado y cambiado por otros. Así que debería usar 'revert' pero digamos que quiero revertir los últimos 4 commits así que debería hacer' git revert comit1; git push; git revert comit2; git push; ... 'o simplemente' git revert commit4; git push'? – nacho4d

+0

@sehe: Dije mis suposiciones, y tenga en cuenta que @ nacho4d ** ya ha ejecutado ** el comentario 'git reset --hard'. Acepto que 'git reset --hard' es peligroso en general, pero recomendar que la mayoría de los usuarios de git utilicen el comando de plomería' git update-ref' es una muy mala idea: es difícil de usar correctamente y no hay controles de seguridad. –

44

me resolvió el problema como la suya por estos comandos:

git reset --hard <commit-hash> 
git push -f <remote> <local branch>:<remote branch> 
+0

gracias, esto funcionó, no el aceptado. –

40

Uso las otras respuestas si no le importa perder los cambios locales. Este método aún puede arruinar su control remoto si elige el hash de confirmación incorrecto para volver a.

Si lo que desea es hacer que el partido remota de una confirmación que ya está en su sucursal local:

  1. Haz no realice una puesta a cero.
  2. Usa git log para encontrar el hash de la confirmación que deseas que sea el control remoto. git log -p para ver los cambios, o git log --graph --all --oneline --decorate para ver un árbol compacto. (Tener ese último como alias en tu caparazón es muy útil.)
  3. Copia el hash.
  4. Ejecutar un comando como:

    git push --force <remote> <the-hash>:<the remote branch> 
    

    por ejemplo,

    git push --force origin 606fdfaa33af1844c86f4267a136d4666e576cdc:master 
    
+0

El gráfico fue un consejo muy bueno, acabo de agregar -5 para obtener solo los últimos n commits, era un árbol enorme. También evitar el reinicio es justo lo que estaba buscando. Excelente –

+0

@AlexanderD También puede agregar el alias a Git en lugar de su caparazón, por lo que funciona en todas partes. Git entiende los alias y las pestañas completas del comando completo para que pueda agregar argumentos. 'git config --global alias.graph 'log --graph --all --decorate --oneline'' es menos desordenado y aún así puedes limitarlo, por ejemplo:' git graph -5' – Walf

+0

¡Mejor! Esto resolvió el problema –

3

Mis dos centavos a las respuestas anteriores: si

git push --force <remote> <the-hash>:<the remote branch> 

todavía no funciona, es posible que desee editar sección de recepción <your-remote-repo>.git/config de archivo:

[receive] 
    #denyNonFastforwards = true 
    denyNonFastforwards = false 
1

Si Si desea una versión anterior del archivo, le recomendaría usar el proceso de pago de git.

git checkout <commit-hash> 

Hacer esto le enviará atrás en el tiempo, que no afecta el estado actual de su proyecto, se puede llegar a la línea principal git checkout línea principal

pero cuando se agrega un archivo en el argumento, ese archivo se devuelve a usted desde un tiempo anterior a su hora actual del proyecto, es decir, su proyecto actual se cambia y debe confirmarse.

git checkout <commit-hash> -- file_name 
git add . 
git commit -m 'file brought from previous time' 
git push 

La ventaja de esto es que no elimina la historia, y tampoco revertir un determinado cambio de código (Revert GIT)

Consulte más aquí https://www.atlassian.com/git/tutorials/undoing-changes#git-checkout

1

hacer una cosa, obtener el commit's SHA no. como 87c9808 y luego,

  1. mover por sí mismo, es decir la cabeza a la especificada comprometerse (haciendo git restablecer --hard 89cef43 // mencionar su número aquí)
  2. Siguiente hacer algunos cambios de forma aleatoria archivo, por lo que el git le pedirá que lo confirme localmente y luego de forma remota Por lo tanto, lo que necesita hacer ahora es. después de aplicar el cambio git commit -a -m "juicio cometió"
  3. Introducir la siguiente commit (si así se ha comprometido a nivel local) por git push origin master
  4. Ahora lo Git le pedirá a usted es que

error: failed to push some refs to ' https://github.com/YOURREPOSITORY/AndroidExperiments.git ' hint: Updates were rejected because the tip of your current branch is behind hint: its remote counterpart. Integrate the remote changes (e.g. hint: 'git pull ...') before pushing again.**

  1. Por lo tanto ahora lo que se puede hacer es

git push --force origin master

  1. Y así, espero que funcione :)
0

En GitLab, puede que tenga que configurar su rama en sin protección antes de hacer esto. Puede hacer esto en [repo]> Configuración> Depósito> Sucursales protegidas. Entonces el método de la respuesta de Marcos funciona.

git reset --hard <commit-hash> 
git push -f origin master 
Cuestiones relacionadas