¿Alguna vez está bien cometer código que no funciona?

40

¿Es una buena idea exigir que se confirme solo el código de trabajo?

Este commit no necesita dejar el repositorio en un estado de trabajo como:

  • ... estamos en las primeras etapas de diseño, el código aún no es estable.
  • ... usted es el único desarrollador del proyecto. Ya sabes por qué las cosas no funcionan. Además, no está deteniendo el trabajo de nadie al cometer un código roto.
  • ... el código actualmente no funciona. Vamos a hacer un gran cambio. Vamos a comprometernos, para tener un punto al que volver si las cosas se ponen feas.
  • ... la cadena es larga, no hay problema si existe un código roto en la rama local. Es decir

    1. archivos locales
    2. área de ensayo
    3. se compromete en la sucursal local
    4. se compromete en la rama de características personales remotas
    5. fusionar con developrama remota
    6. fusionar con masterrama remota
    7. fusionar con releaserama remota
  • ... comprometerse temprano, comprometerse a menudo.

Entonces, en la pregunta vinculada anteriormente, la mayoría de las respuestas dicen que cometer código no compilable no es un problema en las ramas locales y de características. ¿Por qué? ¿Cuál es el valor de un commit roto?


Agregado: hay un par de comentarios muy votados que dicen que en un grupo local se puede hacer lo que se quiera. Sin embargo, no estoy interesado en el aspecto técnico de la pregunta. Más bien, me gustaría aprender las mejores prácticas: los hábitos que las personas que han trabajado durante muchos años en la industria son los más productivos.


¡Estoy sorprendido por la gran cantidad de excelentes respuestas! Me llevan a la conclusión de que no soy lo suficientemente hábil para usar ramas para organizar mi código.

Vorac
fuente
28
En las sucursales locales todo vale. Comete lo que quieras. Simplemente limpie antes de empujar.
Joachim Sauer
@Joachim Sauer, estoy preguntando sobre las mejores prácticas y el razonamiento detrás de ellas, para desarrollar buenos hábitos . Actualmente a menudo cometo código roto. Y revertir es una pesadilla, a través de las decenas de compromisos de los últimos días.
Vorac
9
si desarrolla cada característica en su propia rama, entonces esa decisión es trivial: descarte la rama, continúe desde una nueva rama creada en el maestro actual
Joachim Sauer
1
a menos que defina qué hace que commit "se rompa", es imposible responder con autoridad a esta pregunta. Ver también: ¿Debería un programador corregir la compilación fallida de otra persona?
mosquito
1
"¿Por qué? ¿Cuál es el valor de un commit roto?" La capacidad de haber identificado un problema y probar varias resoluciones diferentes además de poder volver de manera confiable al problema que sabía que tenía, en lugar de un estado en el que lo tiene y quizás algunos nuevos también .
Joshua Taylor

Respuestas:

20

Una de las filosofías de ramificación (sección Desarrollo de la estrategia de ramificación y la política de línea de código en las estrategias de ramificación avanzadas de SCM , también lea las mejores prácticas de Perforce , es un pdf pero entra en algunos otros detalles) es que se ramifica en una política incompatible.

Una política de línea de código especifica el uso justo y los registros permitidos para la línea de código, y es el manual esencial del usuario para la línea de código SCM. Por ejemplo, la política de una línea de código de desarrollo debería indicar que no es para publicación; Del mismo modo, la política de una línea de código de lanzamiento debería limitar los cambios a las correcciones de errores aprobadas. La política también puede describir cómo documentar los cambios que se registran, qué revisión se necesita, qué pruebas se requieren y las expectativas de estabilidad de la línea de código después de los registros. Una política es un componente crítico para un proceso de desarrollo de software documentado y exigible, y una línea de código sin una política, desde el punto de vista de SCM, está fuera de control.

(de Perforce Best Practices)

Supongamos que tiene las 'versión' (o 'maestra') de las ramas a partir de las cuales se construye una versión y 'troncal' (o 'dev') donde los desarrolladores registran el código de trabajo. Estas son las políticas de las sucursales. Teniendo en cuenta que el "código de trabajo" es parte de la política de la rama "dev", nunca se debe confirmar el código roto en la rama dev. A menudo hay cosas como los servidores de CI conectados a estas ramas y el registro de código roto en el desarrollo podría estropear la rama de todos y romper la compilación.

Sin embargo, hay momentos en que es apropiado registrar un código parcial que no funciona. En estos casos, se debe bifurcar, una política incompatible con troncal. En esta nueva rama, uno puede decidir la política ('el código roto está bien') y luego confirmar el código.

Hay una regla simple para determinar si una línea de código debe ser ramificada: debe ser ramificada cuando sus usuarios necesitan diferentes políticas de registro. Por ejemplo, un grupo de lanzamiento de productos puede necesitar una política de registro que aplique pruebas rigurosas, mientras que un equipo de desarrollo puede necesitar una política que permita registros frecuentes de cambios parcialmente probados. Esta divergencia de políticas requiere una rama de línea de código. Cuando un grupo de desarrollo no desea ver a otro

(de Perforce Best Practices)

Tenga en cuenta que esto proviene de un SCM basado en un servidor central con una fuerte mentalidad corporativa. La idea central sigue siendo buena. A menudo se piensa implícitamente en esto: no se registra el código de desarrollo no probado en la rama de lanzamiento. Eso es una política.

Entonces rama, digamos que esta rama puede tener código roto y comprometerse.


fuente
40

Una de las filosofías sugeridas por Linus Torvalds es que la programación creativa debería ser como una serie de experimentos. Tienes una idea y síguela. No siempre funciona, pero al menos lo intentaste. Desea alentar a los desarrolladores a probar ideas creativas y, para hacerlo, debe ser barato probar ese experimento y recuperarlo. Este es el verdadero poder de git commits por ser tan barato (rápido y fácil). Abre este paradigma creativo que permite a los desarrolladores probar cosas que de otro modo no tendrían. Esta es la liberación de git.

WarrenT
fuente
2
De hecho es una cosa hermosa. No creo que la comunidad haya aprendido realmente a apreciar git y DVCS en general.
ChaosPandion
55
Mientras la gente no confunda esta filosofía con la programación de prueba y error, lo que debe evitarse.
Pieter B
10

Sí, siempre que no sea una rama de lanzamiento.

En las ramas personales, todo funciona y luego puede descartarse si el experimento no funcionó. Ese es uno de los principales beneficios de DVCS: libertad

¿El valor de cometer código roto ?: colaboración y experimentación

dukeofgaming
fuente
Ajuste menor: Sí, siempre que no se ejecute en producción. Código que está oculto por una función alternar, por ejemplo.
Rob Crawford el
5

Sí, está bien y es algo que hago mucho.

El punto de comprometer el código no compilable (al menos en las ramas) es que a veces su código es un trabajo en progreso, pero que el trabajo realizado hasta ahora vale la pena guardarlo y / o compartirlo con otros.

Mis practicas son:

  • escribir pruebas primero
  • los compromisos de wip (trabajo en progreso) son buenos
  • comprometerse a menudo (múltiples dentro de un día) y temprano (guardar pasos de 'trabajo')
  • presione después de cada confirmación (en caso de que su disco duro se bloquee / el bus lo golpee).
  • siempre trabaje en sucursales primero
  • cuando sea posible, solo combine en el código de trabajo para dominar
  • rebase interactivo en git para aplastar wips antes de master merge

El problema principal y quizás el que está abordando es cuando tiene una función que básicamente funciona y que la empresa necesita con urgencia (y, por lo tanto, debe estar en 'maestro') pero tiene algunas pruebas fallidas. Una opción aquí puede ser hacer una prueba pendiente que le permita avanzar por ahora. Sin embargo, esto está plagado de peligros, ya que la prueba puede que nunca se repare y puede establecer un patrón en otras áreas de pruebas rotas simplemente 'pendientes' en lugar de repararlas.

Otra opción sería usar e implementar temporalmente la sucursal. Esto puede ayudar en ciertas situaciones, pero generalmente no se recomienda y no es sostenible.

Quizás la mejor opción es básicamente adoptar un enfoque más profesional para el desarrollo de software y realmente requerir pruebas de trabajo para cualquier código comprometido. Esta es con frecuencia la parte "difícil" del desarrollo de software, no la codificación que mucha gente imagina. Un mejor enfoque probablemente requerirá mejores estimaciones iniciales, asignación de recursos, establecimiento de prioridades, etc., además, durante el desarrollo ágil, permitiendo suficiente tiempo y utilizando suficiente disciplina para solucionar cualquier problema, tanto en el momento en que ocurren como durante las sesiones de preparación.

Concéntrese en lo que significa "hecho": significa que el código Y las pruebas están escritas, han sido refactorizadas y funcionan. Si escuchas comentarios como "en su mayoría hechos, solo necesitas escribir / corregir / refactorizar las pruebas, entonces NO se hace. Decir que una característica se hace sin que esté técnicamente completa es uno de los errores más comunes de los programadores junior.

Michael Durrant
fuente
3

El valor de cualquier confirmación, rota o no, es que el código se confirma en un servidor. En entornos profesionales, ese servidor es seguro, redundante y ejecuta copias de seguridad. Si trabajo todo el día, comprometerme es una forma de asegurarme de que mi código sobreviva pase lo que pase con mi máquina local. Los discos duros mueren. Las computadoras portátiles se pierden o son robadas. Las copias de seguridad del servidor del repositorio estarán disponibles incluso si el edificio se incendia.

nvoigt
fuente
8
Esto no es necesariamente cierto para DVCSes. Por ejemplo, si su repositorio personal local o rama de características es local, puede tener una copia de seguridad o no (y esto es especialmente cierto si está trabajando sin conexión desde la red corporativa sin acceso a los recursos de la compañía). Las ramas maestra y de lanzamiento deben estar en algún lugar que esté respaldado, pero eso no es necesariamente cierto para una rama local.
Thomas Owens
Incluso en DVCSes un commit vale algo, ya que el código que contiene es "más permanente" que el de los archivos. Al menos para git.
Joachim Sauer
3
@ThomasOwens, con el debido respeto, si su administrador de DVCS configuró su sistema para que no se respalden los repositorios o sucursales locales, su administrador de DVCS es un idiota y necesita encontrar un nuevo trabajo más adecuado a sus talentos ("¿Le gustaría papas fritas con eso? "). Si su administrador de DVCS lo hizo de esa manera porque sus muchachos de TI se lo dijeron, eso también se aplica a su organización de TI. En todo caso, esto podría decirse que es una acusación de todo el concepto DVCS: comprometer el código a VCS debería, POR DEFINICIÓN, significa comprometerlo a una copia de seguridad automática.
John R. Strohm
66
@ JohnR.Strohm Cuando viajo, a menudo tengo acceso limitado a la red, por lo que no tengo acceso a ninguno de los recursos de respaldo o unidades de red. Estoy desarrollando sin respaldo hasta que tenga acceso a una red. Este es el punto de un DVCS: no necesita la red. ¿Debería respaldar su repositorio? Probablemente, pero es solo un requisito para el lanzamiento o repositorios maestros. Realmente no deberías pasar días entre presionar a un repositorio respaldado de todos modos, pero esos empujes no deberían ser código roto.
Thomas Owens
1
@ThomasOwens, mi punto es que, aunque su acceso a dicho servidor de respaldo es esporádico, comprometerse con él debería ser una prioridad sobre hacer que su código funcione. Siempre puede hacer que su código funcione en otra máquina, incluso otras personas de su equipo podrían hacer que el código funcione en sus máquinas. Si solo se encuentra en su máquina, lo más probable es que al cliente no le importe si funciona. El cliente se preocupa por una nueva versión del servidor de compilación que a su vez se basa en el repositorio del servidor.
nvoigt
3

Piensa en ello de esta manera. Como desarrollador, una de las cosas más disruptivas que debe hacer es evitar que otros desarrolladores de su equipo trabajen en sus tareas.

La filosofía de solo comprometer el código de trabajo proviene de los equipos de desarrollo que trabajan en el mismo tronco único en el repositorio. Puede parecer una locura ahora, pero hace 10 años, esta era la forma normal de trabajar. Aparecería una rama cuando quisiera crear una versión estable, pero la idea de un desarrollador trabajando en una rama para implementar una nueva característica era casi desconocida.

Si su entorno significa que sus confirmaciones no afectan inmediatamente a otros desarrolladores, entonces confirme con frecuencia. le brinda más seguridad en su código, lo que hace que sea más fácil revertir un error de código y muchos sistemas de control de fuente le brindan cierta protección de código al código comprometido (aunque no todos).

Ahora, asegurarse de que sus fusiones con sucursales compartidas con otros desarrolladores funcionen, y que cualquier código que promueva a este nivel compile, pase todas las pruebas unitarias y otras comprobaciones de sanidad basadas en equipos ... eso es algo esencial si no desea sigue comprando la cerveza en el pub ...

Michael Shaw
fuente
3

Antes de comenzar a ser dogmático sobre cómo trabajar con su control de versiones, vale la pena pensar por qué está trabajando con el control de versiones.

Comprometerse con el control de versiones congela el estado de su código para referencia futura; todo lo demás queda fuera de esto. Mirar los diferenciales y hacer parches es solo ver cómo el código cambió entre las instantáneas. Las ramas y las etiquetas son solo formas de organizar instantáneas. Compartir código con otros desarrolladores solo les permite ver una instantánea en particular.

¿Cuándo deberías comprometerte? Cuando haya una posibilidad razonable de que vea el estado de su código (o el mensaje de confirmación que explica un cambio) en el futuro.

Git te ofrece mucha flexibilidad en cuanto a cómo organizar tus instantáneas. No hay un repositorio central, por lo que puede compartir su código con otros desarrolladores sin llevar su estado al repositorio 'principal'. Puede crear, fusionar y eliminar ramas fácilmente para aislar los detalles de un conjunto de estados de la narrativa del código principal. Puede comprometerse localmente, para ayudarlo a deshacer y seguir su desarrollo actual, y luego agrupar todo en un solo compromiso antes de enviarlo para que otros lo vean. Puede etiquetar revisiones específicas para que sean fáciles de encontrar más tarde.

BESO . Lo que funciona mejor para un único desarrollador en las primeras etapas de desarrollo de un pequeño proyecto será completamente diferente de lo que necesita hacer cuando tiene cien desarrolladores trabajando en un sistema de misión crítica de una década de antigüedad. En cualquier proceso de desarrollo de software, debe evitar crear artefactos innecesarios simplemente porque alguien más le dijo que lo hiciera.

Sean McSomething
fuente
Su respuesta es inspiradora, pero vaga para mí. Mi problema es que creo (creo) demasiados commits, y cuando necesito revertir, no sé a dónde, ya que muchos de ellos no funcionan. El contexto es el desarrollo individual del pequeño equipo de <5. Creo que estoy llevando la cosa de "comprometerme con frecuencia" demasiado lejos y es posible que necesite recuperarme. ¿Cómo hago commits, que tendrá un mensaje de commit significativo?
Vorac
1
Si encuentra que tiene que comprometerse cada vez que compila / prueba, tal vez necesite encontrar un mejor editor que le brinde más historial de deshacer. Si no puede escribir un mensaje de confirmación que exprese sus cambios de manera significativa, no lo haga.
Sean McSomething
Si tiene problemas para recordar a qué compromiso volver, no está fusionando sus cambios con la frecuencia suficiente. Mantenga una rama "estable", una rama de "desarrollo" y una rama "experimental". Cuando el código esté funcionando, combine los cambios de "experimental" a "dev" (elimine primero sus confirmaciones), luego siéntase libre de romper "experimental" sabiendo que puede eliminarlo y crear una nueva rama de "dev". Una vez que se completa una función completa, combine dev en estable.
RubberDuck
2

Construir / liberar ramas

Nunca debe cometer deliberadamente código roto en una rama de compilación. Cualquier rama que esté bajo integración continua o desde la cual se realizan lanzamientos o compilaciones diarias siempre debe estar en un estado potencialmente liberable.

Otras ramas: Guardar estado a menudo

Para sucursales privadas o de entidades, los objetivos son a menudo diferentes. El check-in frecuente de código (ya sea que funcione o no) puede ser deseable. En general, querrá comprometerse en cualquier momento que necesite rebobinar al estado actual.

Considere estos ejemplos donde el estado guardado proporciona un beneficio significativo:

  • Puede realizar una confirmación justo antes de ejecutar una búsqueda y reemplazo global para que pueda revertir su árbol en una sola operación si las cosas salen mal.
  • Puede realizar una serie de confirmaciones provisionales mientras refactoriza una pieza compleja de código para que pueda dividir o rebobinar si termina rompiendo algo en el proceso.
  • Puede realizar una confirmación, iniciar una nueva rama o crear una etiqueta cuando desee probar algo experimental mientras puede volver al estado del árbol de trabajo actual en cualquier momento.
CodeGnome
fuente
0

Confirmar un código base roto está bien siempre que sea local.

¿Por qué?

  • Es esencial utilizar el compromiso como un punto de guardado en su desarrollo.
  • Le muestra un patrón de pensamiento utilizado durante el desarrollo del producto.
  • No rompe la colaboración .

Sin embargo, cuando hay un equipo de programadores, la filosofía de la casa de programación es primordial y reemplaza los comportamientos de compromiso individuales. Algunas casas de programación deciden registrar todo el progreso, mientras que otras deciden comprometer solo el código que resuelve una característica. En este caso, el valor ( costo , desde el punto de vista de la administración del software) de un commit roto es grave:

  1. el tiempo utilizado para otras funciones ahora se dedica a corregir errores ...
  2. el corte de desarrollo no se cumple ...
  3. el producto no se envía a tiempo

Se pueden agregar otros puntos a estos tres que conectan sus efectos exponencialmente en un colapso de la compañía ... por supuesto, esto tiene que ser un efecto de la comisión habitual crónica de código incorrecto.

iGbanam
fuente
0

No creo que esté bien cometer código roto.

Qué pasa si

  • Se requiere una reparación urgente. La base del código está en un estado roto. Estás obligado a retroceder, arreglar y desplegar.

  • Alguien más comienza a trabajar en la misma rama sin saber que ha cometido un código roto. Podrían estar persiguiendo un 'arenque rojo' pensando que sus cambios han roto algo.

  • Decide dejar la empresa, irse de vacaciones o no puede venir a trabajar por ningún motivo. Sus colegas tendrán que cavar profundamente para encontrar lo que está roto y por qué se ha cometido en un estado roto.

  • ¿Alguien implementa su 'código roto'? Esto puede ser un "juego terminado" si está trabajando con datos personales o en un proveedor de pagos.

Responder a @WarrenT

Estoy de acuerdo con usted en que en un mundo ideal en el que todos trabajan en una rama de características, la confirmación de código que no funciona podría funcionar. He trabajado en proyectos grandes e incluso entonces hubo casos en los que varias personas tuvieron que trabajar en una sola rama de características. También he visto personas que envían el código 'no funciona' a la sucursal principal porque faltaban semanas para el lanzamiento y planeaban arreglarlo al día siguiente. Todas estas cosas son candidatas para un desastre y creo firmemente que deben evitarse a toda costa.

CodeART
fuente
Voto a favor. Ninguno de estos escenarios es probable si está utilizando un flujo de trabajo DVCS estándar.
user16764
1
Con el flujo de trabajo de git (u otro DVCS), los desarrolladores están trabajando en sucursales, sucursales locales, NO en la troncal principal. La siguiente pregunta sería si un desarrollador empuja el código roto a otro repositorio. Se trata de un equipo que comprende qué ramas son para qué y de utilizar buenos comentarios en sus compromisos. Solo se realizaría una corrección en una rama de lanzamiento. Por supuesto, nadie debería fusionar código roto allí. Los equipos necesitan tener reglas sobre el flujo de trabajo, pero lo que se hace en un repositorio local es un asunto completamente diferente.
WarrenT
Creo que hay una diferencia entre el "código que no funciona" (lo que solicitó el OP) y el "código roto" al que se refiere.
Simon
@WarrenT Por favor, vea la respuesta.
CodeART
-1

Algunas preguntas para ayudarlo a determinar si está bien confirmar código que no funciona:

  1. ¿Estás siendo sobrecargado de trabajo?
  2. ¿Tus compañeros de equipo rompen constantemente la construcción?
  3. ¿Su código base es un desastre y aparentemente no puede empeorar?

Si dice que sí a cualquiera de los anteriores, sí, está bien confirmar código que no funciona.

Solo recuerde arreglarlo lo antes posible, cubrirlo con cualquier prueba de unidad aplicable y disculparse por romper la construcción.

Rudolf Olah
fuente