what version-control blame

version-control - what - github history of file



¿Es una semántica simplificada para el comando de ''culpa'' algo bueno? (3)

Estoy trabajando en una nueva estructura de datos basada en weave para almacenar el historial de control de versiones. Indudablemente, esto provocará algunas guerras religiosas sobre si es la forma correcta de hacer las cosas cuando se publique, pero esa no es mi pregunta en este momento.

Mi pregunta tiene que ver con lo que la blame debería dar. Cuando una línea de código ha sido agregada, eliminada y fusionada en sí misma varias veces, no siempre queda claro qué revisión debe ser la responsable. En particular, esto significa que cuando se borra una sección del código, todos los registros de su existencia han desaparecido y no hay culpa por la eliminación. Todo el mundo con el que he tratado este tema ha dicho que tratar de hacerlo mejor simplemente no vale la pena. A veces, las personas que escriben la línea después de la sección que fue eliminada tienen su culpa cambiada de lo que realmente fue a la revisión cuando la sección fue eliminada. Presumiblemente, si la sección está al final, entonces la última línea cambia su culpa, y si el archivo termina vacío, la culpa realmente desaparece en el éter, porque literalmente no hay lugar para poner la información de la culpa. Por diversas razones técnicas, no usaré este truco, pero supongo que continuar, pero con esta práctica completamente no documentada pero de facto no será controvertido (pero siéntete libre de llamarme y sacarlo de tu sistema).

Pasando a mi pregunta real. Por lo general, la culpa de cada línea se ve en el historial completo de dónde se agregó y eliminó en el historial y se usa la combinación de tres vías (o, en el caso de las combinaciones cruzadas, la mierda aleatoria) y se basa en las relaciones entre ellas. usted determina si la línea debería haber estado allí en función de su historial, y si no debería hacerlo, es porque la marca como nueva con la revisión actual. En el caso de que una línea ocurra en varios ancestros con diferentes culpas, entonces elige cuál heredar arbitrariamente. Una vez más, asumo que continuar con esta práctica estándar completamente indocumentada pero de facto no será controversial.

Donde mi nuevo sistema difiere es que en lugar de hacer un cálculo complicado de si una línea dada debería estar en la revisión actual basada en un cálculo complejo de todo el historial, simplemente mira a los antepasados ​​inmediatos, y si la línea está en cualquiera de De ellos escoge uno arbitrario para heredar la culpa. Estoy haciendo este cambio por razones en gran parte técnicas (y es totalmente posible que otras implementaciones de culpas hagan lo mismo, por razones técnicas similares y por falta de atención) pero después de pensarlo, una parte de mí en realidad prefiere el nuevo comportamiento como Ser más intuitivo y predecible que el anterior. ¿Qué piensan todos?


A nivel personal, prefiero tu opción simplificada.

Razón: la culpa no se usa mucho de todos modos.

Por lo tanto, no veo el motivo de perder mucho tiempo haciendo una implementación integral de la misma.

Es verdad. La culpa se ha convertido en una de esas características de "olla de oro al final del arco iris". Parecía realmente genial para aquellos de nosotros que estábamos en el suelo, soñando con un día en que pudiéramos simplemente hacer clic en un archivo y ver quién escribió qué líneas de código. Pero ahora que está implementado ampliamente, la mayoría de nosotros nos hemos dado cuenta de que en realidad no es muy útil. Verifique la actividad en la etiqueta de blame aquí en . Es muy desolador.

Me he encontrado con docenas de escenarios "dignos de la culpa" solo en los últimos meses, y en la mayoría de los casos he intentado usar la culpa primero, y me pareció incómodo o totalmente inútil. En su lugar, encontré la información que necesitaba haciendo un simple registro de cambios filtrado en el archivo en cuestión. En algunos casos, también podría haber encontrado la información utilizando Blame, si hubiera sido persistente, pero hubiera tardado mucho más.

El principal problema es el código de cambios de formato. La culpa de primer nivel por casi todo fue catalogado como ... ¡yo! ¿Por qué? Porque soy el responsable de corregir nuevas líneas y pestañas, reorganizar el orden de las funciones, dividir las funciones en módulos de utilidad separados, corregir errores tipográficos de comentarios y mejorar o simplificar el flujo de código. Y si no fuera yo, alguien más había hecho un espacio en blanco o un movimiento de bloque en algún lugar también. Para poder culpar de manera significativa a cualquier cosa que se remonta a un tiempo antes de que ya pueda recordar sin la ayuda de la culpa, tuve que hacer retroceder las revisiones y volver a culpar. Y vuelve a culpar de nuevo. Y otra vez.

Por lo tanto, para que la culpa sea realmente un ahorro de tiempo útil para las situaciones más afortunadas, la culpa tiene que ser capaz de hacer su camino más allá de la nueva línea, el espacio en blanco y, idealmente, bloquear los cambios de copiar / mover. Eso suena como una tarea muy difícil, especialmente cuando se busca en el registro de cambios en un solo archivo, la mayoría de las veces, no produce muchas diferencias de todos modos y se puede filtrar a mano con bastante rapidez. (La excepción notable es, quizás, los árboles de origen mal diseñados donde el 90% del código se rellena en uno o dos archivos gigantes ... pero, ¿quiénes en estos días en un entorno de codificación colaborativa hacen mucho de eso?).

Conclusión: déle una aplicación de culpa escueto, porque a algunas personas les gusta ver "¡se puede culpar!" en la lista de características. Y luego pasar a las cosas que importan. ¡Disfrutar!


De hecho, escribí una de las implementaciones de la culpa (creo que es la actual de Subversion , a menos que alguien la haya reemplazado en el último año o dos). También ayudé con algunos otros.

Al menos la mayoría de las implementaciones de la culpa no hacen lo que usted describe:

Por lo general, la culpa de cada línea se ve en el historial completo de dónde se agregó y eliminó en el historial y se usa la combinación de tres vías (o, en el caso de las combinaciones cruzadas, una mierda aleatoria) y se basa en las relaciones entre aquellos con los que Determine si la línea debería haber estado allí en función de su historial, y si no debería, pero entonces la marca como nueva con la revisión actual. En el caso de que una línea ocurra en varios ancestros con diferentes culpas, entonces elige cuál heredar arbitrariamente. Una vez más, asumo que continuar con esta práctica estándar completamente indocumentada pero de facto no será controversial.

En realidad, la mayoría de las culpas son mucho menos complejas que esto y no se molestan en tratar de usar las relaciones en absoluto, sino que simplemente conducen a los padres en un orden arbitrario, utilizando estructuras delta simples (por lo general, la misma estructura interna, independientemente del algoritmo diferencial que tengan antes). lo convierte en salida textual) para ver si el fragmento cambió, y si es así, culpe y marque esa línea como hecha.

Por ejemplo, Mercurial solo realiza una búsqueda iterativa en profundidad hasta que se culpe a todas las líneas. No trata de tener en cuenta si las relaciones hacen que sea improbable que culpe a la correcta.

Git hace algo un poco más complicado, pero aún así, no del todo como lo describiste.

Subversion hace lo que hace Mercurial, pero el gráfico de la historia es muy simple, por lo que es aún más fácil.

A su vez, lo que estás sugiriendo es, de hecho, lo que realmente hacen todos:

Elija un antepasado arbitrario y siga ese camino por el agujero del conejo hasta que esté listo, y si no causa que haya culpado a todas las líneas, elija arbitrariamente el siguiente antepasado, continúe hasta que se asigne toda la culpa.


El algoritmo de combinación de líneas es más estúpido que el desarrollador. Si no están de acuerdo, eso solo indica que la fusión es incorrecta en lugar de indicar un punto de decisión. Entonces, la lógica simplificada debería ser más correcta.