git: mejor forma de revertir git sin commit revertido adicional

Tengo un compromiso en una sucursal remota + local y quiero descartar ese compromiso del historial y poner algunos de ellos en una twig propia.

Básicamente, ahora tengo:

D---E---F---G master 

Y yo quiero:

  E---G topic / D master 

Eso debería ser tanto en mi local como en el (hay solo un, llamado origen) repository remoto.

¿Cuál es la forma más limpia de get eso?

Además, también hay otras personas que han clonado ese informe y que han verificado la twig principal. Si hiciera un cambio de este tipo en el repository remoto, ¿funcionaría 'git pull' para que ellos también lleguen al mismo estado?

Si ha publicado, tiene razón en que no desea volver a escribir la historia del master . Lo que desea es publicar un compromiso de dominar que lo devuelva al estado en el que estaba en D , conservando su historial actual para que otros usuarios puedan fusionar o modificar su trabajo fácilmente.

Si planea en algún momento en el futuro fusionar el topic en master entonces lo que probablemente también quiera hacer es crear una nueva base común entre el master y el topic , de modo que cuando fusione el topic posteriormente, no pierda los commits. que fueron revertidos en el master . La forma más sencilla de hacerlo es haciendo una confirmación 'rehacer' encima de la confirmación 'deshacer' que restablece el master a su estado original y basando la nueva twig de topic sobre eso.

 # checkout master branch (currently at G) git checkout master # Reset the index to how we want master to look like git reset D # Move the branch pointer back to where it should be, leaving the index # looking like D git reset --soft HEAD@{1} # Make a commit (D') for the head of the master branch git commit -m "Temporarily revert E, F and G" # Create the new topic branch based on master. # We're going to make it on top of master and the 'undo' # commit to ensure that subsequent merges of master->topic # or topic->master don't merge in the undo. git checkout -b topic # Revert the undo commit, making a networkingo commit (G'). git revert HEAD 

Como alternativa, podría haber hecho commits E ', F' y G 'rehaciendo cada parte por separado, pero como E, F y G ya están en su historial publicado, probablemente sea más comprensible si solo hace reference al compromiso' deshacer 'y dice que cometer se está deshaciendo Esto es lo que hace git revert , de todos modos.

Esencialmente, lo que sabes tiene es esto.

 D -- E -- F -- G -- D' <-- master \ \ G' <-- topic 

Lo importante es que no ha reescrito el historial y el tema está basado en el maestro, por lo que las fusiones no aplicarán accidentalmente ninguna confirmación de "deshacer". Ahora puede enviar de forma segura tanto el master como el topic a su repository remoto.

Puede reescribir su historial si lo desea, pero es una mala idea si alguien más tiene copys del historial. En este caso, probablemente usarías rebase interactivo: git rebase -i master topic . Esto le dará una list de confirmaciones de maestro a tema, con consejos sobre cómo jugar con ellos. Solo necesitarás eliminar la línea que contiene la confirmación que deseas eliminar.

Dicho esto, debo enfatizar que es irresponsable hacer esto si alguien más tiene este historial. Debería forzarlo a su repo central, y todos los demás tendrían que arreglar sus repositorys para que coincidan, puede ser relativamente simple o complejo dependiendo de las circunstancias.

Hay una buena sección llamada "recuperación desde el rebase ascendente" en la página de manual de git-rebase que trata sobre cómo lidiar con esto, si realmente lo decides.

Editar:

Para la historia simple, un escenario común sería, después de forzar un empuje no rápido hacia el repository central ( push -f ), otros desarrolladores:

  • copy de security de su antiguo maestro: git branch -m master master_old
  • get actualizaciones y recrear maestro desde el origen: git remote update origin; git branch master origin/master git remote update origin; git branch master origin/master
  • rebase todas las twigs de tema en el nuevo maestro: git rebase --onto master master_old topic

Si tienen trabajo en su twig principal que aún no está en su origen, tendrán que ser más elegantes, volver a basar este trabajo y todas las twigs temáticas en el nuevo puesto de maestro … esto debería darte una idea de por qué es tan horrible reescribe la historia que otras personas tienen. Realmente, una vez que algo ha pasado al repository público, debe considerarlo como un historial grabado rápido y no como un trabajo en progreso.

Encuentro que el git stash es bastante útil

Solo guárdelo y nunca lo vuelva a mirar.