2010-03-10 7 views
7

Tengo el siguiente problema que otras personas deben haber encontrado. Estoy trabajando en una base de código que se ejecuta en dos plataformas diferentes. La mayoría del código se comparte entre las plataformas, pero algunas partes del código están optimizadas para una plataforma en particular. Por lo tanto, puede haber una implementación genérica de la función foo() en el archivo foo.cpp y una implementación optimizada para la plataforma A en el archivo foo_A.cpp.¿Hay alguna manera de "enredar" dos archivos en Subversion?

Por supuesto, lo que sucede a veces es que un desarrollador modifica foo.cpp y olvida hacer un cambio correspondiente a foo_A.cpp para mantenerlos sincronizados. Esto lleva a errores muy desagradables, que son difíciles de rastrear.

Finalmente, aquí está mi pregunta: ¿hay alguna forma de "enredar" dos o más archivos en Subversion? ¿Es posible que cada vez que se comete un cambio en foo.cpp, svn emita una advertencia, un recordatorio para actualizar foo_A.cpp?

+3

¿Cuál es el motivo por el que las funciones se encuentran en archivos separados? Los tendría en un solo archivo con #ifdef para incluir una función sobre la otra. No resuelve directamente el problema, pero acerca mucho las funciones. – Robert

+1

Esto no es algo que realmente debería ser manejado por un VCS. En cambio, es su proceso de edición lo que de alguna manera debe mantener sincronizados los dos archivos. –

+1

@Neil, ¿cómo? Básicamente, debe recordar que cada vez que modifique foo.cpp, es posible que necesite modificar foo_A.cpp. Y si tiene 500 archivos, 20 de los cuales tienen una contraparte optimizada, las posibilidades de olvidar esto son muy altas. Agregue a eso el hecho de que la versión optimizada es probable que haya sido escrita por otra persona. Usar el VCS para verificar y darle una advertencia si se modifica uno de esos 20 archivos parece razonable. – Dima

Respuesta

7

Puede escribir un pre-commit hook que verifica para asegurarse de que foo.cpp y foo_A.cpp están presentes cuando se confirma uno de ellos.

Podría simplemente presentar un mensaje de advertencia y continuar, o realmente fallar la confirmación devolviendo un error, su elección.

3

Subversion tiene ganchos que puede usar. Básicamente, escribes un script en la carpeta correcta y con el nombre correcto. Puede verificar si un archivo específicamente nombrado está registrado, y luego hacer un montón de cosas en respuesta. (En otras palabras, puede automatizar la actualización de un archivo cada vez que se ingrese otro archivo.)

Esto generalmente es una mala idea. Reestructurar sus proyectos para que todos compartan el mismo archivo suele ser una mejor solución.

+0

No quiero que svn actualice automáticamente el otro archivo. Eso sería una mala idea. Idealmente, quiero que me dé un cuadro de diálogo/mensaje que diga "Has modificado foo.cpp, pero no foo_A.cpp. ¿Estás seguro de que está bien? Deberías comprobarlo, porque ahora foo.cpp y foo_A.cpp puede estar haciendo cosas diferentes ". Y quiero que aborte commit, si no digo que está bien. Pegar código para diferentes plataformas en el mismo archivo es una mala idea, en mi humilde opinión. Es mejor tener un código específico de plataforma en archivos separados y tratar con ellos en el nivel de configuración de compilación. – Dima

0

Es posible que también desee realizar pruebas unitarias contra ese archivo, ejecute en ambas plataformas mediante integración continua; luego, podrían detectarse cambios que solo rompan una plataforma. Al menos se verificará que ambas implementaciones expongan la misma interfaz durante la compilación.

+0

No es realmente una cuestión de romper la interfaz. Puedo modificar el algoritmo de alguna manera en la implementación genérica, manteniendo la interfaz exactamente igual, y luego olvidar actualizar la versión optimizada. De hecho, esto es exactamente lo que sucedió. :( – Dima

1

Como está utilizando un lenguaje compilado, ¿ha considerado escribir #ifdef (buscando indicadores que definan la plataforma) en las funciones para las optimizaciones en lugar de simplemente escribir una función completamente nueva?

+1

por cierto, sé que esto no responde a su pregunta sobre svn. Lo decía por buenas prácticas. No conozco su situación, por lo que esta puede no ser una solución mejor, pero solo quería ver si lo había considerado – Seaux

+0

#ifdefs a menudo son mal vistos en el mundo de C++. Es mejor resolver estos problemas en la configuración de compilación que en el nivel de preprocesador. Comprueba "Effective C++" de Scott Meyers. Además, incluso con ifdefs, sigue siendo muy es fácil olvidarse de actualizar la otra versión del código. – Dima

+1

Gotcha, vengo de un mundo de C sobre todo basado en Linux y no tengo mucha experiencia (además de educativamente) con C++. Solo quería dejar pasar la idea y ver si ayudó. ¡Gracias por la información! – Seaux

2

Puede rechazar pre-commit hook para rechazar la confirmación si foo.c se modifica como parte de la confirmación, pero foo_A.c no lo está. Dependiendo de la cantidad de archivos en su proyecto, esto puede ser difícil de administrar al listar los archivos explícitamente en el script hook.

Si tiene convenciones de nomenclatura de archivos coherentes, es posible que pueda poner alguna lógica inteligente de coincidencia de patrones en la secuencia de comandos. (Por ejemplo, si sabe que los nombres de los archivos optimizados siempre terminan en "_A", puede automatizar la verificación un poco más fácilmente.)

Como alternativa, puede intentar solucionar el problema en su proceso de compilación. La secuencia de comandos de compilación podría hacer una "información svn" en los dos archivos, y luego arrojar una advertencia/error si los números de rev. SVN de los dos archivos no concuerdan. Sin embargo, podría ser difícil detectar si los números de rev son diferentes por razones legítimas (por ejemplo, editó solo uno de los archivos deliberadamente).

Sin embargo, como han señalado los comentaristas, sinceramente siento que está tratando de resolver el problema incorrectamente. Intentaré estructurar el código para evitar que esta clase de errores suceda en primer lugar.Si ambas funciones necesitan cambiar al mismo tiempo, esto es un signo de duplicación innecesaria en la base de código. Mira consolidando los elementos comunes de los dos archivos en un solo lugar.

Cuestiones relacionadas