remota rama origin example cambiar git branch cherry-pick

rama - git pull origin master



¿Cómo divido una rama grande de Git en muchas ramas más pequeñas? (5)

He importado de SVN a Git, ahora tengo una gran sucursal, como esta:

  • trabajar en la característica C
  • trabajar en la característica B
  • trabajar en la característica C
  • trabajar en la característica C
  • trabajar en la característica B
  • trabajar en la característica A

Quiero ramas de características separadas, para A, B, C. Me dedico a elegir nuevas sucursales, pero esto no las elimina de la rama original, por lo que tengo que rastrear manualmente cuáles he sacado.

Hay alrededor de 800 confirmaciones para dividir, y tal vez 50 características / correcciones de errores.

Sería bueno que los que he sacado se reflejen de alguna manera en el registro de git, así que sé cuáles ya he hecho. es posible?

Puedo cambiar de base la rama completa, saltándome los compromisos que he sacado, pero me preocupa que esto cause muchos conflictos. No quiero resolver 500 conflictos cada vez que hago un compromiso.

¿Cuál es el mejor método para extraer los compromisos de una rama súper en ramas más pequeñas, al mismo tiempo que realiza un seguimiento de su progreso?


Lo que hago en este caso es usar rebase interactivo .

En tu HEAD , crea tus ramas A , B y C También cree una rama de "copia de seguridad" (podría llamarlo backup ) en caso de que las cosas salgan mal y necesite su HEAD original.

git branch feature-a git branch feature-b git branch feature-c git-branch backup-before-rebase

Luego, cree una rama en la confirmación desde la que desea que empiecen, tal vez en una confirmación estable y conveniente. Llámalo new_trunk o algo así.

git checkout HEAD~50 ## this will be the new tree-trunk git branch new_trunk

Luego, realice rebase interactivas y seleccione los compromisos que desea mantener en esa rama. Usado de esta manera, es básicamente como cherry-pick de cherry-pick a granel.

git checkout feature-a git rebase -i new_trunk ## -i is for "Interactive"

Cuando hayas terminado, deberías tener 3 ramas con historiales separados comenzando desde new_trunk y una rama de backup refleje la antigua HEAD si aún la necesitas.


Otro método que acabo de descubrir es usar "notas de git".

http://alblue.bandlem.com/2011/11/git-tip-of-week-git-notes.html

Esta función permite agregar comentarios a las confirmaciones existentes sin cambiar realmente la sucursal / requiriendo una rebase. Un método para rastrear las confirmaciones que se han extraído es agregar una nota de git a cada una:

Cherry-picked to features/xyz 925a5239d4fbcf7ad7cd656020793f83275ef45b

Esto podría ayudar en un proceso en gran parte manual: puede escribir un pequeño script para elegir un compromiso para una rama en particular y luego agregar la nota de git relevante a la confirmación original.

Alternativamente, si desea obtener realmente funky, puede automatizar todo el proceso, mediante:

  1. Agregue una nota de git a cada confirmación, indicando qué rama de función desea que se seleccione: TOCHERRYPICK: features/xyz
  2. Escriba una secuencia de comandos para escanear todas las notas de git, cree automáticamente todas las ramas de características y seleccione los compromisos correctos seleccionados. Luego podría cambiar la nota de git a CHERRYPICKED: features/xxx at 925a5239d4fbcf7ad7cd656020793f83275ef45b para permitir que la herramienta se vuelva a ejecutar más tarde para seleccionar más confirmaciones.
  3. Si está realmente interesado en hacerlo prominente cuando se ha seleccionado una confirmación, también puede automatizar la creación de una etiqueta con un nombre similar: CHERRYPICKED:<branch>:SHA

Personalmente, realmente consideraría los pros y los contras de cambios tan grandes (una vez más si ya lo ha hecho). Si se topa con conflictos (que se encuentran en un gran rebase / selección molesta y difícil de resolver por sí mismo) probablemente tendrá momentos difíciles al fusionar las características con su rama "maestra".

¿No sería mejor / más fácil congelar tu rama grande, hacerla "hecha" (o "lo suficientemente buena") y crear nuevas características en ella? (¿O excluir sólo algunas ramas?)

Pero a tu pregunta:

Si desea realizar un seguimiento de los cambios / confirmaciones faltantes, utilice automáticamente el comando git cherry.

git cherry featureBranch bigBranch

Si no hubo conflictos al cambiar o rebasar su rama de función, puede usar el código anterior con algunas canalizaciones adicionales:

git cherry featureBranch bigBranch | awk ''{ print "pick " $2 }'' | tee remaining

Esto imprimirá (y se guardará en el archivo llamado "restante") los errores faltantes en featureBranch. Puede agregar esto a la rebase interactiva en bigBranch para deshacerse de los compromisos que ya no desea. (Tal vez puedas escribirlo aún más con el editor "ed" como editor de git y pasar comandos a la entrada estándar de rebase interactiva, pero no lo probé).


Sólo para simplificar aún más la respuesta de Willoller ,

hacer las ramas de características, y copia de seguridad, en el caso

git branch feature-a git branch feature-b git branch feature-c git branch backup-before-rebase

luego verifique una rama de funciones y realice una rebase interactiva desde el compromiso desde el que desea que empiecen

git checkout feature-a git rebase -i <safecommit> enter code here

Si desea que algunas ramas de características compartan algunos compromisos para mantener limpio su árbol, no cree la última rama de características al comienzo, pero una vez que tenga una rama de características reajustada y luego use la referencia de confirmación compartida como su próximo compromiso de seguridad

#on branch feature-a git checkout -b feature-d git rebase -i <sharedcommit>


Honestamente, no haría esto a menos que tenga una gran lista de confirmaciones que necesitan dividirse y son características muy independientes, es decir, no alteran la misma línea donde habría conflictos que resolver.

Como otros lo han sugerido, cree una nueva rama para cada función y use git rebase --interactive para incluir los compromisos deseados.

Para asegurarse de que ninguno se desvíe, cree el contenido de los archivos git-rebase-todo mediante

  • Editar una lista de todas las confirmaciones deseadas y clasificarlas por características
  • separando la lista de confirmaciones en archivos separados

Puede crear la lista de confirmaciones usando un comando como

git log --oneline --reverse 44e19^... > log.txt

para visualizar commit 44e19 en adelante. Esto te dará un archivo como este.

44e1936 dSRGratuities (SummaryRecord) 67fedda Receipt Report HEADER: 20! multiply by Paym_FieldCount 69d70e2 Receipt Report: Payment ....

que cuando se edita puede parecerse a mi sorted.txt

c 44e1936 dSRGratuities (SummaryRecord) a 67fedda Receipt Report HEADER: 20! multiply by Paym_FieldCount b 69d70e2 Receipt Report: Payment c abea7db Receipt Report: Cashback a cf96185 Receipt Report: Gratuity c 70e987a Receipt Report: use amount tendered for printing a 7722ac8 Receipt Report: use amount tendered for calculations c 47f1754 Receipt Report: store amount tendered b b69a73f Receipt Report: Use enum Paym_FieldCount a 9a0b471 Receipt Report HEADER: enum PaymentEntries (with Paym_FieldCount) c ad67e79 Use SharpReport enum b 3c510c6 enum SharpReport a e470e07 m_Gratuities m_dSSGratuities (SalesSummary) b 4e0c3e4 m_Gratuities m_szGratuities (SalesSummaryRecord) b bd054f7 _gx_fn_Cashback

Luego git-rebase-todo un script en su lenguaje de scripting favorito para convertir la lista ordenada en una colección de archivos git-rebase-todo . Tu guión podría parecerse al que acabo de escribir.

foreachline text sorted.txt { set fields [split $text { }] set branch [lindex $fields 0] set commit [lindex $fields 1] set comment [string range $text 10 end] set command "echo pick $commit $comment" exec cmd /S /C $command >> $branch.txt }

La secuencia de comandos lee el archivo de clasificación de compromiso línea por línea y se divide por un carácter de espacio {} para obtener la branch y el commit dos campos, y toma una subcadena (caracteres 10 en adelante) para una descripción del compromiso. La descripción no es necesaria pero es útil para nosotros, los humanos, verificar errores.

Luego coloca una línea en el archivo git-rebase-todo apropiado, creando un archivo por característica. Hacké esto ejecutando un muy feo comando de echo string >> file Windows echo string >> file .

Esto crea una serie de archivos, por ejemplo, mi archivo a.txt

pick 67fedda Receipt Report HEADER: 20! multiply by Paym_FieldCount pick cf96185 Receipt Report: Gratuity pick 7722ac8 Receipt Report: use amount tendered for calculations pick 9a0b471 Receipt Report HEADER: enum PaymentEntries (with Paym_FieldCount) pick e470e07 m_Gratuities m_dSSGratuities (SalesSummary)

Todo el asunto es feo. No lo recomiendo a menos que tenga que hacerlo y sea bueno escribiendo guiones.