¿Se debe poner el código temporal bajo control de versiones y cómo?

29

Aquí hay algunos ejemplos de código temporal / local. Es necesario para trabajar con la base de código, pero sería perjudicial formar parte de ella:

  1. Archivos de proyecto Es posible que sea necesario editar las rutas para reflejar el diseño en la PC actual.
  2. Makefiles Por ejemplo, la optimización puede necesitar desactivarse durante la depuración, pero no para el servidor CI.
  3. Hacks feos y sucios. Por ejemplo, return 7en el medio de una función, para probar algo, dependiendo de la función, y se sospecha que se rompe en el valor de 7. O 7 es el código del botón aún no implementado, que estoy implementando y necesito probar en todo momento La vida de mi rama.

He tratado de mantener a los que están en un compromiso de git que siempre rebase a la cima antes de presionar al repositorio y luego presionar HEAD~. Esto es bastante inconveniente y no funciona con svn. El alijo me asusta aún más: "¿Me acordé de hacer estallar después de empujar?".

Mantener el código fuera del control de versiones introduce un ruido desagradable cada vez que se ensambla una confirmación, además de que podría introducirse accidentalmente en una confirmación un viernes por la noche.

¿Cuál sería una solución sensata para tal código desechable?

Vorac
fuente
¿Será necesario actualizar este código temporal del proyecto original durante su período de uso temporal?
JeffO
@JeffO, no estoy seguro si te entiendo. Los fragmentos sucios son pequeños y rara vez chocan con el código en desarrollo. Sin embargo, @ Blrfl, es muy peligroso para ellos comprometerse en la corriente principal. Imagine una return 7en el trunkviernes por la noche, después de un pésimo fusión en el calor del verano.
Vorac
@Vorac: ¡para eso están las revisiones y pruebas de código! Puedo mostrarte mucho peor que eso: código que no funciona a pesar de que se veía bien a primera vista. Return 7.. si tan solo todos fueran tan obvios!
gbjbaanb
@Vorac: Ese fue más un comentario filosófico que otra cosa.
Blrfl
2
¿Hay alguna manera de saber en qué entorno estás? Por ejemplo, puede configurarlo para ejecutar código si detecta que está en el entorno de desarrollo, pero no en val / prod. De esa manera, no tiene que agregar / eliminar constantemente el código de marcador de posición cuando se compromete.
Saggio

Respuestas:

46

Todo el código es temporal. Cuando realice cambios, ocasionalmente introduciré marcadores de posición: ese icono que dibujé esperando el real del diseñador, la función que conozco llamará a la biblioteca que mi colega está escribiendo y aún no ha terminado (o comenzado), el registro adicional que se eliminará o se hará condicional, los errores que solucionaré una vez que el equipo de prueba los haya notado, etc.

Así que verifique todo. Use una rama de características para todo su desarrollo, luego puede fusionar la versión final en el tronco y nadie necesitará saber qué hacks y bodges y correcciones que realizó durante su ciclo de desarrollo, solo necesitarán Ver la versión final. Pero si se ha comprometido con su sucursal regularmente, podrá ver las cosas que valía la pena guardar si un día salía espectacularmente mal, o si continuaba codificando después de un almuerzo en el pub.

El control de versiones no es un repositorio de artefactos o un sistema de almacenamiento de documentos. Se trata de mantener la historia de los cambios. Pegue todo lo que quiera allí porque algún día querrá ver de qué se trata, y esos son los días en que se da cuenta de qué se trata realmente su SCM.

PD. Los archivos verdaderamente temporales (por ejemplo, .obj o artefactos de compilación) no tienen cabida en su SCM. Estas son cosas que no tienen valor para nadie. Puede saber cuáles son: si los elimina, no le importa, o incluso nota que se han ido.

gbjbaanb
fuente
55
Convenido. Ramificar es el camino a seguir. Cree una rama, haga lo que quiera allí y combine el código terminado cuando esté completo. La cabeza debe tratarse como una versión de lanzamiento que el cliente puede descargar y usar en cualquier momento.
Cameron McKay
Gran respuesta, por lo que vi, GIT introdujo el versionado local en parte para ayudar a las personas que desean tener un registro de su trabajo local. El código temporal debe permanecer en las máquinas de desarrollo hasta que esté listo para enviarlos al repositorio
InformadoA
2
Voy a imprimir un gran cartel que dice "TODO EL CÓDIGO ES TEMPORAL" y pegarlo en la pared. Probablemente en Comic Sans.
Bob Tway
2
@MattThrower en una cita de burbujas, ¿viene de los labios de Clippy?
gbjbaanb
1
Sin embargo, el código que no se ejecuta o el código que no se compila no debe comprometerse con el control de versiones.
Tulains Córdova
17

Archivos de proyecto Es posible que sea necesario editar las rutas para reflejar el diseño en la PC actual.

Para los archivos de proyecto, la mejor estrategia es cuando puede generar el archivo de proyecto a través de un script. Agregue el archivo de proyecto real a sus ignorados y simplemente vuelva a generar el archivo de proyecto según sea necesario. Por ejemplo, en proyectos Java, uso gradle que puede generar un proyecto de eclipse.

Makefiles Por ejemplo, la optimización puede necesitar desactivarse durante la depuración, pero no para el servidor CI.

Debería poder cambiar entre la optimización y el modo de depuración sin modificar su Makefile. En su lugar, use un indicador de línea de comando, una variable de entorno o un archivo separado que no esté en su repositorio para controlar eso.

Hacks feos y sucios. Por ejemplo, devuelve 7 en el medio de una función, para probar algo, dependiendo de la función, y se sospecha que se rompe en el valor de 7. O 7 es el código del botón aún no implementado, que estoy implementando y necesito prueba durante toda la vida de mi rama.

¿No puedes escribir una prueba que induzca el supuesto caso de falla?

En la mayoría de los casos, debe poder ajustar su flujo de trabajo para que no realice estos cambios en los archivos de su repositorio. Los archivos que se cambian localmente deben agregarse al mecanismo de ignorar de su proyecto y no estar en el repositorio. En algunos casos, aún hará cambios temporales que no desea incluir en el repositorio. Para esos, agregue una secuencia especial como: XXX, y agregue un enlace de precompromiso que rechace los compromisos que aún lo tienen allí.

Winston Ewert
fuente
A veces necesito hacer pequeños hacks en un archivo, al mismo tiempo que escribo código de producción en el mismo archivo. svnno admite confirmaciones de archivos parciales, por lo que es un problema en esas situaciones. La mayoría de mis colegas simplemente envían los hacks a la sucursal y los purgan en la fusión trunk. Sin embargo, me distraigo (y cometo errores durante las fusiones, y las fusiones en svn son sagradas e inmutables) mucho más fácil y de ahí esta pregunta.
Vorac
@Vorac, buscaría en los ganchos de subversión que le permiten ejecutar scripts cuando se compromete. Debería ser posible escribir un script que rechace una fusión si contiene XXX o algo similar.
Winston Ewert
1
@Vorac: Si usa TortoiseSVN, puede usar Restaurar después de confirmar en un archivo para confirmar parcialmente, use una herramienta diff o su editor para eliminar temporalmente los bloques que no desea confirmar, luego confirme. Tortoise restaurará el archivo completo inmediatamente después y puede confirmar los bloques restantes si está listo. Esto podría hacerse haciendo una copia de seguridad rápida del archivo y restableciéndolo después de la primera confirmación.
leokhorn
5

El control de versiones debe contener el código y la configuración necesarios para compilar la aplicación.

Esto significa que:

  • Las cosas temporales que se introdujeron por un corto período de tiempo (el tiempo requerido para determinar la ubicación de un error, o para experimentar con una característica de un idioma, por ejemplo) no deberían estar en un control de versión: guárdelo hasta que lo necesite luego, simplemente elimínelo cuando haga el commit .

  • Los archivos locales que son propios de una máquina en particular se pueden guardar en una rama.

    Evitaría mantenerlos solo localmente, ya que es demasiado doloroso rehacer todo esto cuando le roban su computadora portátil o un virus lo obliga a reinstalar el sistema operativo (y, por cierto, descubre que su última copia de seguridad se realizó hace dos años) .

    Por otro lado, tenga cuidado con la estructura del archivo: la configuración local está bien, hasta que se vuelva abrumadora y lo obligue a hacer un solo cambio en cada archivo de cada uno de los 42 desarrolladores que participan en el proyecto.

    Esté atento a la oportunidad de eliminar las particularidades entre las máquinas. Puede significar:

    • Otorgando acceso a un servidor SQL de desarrollo para reemplazar instancias locales en máquinas de desarrolladores,

    • Usando servicios de distribución de paquetes como Pypi o npm para paquetes públicos y sus contrapartes privadas para paquetes internos,

    • Solicite a los miembros del equipo que instalen las mismas versiones de software,

    • Hacer actualizaciones de software lo más transparente posible,

    • O haga posible implementar el sistema operativo y el software necesario en una máquina con un solo clic (más el tiempo para que cada desarrollador instale su Vim vs. Emacs preferido, Chrome vs. Firefox, etc.)

Asi que:

Archivos de proyecto Es posible que sea necesario editar las rutas para reflejar el diseño en la PC actual.

¿Por qué no usar el mismo diseño en cada PC? Las rutas dentro del proyecto deben estar relacionadas con el archivo del proyecto, lo que significa que no importa dónde se encuentre el proyecto. Es mejor que las versiones de software y bibliotecas sean las mismas para evitar errores crípticos que solo aparecen en algunas máquinas y que son imposibles de reproducir para otros miembros del equipo.

Ejemplo:

En un proyecto creado con Visual Studio, puede encontrar:

  • Los archivos mismos. Las rutas son relativas, no importa si en mi máquina, el proyecto está ubicado H:\Development\Hello World Project\mientras otros miembros del equipo lo registraron C:\Work\HelloWorld\.

  • Las dependencias, es decir, bibliotecas internas y de terceros. NuGet debe manejar ambos tipos, lo que hace que todas las discusiones relacionadas con conflictos sean obsoletas. Si no tiene la misma versión de la biblioteca que tengo, solicite a NuGet que actualice las dependencias. Tan simple como eso (cuando funciona bien, que no siempre es el caso).

    Tenga en cuenta que también es crucial mantener las bibliotecas internas en un NuGet privado. Tener un montón de bibliotecas almacenadas en una carpeta compartida o enviadas por correo electrónico a través de un equipo conduce a la anarquía y a los servidores depresivos de CI.

  • La configuración. Es crucial que el equipo comparta la misma configuración. Si la mitad del equipo decide tratar las advertencias como errores y la mitad del equipo mantiene las advertencias como están, los miembros de la primera parte del equipo pasarán su tiempo eliminando las advertencias generadas por los desarrolladores de la segunda parte del equipo.

  • La configuración relacionada con las utilidades. Esos son complicados, porque algunos miembros del equipo pueden haber instalado algunas utilidades, mientras que otros no.

    Se recomienda encarecidamente tener instalado el mismo conjunto de herramientas. Si algunos programadores quieren usar StyleCop, pero otros no, el equipo no hará el trabajo. Si algunos usan contratos de Código pero otros no, tendrán los mismos problemas.

Makefiles Por ejemplo, la optimización puede necesitar desactivarse durante la depuración, pero no para el servidor CI.

Mantenga varios makefiles en el control de versiones. No es inusual construir una versión de depuración en el servidor CI también y enviarla a un cliente que experimente un error complicado.

Hacks feos y sucios. Por ejemplo, devuelve 7 en el medio de una función, para probar algo, dependiendo de la función, y se sospecha que se rompe al valor de 7.

Evitaría ese código en primer lugar. Para probar algo, use pruebas unitarias. Si realmente toma unos segundos intercambiar algún código con el fin de depurar , entonces hágalo, pero de todos modos eliminará este código en unos minutos, por lo que no hay necesidad de confirmarlo.

Como lo describe, debe escribir una prueba. Por ejemplo, si quiere estar seguro de que:

class TemperatureConverter
{
    public int CelsiusToFahrenheit(int temperature)
    {
        ...
    }
}

lanza una excepción cuando temperaturees inferior a AbsoluteZeroconstante, no debes jugar con el código en sí. En su lugar, cree una prueba unitaria que:

  • auto-documentar su código,
  • aumentar la confiabilidad de su código,
  • asegúrese de que los encargados del mantenimiento puedan confiar en las pruebas de regresión al modificar el método anterior,
  • Servir a otros desarrolladores de su equipo que puedan necesitar hacer la misma prueba.
Arseni Mourzenko
fuente
2
Lamentablemente no tengo experiencia en escribir exámenes. La plataforma actual involucra una CPU ARM, configurando algún hardware en respuesta a los comandos USB. No hay comentarios del hardware a la CPU.
Vorac
2
Si el código temporal puede tener efectos persistentes, incluso si el código puede no ser necesario una vez que se hayan logrado esos efectos, creo que guardar el código en algún lugar sería prudente en caso de que haya dudas sobre si los efectos se lograron correctamente. Por ejemplo, si se cambia el formato de la base de datos de un producto mientras está en desarrollo, se podría escribir una utilidad rápida única para cambiar el formato. Es posible que la utilidad nunca sea necesaria después de convertir la única base de datos existente en el formato anterior, pero puede ser necesario examinar cómo se realizó la conversión.
supercat
Para los archivos de proyecto de Visual Studio, he tenido buenas experiencias al generarlos con CMake, lo que permite cierta flexibilidad sobre cómo se ubican exactamente el código fuente y el código compilado en el sistema de archivos. Luego controlo la versión de los archivos de entrada CMake en lugar de los archivos de proyecto VS. Pero esto aún se ajusta a su dictamen: "El control de versiones debe contener el código y la configuración que se necesitan para construir la aplicación". ¡Estoy completamente de acuerdo con eso!
David K
Con VS, a veces es necesario tener cuidado para asegurarse de que usted no tiene rutas absolutas a escondidas en Corrí hemos aplicado a más de algunos problemas con referencias roto cuando se actualiza a Win64 y que tienen las bibliotecas para las plataformas de 3 ª parte se mueven de. C:\Program Files\...AC:\Program Files (x86)\...
Dan Neely
@DanNeely: por eso NuGet debe manejar las bibliotecas de terceros.
Arseni Mourzenko
2

Usamos @@comentarios en el código para indicar que algo no está listo, para propósitos de prueba, etc.

De esa manera podemos comprometernos, los colegas no tienen que esperar demasiado para sincronizar, y pueden ver dónde todavía hay trabajo en progreso (por ejemplo, entender por qué una parte aún no funciona por completo).

Hacemos una búsqueda global para @@evitar cualquier 'sobrante' antes de ingresar a las etapas finales de las pruebas beta, etc.

Usando esa disciplina, no veo razón para no solo comprometerme. De esta manera, no tenemos ramas separadas y solo un 'protocolo' adicional a seguir.


Como beneficio adicional, estas tareas pendientes (generalmente cosas pequeñas) siempre están en el código. El desarrollador que trabaja en ellos puede revisarlos rápidamente, y no es necesario mantener listas separadas.
Ya sabes cómo va el desarrollo: estás trabajando en un lugar pero constantemente estás usando tu mente como una pila (' Debería cambiar eso allí cuando termine aquí '). Simplemente anotar un @@comentario rápido evita el desbordamiento de la pila.

Incluso uso @@namepara indicar cuestiones que necesito discutir con 'nombre'.

Jan Doggen
fuente
1

2 soluciones HAMSTER:

  • Puede usar un enlace previo a la confirmación para verificar su código para alguna palabra clave inusual como HAMSTER. Simplemente no permita que las personas cometan código que ha sido HAMSTER y lo usen cada vez que realice hacks sucios.

  • Otra opción, por ejemplo, en C es usar #ifdef HAMSTER, entonces el código solo se ejecutará en su máquina donde tenga un indicador de compilación HAMSTER.

usuario143985
fuente
0

Ponemos todo bajo control de origen necesario para compilar y probar los binarios actuales y entender por qué las cosas fueron diseñadas / implementadas / probadas de la manera en que son.

Eso incluso es válido para los picos http://www.extremeprogramming.org/rules/spike.html , como los que usted describió; simplemente los alojamos en un subárbol diferente.

Solkar
fuente
0

Aquí hay una serie de soluciones que ocasionalmente uso en varias circunstancias, y que puede considerar útiles cuando se aplica a sus propios flujos de trabajo:

  1. Ramas ligeras que pueden aplastarse.

    Git es genial en esto. Hackea una sucursal, realiza muchas confirmaciones y luego vuelve a crear o aplasta tu historial para editar el ruido.

  2. Use una cola de parches en la parte superior de su SCM.

    A menudo me encuentro usando StGit para flotar parches en la parte superior de mi rama actual. Cuando termine con la rama, puedo volver a sacarlos de la pila antes de fusionarlos, aplastarlos o volver a crearlos, o puedo fusionarlos en la base de código principal si quiero mantenerlos cerca.

  3. Use RCS como un SCM "fuera de banda" para pequeños experimentos.

    A veces, solo desea marcar un archivo en progreso de forma desechable, sin tener que limpiar el historial después. Normalmente uso RCS para esto dentro de Git o SVN. Le digo a Git que ignore los artefactos RCS, controle mi trabajo en progreso en RCS y, cuando me gustan los resultados, simplemente lanzo el*,v archivos o todo el directorio RCS. Simplemente no corras git clean -fdxo similar hasta que hayas comprometido tu trabajo con tu SCM "real", o te arrepentirás.

  4. Aliños con nombre.

    Otro Git-ismo, pero útil: git stash save --include-untracked <some-cool-title>puede ser útil en caso de apuro. Puede guardar, reventar y aplicar el trabajo en progreso de esta manera, y ver sus diversos puntos de control a través de git stash listo git reflog --all. Otros SCM pueden tener características similares, pero su kilometraje puede variar mucho con este.

CodeGnome
fuente
0

Parte de ese código temporal es realmente una manifestación de una metodología inadecuada de construcción / prueba / desarrollo, y esperamos que su existencia motive mejoras futuras.

Al menos en git, debe ser libre de jugar con cualquier cantidad de ramas de características hasta que estén listas para fusionarse en master / trunk.

Se supone que el control de versiones te ayudará , y la mayoría de las veces agradezco las ideas de la forma en que se cometieron los errores (o tal vez solo las decisiones menos intuitivas) en el pasado, y tomo decisiones más informadas para el presente.

Prusswan
fuente
0

Creo que algunos sistemas arrojarán advertencias al ver TODO en un comentario, así que

// TODO: remove this hack.

podría ser todo lo que sea necesario si puede encontrar una opción relevante en alguna parte de su entorno de desarrollo, o simplemente pegar algún tipo de comando grep en su archivo de compilación. También podría ser posible organizar // HACKo recoger cualquier cadena arbitraria.

Esto es más simple que organizar su código de una manera particular y esperar que la gente recuerde no usarlo. También hace que sea más seguro seguir los consejos de @gbjbaanb (¡si puede asegurarse de que todos estén viendo las advertencias!).

Pegue todo lo que quiera allí porque algún día querrá ver de qué se trata, y esos son los días en que se da cuenta de qué se trata realmente su SCM.

GKFX
fuente
0

Nunca es dañino poner código en el control de código fuente.

Todos y cada uno de los elementos que menciona deben estar en control de fuente.

Toby Allen
fuente