¡Feliz día del programador! Le deseo más compromisos brillantes, solicitudes de extracción fusionadas, menos conflictos de fusión y que las ramas de su vida sigan siendo relevantes el mayor tiempo posible. Como regalo conceptual, propongo la implementación de un árbol genealógico mediante el sistema de control de versiones Git. Bueno ... suena como un plan!
Para aquellos que han entendido todo de inmediato, les doy enlaces al código fuente: GenealogyTreeInGit y árboles genealógicos: mineros y presidentes de los Estados Unidos .
Además, implementé un gráfico social simple. Muestra no solo el grado de parentesco, sino también el estado de las relaciones entre descendientes, eventos como bodas, divorcios, partos, así como contribuciones a las relaciones.
Git
Afortunadamente o desafortunadamente, Git es similar al ganador que reescribe el historial: le permite cambiar fechas, mensajes y autores de confirmaciones. Pero esto le permite agregar miembros de la familia, como si fueran los autores de los eventos realizados en una fecha específica.
Empecé pequeño: escribí varios comandos y listo, un fragmento del árbol está listo. Bien Ahora vamos a hacer esto con todo el ejército de parientes. ¡Estaré encantado de escribir 200 líneas de código confuso para ellos y 10K líneas para presidentes!
¿Ya me has agregado a la lista de idiotas? Quitarse Por supuesto, automaticé el proceso y escribí una aplicación para convertir datos genealógicos en una secuencia de comandos Git. Hay varios formatos para dichos datos, elegí GEDCOM .
Gedcom
Implementé todo este desastre en .NET Core: es conveniente y multiplataforma. Para analizar y procesar GEDCOM, hay varias bibliotecas de C #, por ejemplo, GeneGenie.Gedcom , gedcomx-csharp . Decidí escribir mi propia biblioteca basada en GedcomParser , porque tiene un defecto fatal ... En realidad, no: solo quería entender el formato y deshacerme de todas las dependencias, lo que permitiría, si es necesario, portar fácilmente el proyecto a otros idiomas
Generación de comandos
Es hora de procesar los datos extraídos en un formato conveniente y generar comandos Git para ellos. Decidí ordenar todos los eventos en orden cronológico, y luego crear ramas, fusionarlas y comprometerlas en orden ascendente de fechas. Desafortunadamente, no todos los eventos tienen fechas, por lo que no fue fácil clasificar todos los eventos correctamente. 2 ^ 2 ^ 3 días se acerca, y me di cuenta de que este enfoque no era del todo correcto, ya que la búsqueda en profundidad sería mucho más fácil. Tal vez lo corregiré más tarde.
Inicialización
En esta etapa, solo inicializamos el repositorio:
mkdir Family cd Family git init
Eventos
En esta parte del script procesamos y confirmamos todos los eventos. Para hacer esto, se usaron los siguientes comandos:
git checkout --orphan branch_name
git merge @I1@ --allow-unrelated-histories --no-commit
git commit -m "msg" --date "" --author "name <email>" --allow-empty
El primer comando, checkout
, crea una rama para cada persona. La bandera --orphan
permite crear ramas huérfanas, es decir, ramas sin padres. La rama huérfana se crea una vez; la próxima vez que cambie de rama utilizando el comando de checkout
este parámetro se omite. Al final, casi todos los commits tienen padres, excepto los ancestros más distantes, ya que los anteriores son desconocidos.
El segundo comando, merge
, une a los padres y crea al hijo. Escribimos "Nacimiento" con el año correspondiente en el mensaje de confirmación. También especificamos las banderas --allow-unrelated-histories
y --no-commit
para habilitar la fusión de ramas huérfanas y para confirmar los cambios más adelante. Algunos niños son adoptados, así que escribimos "Adoptados" para ellos. Es gracioso, pero Git permite matrimonios grupales, es decir, es posible fusionar más de dos ramas a la vez. Y las ramas no tienen género, por lo que puede llamarlas "padre 1" y "padre 2". Por cierto, también es posible crear padres solteros.
Finalmente, el tercer comando, commit
, crea un nuevo commit con el mensaje -m
, la fecha --date
y el autor --author
. Como ya mencioné, Git le permite cambiar el mensaje, el autor y la fecha de la confirmación. Además, Git le permite crear confirmaciones sin archivos con el indicador --allow-empty
, y sin mensajes con el indicador --allow-empty-message
. El autor también necesita especificar un correo electrónico, pero Git acepta uno vacío, solo necesita escribir <>
. Desafortunadamente, Git no respeta a los ancianos: el límite inferior de la fecha de la confirmación es el 1 de enero de 1970 (el "inicio" de Unix Time); la fecha anterior se mostrará incorrectamente. Sin embargo, simplemente puede mencionar la fecha real en la descripción. Sin embargo, Git acepta fechas en el futuro: mira a mi hijo Git. Por cierto, también es posible crear padres solteros.
Gráfico social
En el gráfico social, también se almacenan otros eventos además del nacimiento: bautismo, cambio de residencia, graduación, matrimonio, divorcio, muerte, funeral. Despues de la muerte la rama va al cielo digital La aparición de eventos posteriores, excepto los funerales, es imposible en la sucursal. En el servidor, puede proteger esta rama (no se preocupe: es posible "resucitarla" en el futuro, si es necesario).
El evento "Boda" tiene dos antepasados: cónyuges. El "divorcio" tiene un antepasado: la "boda" anterior. La familia y la paternidad son trabajo, por lo que podemos decir que después de la boda también aparece un nuevo descendiente: "relación" que termina después de un divorcio (o la muerte de un cónyuge). Se reanuda después de la próxima boda. Además, varias personas pueden participar en una relación (fusionando varias ramas).
Finalizacion
La guinda del pastel: hacemos un repositorio de respaldo y cargamos a todos los participantes a GitHub, GitLab o cualquier otro servidor que admita Git. Podemos empujar las ramas una por una, pero usando el comando mágico las empujaremos todas, lo cual es mucho más rápido y simple:
git remote add origin https://gitlab.com/KvanTTT/Family.git git push origin --all -u
Para generar un árbol genealógico común, debe pasar la bandera: --only-birth-events
al iniciar el generador. En este caso, se creará una confirmación por persona (nacimiento). De lo contrario, un red social Se generará un gráfico social.
Ejemplos
Como un pequeño ejemplo, que al menos funcionará en todas partes, creé mi árbol genealógico, y un gran ejemplo es el árbol de los presidentes estadounidenses (2145 personas). Están disponibles en los repositorios Kochurkins y Presidentes , respectivamente. Para crear mi propio árbol, utilicé el servicio geni.com , desde el cual exporté el árbol a GEDCOM. Un script generado para crear un repositorio genealógico está disponible en Gist .

En GitHub (y GitLab también), puede navegar a través de antepasados y descendientes. Esto es similar a los sistemas wiki genealógicos Familypedia o WeRelate . Sin embargo, GitHub / GitLab es más avanzado: los árboles se descargan fácilmente desde él (con la ayuda del comando --clone
). Y lo más importante, puede abrir todo el gráfico a la vez. (En los programas genealógicos existentes, por alguna razón, existen dificultades para abrir incluso gráficos pequeños). Y puede hacerlo utilizando diferentes herramientas (servicio web, Git Extesions , Sourcetree , GitKraken y otros). Además, estos servicios se pueden usar de forma gratuita, a diferencia de la mayoría de los servicios genealógicos.
Cabe destacar que en GitHub / GitLab incluso hay algún tipo de análisis disponible: puede averiguar quién tiene más cuenta de Instagram seguida vida llena de acontecimientos O la más pública: la pestaña Insights
muestra una lista de personas en orden decreciente de confirmaciones.
Desafortunadamente, GitHub y GitLab no muestran árboles grandes correctamente, pero están almacenados correctamente; puede abrir el repositorio y verificar. Aquí está mi árbol en la interfaz web de GitLab:
Problemas
No está muy claro cómo complementar la historia desde las raíces. Por ahora debes generarlo desde el principio desde el archivo GEDCOM. Probablemente esto se puede hacer con la ayuda de rebase
puede intentar contarlo en los comentarios. También sería mejor reescribir el código para hacerlo "orientado a la confirmación", no "orientado a eventos", porque es más parecido a Git: de hecho, la rama es una secuencia de confirmaciones, no una entidad separada. También pensé en implementar etiquetas y submódulos , pero por ahora no sé cómo hacerlo mejor.
Conclusión
Si amplía la idea de los árboles genealógicos más allá de los servicios web para desarrolladores, utilizando problemas puede crear tareas globales y distribuirlas según los hitos : infancia, juventud, edad adulta, edad avanzada.
Además de los árboles genealógicos, puede usar Git para codificar árboles genealógicos de lenguajes de programación (esto es aún más geek), árboles de sintaxis y cualquier estructura de árbol. Git también puede ser útil para las amas de casa para construir relaciones entre los personajes de las telenovelas brasileñas :)
Beneficio práctico: este calentamiento ayuda a comprender mejor la estructura de Git, sus comandos y el formato GEDCOM para describir datos genealógicos.
Las fuentes del artículo están disponibles en GitHub : envíe una solicitud de extracción si encuentra algún error o desea agregar algo. Para convertir al formato habr.com, uso la biblioteca MarkConv .