¿Está mal dar ramas de fuerza de empuje?

11

Cuando estoy trabajando en una rama de características, tiendo a querer limpiar los commits en la rama usando un rebase interactivo antes de que mi trabajo sea revisado e integrado en la rama principal.

Durante el desarrollo de la función, quiero llevar mi trabajo intermedio al repositorio remoto como una medida de respaldo. Es decir, cuando mi disco duro falla, no quiero que se pierda toda la rama de funciones.

Sin embargo, esto lleva al hecho de que a menudo tengo que hacerle una consulta git push --forceal repositorio remoto después de un rebase, una acción que generalmente está mal vista. O como dice la página de github vinculada:

Debido a que cambiar su historial de confirmación puede dificultar las cosas para todos los que usan el repositorio, se considera una mala práctica cambiar las confirmaciones cuando ya se ha presionado a un repositorio.

¿Existe una política (generalmente aceptada) que resuelva este conflicto?

¿Por qué esto no es un duplicado de Es tan esencial la git "Regla de Oro de Rebasar"?

Mi pregunta aquí pide una política para resolver el conflicto entre querer hacer una copia de seguridad de su trabajo en el repositorio remoto y cambiar su trabajo , mientras que la otra pregunta trata de negar que haya un conflicto y pregunta por qué algunas personas piensan que el conflicto existe. y por lo tanto pregunta por qué "es esencial" no impulsar rebases de fuerza?

Chiel ten Brinke
fuente
1
@gbjbaanb si realiza confirmaciones WIP, una nueva modificación es muy útil para evitar tener muchas confirmaciones para un solo día de trabajo. A menudo hago confirmaciones para pequeños cambios solo para tener una opción de "deshacer a un estado que recuerdo" si es necesario; la mayoría de estos son irrelevantes / molestos para la historia principal del repositorio (por lo que rebase es tan útil).
enderland
1
@gbjbaanb Creo que es una cuestión de opinión. Muchos equipos utilizan una estrategia de rebase para mantener limpia su historia.
Chiel ten Brinke
1
@enderland todo el mundo quiere una historia bonita, sigue siendo algo incorrecto (y peligroso) como se muestra en el enlace. Torvalds nunca debería haberlo puesto, debería haber permitido que las confirmaciones se "comprimieran" en la pantalla.
gbjbaanb
1
@gbjbaanb pero ... no lo hizo, así que tenemos que trabajar con lo que tenemos. Para mí, es mucho más útil tener una única confirmación en la rama maestra en lugar de más de 30 confirmaciones individuales e incrementales de cada rama de características. Pero todo el mundo tendrá un flujo de trabajo diferente, supongo ...
enderland

Respuestas:

5

La pregunta clave que debe hacerse:

  • ¿Mantiene su rama remota después de volver a fusionarse con el maestro?

Si elimina su rama de funciones remotas después de fusionarse con master, ya está perdiendo el historial. Suponiendo que aplaste / rebase la rama antes de hacer su fusión / PR, perderá este historial. Todo lo que está haciendo su fuerza en este caso es permitirle usar github como respaldo.

La situación en la que desea mantener el historial y no forzar el empuje es si su rama remota persiste después de fusionarse y no solo existe por un período de tiempo temporal.

¿Supongo que me preguntas si me quedaría con la rama sin base? No, AFAIC. Aún así, forzarlo podría, en teoría, provocar la pérdida de confirmaciones de otros usuarios que empujaron a la misma rama

Parece que tienes varias personas empujando a esa rama simultáneamente. Esto significa que te importa el historial de la sucursal.

Lo que podría hacer en su lugar para su trabajo intermedio es crear una bifurcación de esa rama. Puede presionar para esto y luego volver a basar todas sus confirmaciones en una sola confirmación antes de fusionarlas, por lo que cuando las combina en su rama característica, solo tiene 1 confirmación (con el historial modificado de toda su rama).

Enderland
fuente
"¿Mantiene su rama remota después de volver a fusionarse con el maestro?" ¿Supongo que me preguntas si me quedaría con la rama sin base? No, AFAIC. Aún así, forzarlo podría resultar en la pérdida de confirmaciones de otros usuarios que presionaron a la misma rama.
Chiel ten Brinke
@ChieltenBrinke Edité un poco sobre eso. FYI
enderland
Creo que la bifurcación como medida para evitar la destrucción de los compromisos cuando se fuerza el empuje es realmente una muy buena sugerencia. Pero AFAIK no es realmente un concepto git, y necesita un envoltorio de servicio para hacerlo fácilmente (como github). ¿Estoy en lo cierto al respecto? ¿O tal vez confundo su uso del término "bifurcación" por solo crear una rama separada?
Chiel ten Brinke
@ChieltenBrinke bien, puedes lograr lo mismo de varias maneras. Si su rama de características está en el repositorio remoto, puede bifurcar el repositorio y tener su versión de esa rama. Y luego combine esa rama en su rama remota después de aplastar las confirmaciones. O simplemente puede crear una rama local diferente (tal vez featurebranch-local) y luego hacer un desarrollo activo en esa rama, con tantos commits como desee. Una vez que desee fusionar, aplastar esas confirmaciones y luego fusionarlas en la función. Básicamente solo haciendo dev en una rama temporal real y luego aplastando / fusionando en su función.
enderland
Asumiendo que bifurcar un repositorio está fuera de opción porque uno no usa github, trabajaríamos con una develop-featurerama "privada" . Por supuesto, la privacidad es puramente por convención y no se aplica por nada, pero puede hacerse parte de una política, especialmente si se introducen ciertas convenciones de denominación de sucursales. (Tal vez estoy demasiado ansioso en este momento, tal vez no :) La combinación con --force-with-leaseno puede doler, aunque no se debe confiar, como se señaló en mi otra publicación.
Chiel ten Brinke
3

Aquí enumero algunas posibilidades que se me pasan por la cabeza.

Rebasar siempre en una nueva sucursal

Cuando tenga una rama desordenada some-feature, vuelva a crear una nueva rama. P.ej

$ git checkout -b some-feature-rebase
$ git rebase -i master # etc..

Luego han some-feature-rebaserevisado e integrado.

Problema: un gran inconveniente aquí es que, estrictamente hablando, necesita una nueva rama para cada rebase. (Podría tener múltiples rebases si realiza cambios después de una revisión de código, por ejemplo)

Utilizar git push --force-with-lease

Acabo de enterarme de la git push --force-with-leasealternativa agit push --force , que

se niega a actualizar una rama a menos que sea el estado que esperamos; es decir, nadie ha actualizado la rama aguas arriba.

Problema : Esto parece mejorar directamente en la situación en la que usamos solo --force, pero todavía tiene algunas advertencias, sobre todo cuando hago un en git fetchlugar de un git pull, que actualiza nuestras ramas locales aguas arriba, engañando --force-with-leasepara pensar que no se realizaron cambios no fusionados en el control remoto rama.

Chiel ten Brinke
fuente