Limpiar la twig de Git antes de empujar para dominar

A continuación se muestra un estado de confirmación simplificado en mi twig de desarrollo.

7f75hsyfr - changes to file1 file1 94dfsrg43 - more changes to file2 file2 92d7a513 - changes to file3 file3 035a72fd - Merge branch 'master' into dev 35bcc341 - Merge branch 'master' into dev 2e05a2fc - changes to file2 file2 60c9daaf - changes to file1 file1 

Como cambiaba de una twig a otra, estaba cometiendo un trabajo inacabado que dio como resultado varias confirmaciones relacionadas con los mismos files. También hay confluencias de fusión desde la fusión de cambios desde el maestro. ¿Cómo puedo limpiar las cosas antes de pasar a la twig principal? Idealmente, me gustaría reorganizar esto, por lo que hay una confirmación para cada file1 y file2 .

La respuesta corta

Si no tenía los commit de fusión, simplemente podría usar una rebase interactiva, como se señala en Combining multiple commits antes de presionar en Git .

También puedes deshacerte de las asignaciones de fusión simplemente networkingefiniendo o seleccionando las confirmaciones únicas de tu sucursal además del maestro, ya que el estado final de tu código será equivalente a haber realizado una combinación.

Para limpiar su sucursal, la siguiente solución combinará las confirmaciones de rebase y selección de cereza para eliminar las confirmaciones de fusión, y luego la reorganización interactiva para aplastar a las demás.

Rebase y Cherry-pick se compromete con el maestro

Crearemos una bifurcación temporal para mantener el estado actual del dev , a continuación, cambiaremos la base de las partes de dev antes de la fusión con el master en la parte superior del master , lo que es equivalente a haber fusionado el master en primer lugar:

 # Create temporary branch to save current state of dev git branch temp dev # Temporarily reset dev to state before the merges git reset --hard 2e05a2fc # Rebase dev onto master git rebase master 

A continuación, selecciona los commit restantes de temp . Utilizaremos un range de compromiso, donde el inicio del range es exclusivo (es decir, no está realmente incluido):

 git cherry-pick 035a72fd..7f75hsyfr 

Squash se compromete con Rebase interactivo

Ahora estás listo para aplastar los commits con rebase interactivo. Encuentre la confirmación reescrita que corresponde a 60c9daaf en su ejemplo. Vamos a llamar a cometer X Entonces

 git rebase -i X^ 

X^ representa el compromiso base de la rebase, que en realidad no cambiará. Sin embargo, cada compromiso descendiente no aparecerá en el editor de rebase interactivo, en order de mayor a menor:

 pick X changes to file1 pick Y changes to file2 pick Z changes to file3 pick AA more changes to file2 pick AB changes to file1 

Reorderar las confirmaciones para que las confirmaciones de cambio de un file sean adyacentes

 pick X changes to file1 pick AB changes to file1 pick Y changes to file2 pick AA more changes to file2 pick Z changes to file3 

A continuación, agregue squash o s a cada siguiente commit que quiera agregar al anterior:

 pick X changes to file1 squash AB changes to file1 pick Y changes to file2 squash AA more changes to file2 pick Z changes to file3 

Cuando haya terminado, guarde y salga del editor, y la rebase continuará a less que haya conflictos, en cuyo caso deberá resolver cada conflicto y continuar la rebase.

Verificar los resultados

Ahora querrá verificar sus resultados para asegurarse de que los cambios que ha realizado sigan siendo equivalentes al estado de su sucursal antes de comenzar a realizar modificaciones:

 git diff temp 

Si no hay salida, entonces el estado final de su bifurcación es el mismo que antes de que comenzara a modificarlo, por lo que ahora puede eliminar la temp con git branch -D temp .

Ver también

  • Pro Git .
    • § 3.6 Git Branching – Rebasing
    • § 6.4 Herramientas de Git – Reescribiendo el historial – Compromisos de aplastamiento
  • Página de manual de git-rebase (1) oficial

Necesitas el command git rebase -i . git rebase la documentation de git rebase . Puedes aplastar tus commits en un commit, reword, re-order y hacer cualquier tipo de limpieza antes de presionar para dominar. Como mencionaste haber fusionado commits, te recomendaría ejecutar git config --global pull.rebase true que garantizará que en el futuro, cada vez que git config --global pull.rebase true de una twig remota, tus commits se vuelvan a aplicar luego de que el jefe de tu sucursal local obtenga actualizado. Esto significa que no terminará con confusiones de fusión entre sus commits. También facilita las cosas, mientras que seleccionar y combinar esto con git rebase puede ser muy útil al revertir los cambios.

No creo que haya una razón en particular para hacer esto, normalmente mantendría intactas todas las confirmaciones. Sin embargo, si desea hacer esto, puede crear un file de parche y aplicarlo en el maestro. Usualmente utilizo gitk para crear parches, ya que hace que sea bastante fácil elegir el inicio y el final, pero también hay un command para hacer esto.

Editar:

La solución de command-line sería algo así como:

 git checkout <branch> git format-patch master --stdout > ../blahblah.patch git checkout master git apply ../blahblah.patch git add . git commit . -m"apply changes from branch" 

Eso pondría todos los cambios de la bifurcación en una confirmación, pero podría elegir cuidadosamente e includelos como usted elija.