commits - how to do cherry pick in git
Git Cherry-pick vs Merge Workflow (3)
Suponiendo que soy el mantenedor de un repositorio, y quiero obtener cambios de un colaborador, hay algunos flujos de trabajo posibles:
-
cherry-pick
cada compromiso desde el control remoto (en orden). En este caso, git registra la confirmación como no relacionada con la rama remota. -
merge
la rama, arrastrando todos los cambios y agregando un nuevo compromiso de "conflicto" (si es necesario). -
merge
cada confirmación desde la rama remota individualmente (de nuevo en orden), lo que permite que los conflictos se registren para cada confirmación, en lugar de agruparlos como uno solo. - Para completar, podría hacer un
rebase
(¿igual que la opción decherry-pick
?), Sin embargo, entiendo que esto puede causar confusión para el contribuyente. Tal vez eso elimina la opción 1.
En ambos casos, 2 y 3, git registra el historial de la rama de los compromisos, a diferencia de 1.
¿Cuáles son las ventajas y desventajas entre usar los métodos de cherry-pick
o de merge
descritos? Mi entendimiento es que el método 2 es la norma, pero creo que resolver un compromiso grande con una única combinación de "conflicto" no es la solución más limpia.
En mi opinión, la selección de cerebros debería reservarse para situaciones raras en las que se requiera, por ejemplo, si corrigió algo directamente en la rama ''maestra'' (troncal, rama de desarrollo principal) y luego se dio cuenta de que también debería aplicarse a ''. Debería basar el flujo de trabajo en combinación o en rebase (o "git pull --rebase").
Recuerde que el compromiso seleccionado o rebasado es diferente desde el punto de vista de Git (tiene un identificador SHA-1 diferente) al original, por lo que es diferente del compromiso en el repositorio remoto. (Por lo general, Rebase puede lidiar con esto, ya que verifica la identificación del parche, es decir, los cambios, no una identificación de confirmación).
También en git puedes fusionar muchas ramas a la vez: la llamada fusión de pulpo . Tenga en cuenta que la fusión del pulpo tiene que tener éxito sin conflictos. Sin embargo, podría ser útil.
HTH.
Rebase y Cherry-pick es la única forma de mantener un historial de compromiso limpio. Evite utilizar la combinación y evite crear conflictos de combinación. Si está utilizando gerrit, establezca un proyecto en Combinar si es necesario y un proyecto en modo de selección directa y pruébelo usted mismo.
Tanto rebase
(como cherry-pick
) y merge
tienen sus ventajas y desventajas. Abogo por la merge
aquí, pero vale la pena entender ambos. (Busque aquí una answer alternativa, bien argumentada, en la que se rebase
casos en los que se prefiere una rebase
).
merge
es preferible a cherry-pick
y rebase
por un par de razones.
- Robustez El identificador SHA1 de un compromiso lo identifica no solo en sí mismo sino también en relación con todos los demás compromisos que lo preceden. Esto le ofrece una garantía de que el estado del repositorio en un SHA1 dado es idéntico en todos los clones. No hay (en teoría) ninguna posibilidad de que alguien haya hecho lo que parece ser el mismo cambio, pero en realidad está corrompiendo o secuestrando su repositorio. Puede elegir los cambios individuales y es probable que sean los mismos, pero no tiene ninguna garantía. (Como un problema secundario menor, las nuevas confirmaciones seleccionadas tomarán espacio adicional si otra persona selecciona las mismas asignaciones nuevamente, ya que ambas estarán presentes en el historial incluso si sus copias de trabajo terminan siendo idénticas).
- Facilidad de uso . La gente tiende a entender el flujo de trabajo de
merge
bastante facilidad.rebase
tiende a ser considerado más avanzado. Es mejor entender ambas cosas, pero las personas que no quieren ser expertos en el control de versiones (que según mi experiencia ha incluido a muchos colegas que son muy buenos en lo que hacen, pero que no quieren pasar el tiempo extra) tienen una mayor facilidad el tiempo acaba de fusionarse.
Incluso con una rebase
flujo de trabajo de fusión pesada y cherry-pick
son aún útiles para casos particulares:
- Un inconveniente para
merge
es la historia desordenada.rebase
evita que una larga serie de confirmaciones serebase
en su historial, como lo sería si se fusionara periódicamente con los cambios de otros. Ese es, de hecho, su propósito principal como lo uso. De lo que se debe tener mucho cuidado, es nunca volver arebase
código que ha compartido con otros repositorios. Una vez que se envía un compromiso, alguien más podría haberlo cometido, y la rebasación en el mejor de los casos causará el tipo de duplicación discutida anteriormente. En el peor de los casos, puede terminar con un repositorio muy confuso y errores sutiles que le llevará mucho tiempo descubrirlo. -
cherry-pick
es útil para muestrear un pequeño subconjunto de cambios de una rama de tema que básicamente ha decidido descartar, pero se dio cuenta de que hay un par de elementos útiles.
En cuanto a la preferencia de combinar muchos cambios en uno, es mucho más simple. Puede ser muy tedioso hacer combinaciones de conjuntos de cambios individuales una vez que comience a tener muchos de ellos. La resolución de fusión en git (y en Mercurial, y en Bazaar) es muy muy buena. No se encontrará con problemas importantes que fusionen incluso ramas largas la mayor parte del tiempo. Generalmente fusiono todo a la vez y solo si tengo una gran cantidad de conflictos hago una copia de seguridad y vuelvo a ejecutar la fusión poco a poco. Incluso entonces lo hago en grandes trozos. Como ejemplo muy real, tuve un colega que tenía 3 meses de cambios para fusionar, y obtuvo unos 9000 conflictos en 250000 códigos de línea base. Lo que hicimos para solucionar es fusionar el valor de un mes a la vez: los conflictos no se acumulan de forma lineal, y hacerlo en piezas da como resultado mucho menos que 9000 conflictos. Todavía era mucho trabajo, pero no tanto como tratar de hacerlo un compromiso a la vez.