Bonne journée du programmeur! Je vous souhaite des commits plus brillants, des demandes de fusion fusionnées, moins de conflits de fusion et que vos branches de vie restent pertinentes aussi longtemps que possible. Comme cadeau conceptuel, je propose la mise en place d'un arbre généalogique au moyen du système de contrôle de version Git. Eh bien ... ça ressemble à un plan!
Pour ceux qui ont tout compris immédiatement, je donne des liens vers le code source: GénéalogieTreeInGit et les arbres généalogiques : les miens et les présidents américains .
De plus, j'ai implémenté un simple graphe social . Il affiche non seulement le degré de parenté, mais aussi le statut des relations entre les descendants, des événements tels que le mariage, le divorce, l'accouchement, ainsi que les contributions aux relations.
Git
Heureusement ou malheureusement, Git est similaire au gagnant qui réécrit l'histoire: il vous permet de changer les dates, les messages et les auteurs des commits. Mais cela vous permet d'ajouter des membres de la famille, comme s'ils étaient les auteurs d'événements faits à une date précise.
J'ai commencé petit: j'ai écrit plusieurs commandes et le tour est joué, un fragment de l'arbre est prêt. Très bien Maintenant, nous allons le faire avec toute l'armée de parents. Je serai heureux d'écrire 200 lignes de code déroutant pour eux, et 10K lignes pour les présidents!
M'as-tu déjà ajouté à la liste des idiots? Radiez. Bien sûr, j'ai automatisé le processus et écrit une application pour convertir des données généalogiques en une séquence de commandes Git. Il existe plusieurs formats pour ces données, j'ai choisi GEDCOM .
Gedcom
J'ai implémenté tout ce gâchis dans .NET Core - c'est pratique et multiplateforme. Pour l'analyse et le traitement de GEDCOM, il existe plusieurs bibliothèques C #, par exemple, GeneGenie.Gedcom , gedcomx-csharp . J'ai décidé d'écrire ma propre bibliothèque basée sur GedcomParser , car elle a une faille fatale ... En fait, non: je voulais juste comprendre le format moi-même et me débarrasser de toutes les dépendances, ce qui permettrait, si nécessaire, de porter facilement le projet vers autres langues.
Génération de commandes
Il est temps de traiter les données extraites dans un format pratique et de générer des commandes Git pour cela. J'ai décidé de trier tous les événements par ordre chronologique, puis de créer des branches, de les fusionner et de les valider par ordre croissant de dates. Malheureusement, tous les événements n'ont pas de date, il n'a donc pas été facile de trier tous les événements correctement. 2 ^ 2 ^ 3 jours arrivent, et j'ai réalisé que cette approche n'était pas tout à fait correcte, car la recherche en profondeur d'abord serait beaucoup plus facile. Je vais peut-être le corriger plus tard.
Initialisation
À ce stade, nous venons d'initialiser le référentiel:
mkdir Family cd Family git init
Les événements
Dans cette partie du script, nous traitons et validons tous les événements. Pour ce faire, les commandes suivantes ont été utilisées:
git checkout --orphan branch_name
git merge @I1@ --allow-unrelated-histories --no-commit
git commit -m "msg" --date "" --author "name <email>" --allow-empty
La première commande, checkout
, crée une branche pour chaque personne. Le drapeau --orphan
vous permet de créer des branches orphelines, c'est-à-dire des branches sans parents. La branche orpheline est créée une fois - la prochaine fois que vous changez de branche à l'aide de la commande de checkout
ce paramètre est omis. En fin de compte, presque tous les commits ont des parents, à l'exception des ancêtres les plus éloignés, car les premiers sont inconnus.
La deuxième commande, merge
, unit les parents et crée l'enfant. Nous écrivons "Naissance" avec l'année correspondante dans le message de validation. Nous --allow-unrelated-histories
également les indicateurs --allow-unrelated-histories
et --no-commit
pour activer la fusion des branches orphelines et pour valider les modifications ultérieurement. Certains enfants sont adoptés, nous leur écrivons donc "Adopté". C'est drôle, mais Git autorise les mariages de groupe, c'est-à-dire qu'il est possible de fusionner plus de deux branches à la fois. Et les branches n'ont pas de sexe, vous pouvez donc les appeler "parent 1" et "parent 2". Soit dit en passant, il est également possible de créer des parents isolés.
Enfin, la troisième commande, commit
, crée un nouveau commit avec le message -m
, la date --date
et l'auteur --author
. Comme je l'ai déjà mentionné, Git vous permet de changer le message, l'auteur et la date du commit. De plus, Git vous permet de créer des commits sans fichiers avec l'indicateur --allow-empty
, et sans messages avec l'indicateur --allow-empty-message
. L'auteur doit également spécifier un e-mail, mais Git en accepte un vide - il suffit d'écrire <>
. Malheureusement, Git ne respecte pas les personnes âgées: la limite inférieure de la date du commit est le 1er janvier 1970 (le "début" de l'heure Unix) - la date antérieure sera affichée de manière incorrecte. Cependant, vous pouvez simplement mentionner la date réelle dans la description. Néanmoins, Git accepte des dates dans le futur - regardez mon fils Git. Soit dit en passant, il est également possible de créer des parents isolés.
Graphique social
Dans le graphique social, d'autres événements en plus de la naissance sont également enregistrés: baptême, changement de résidence, remise des diplômes, mariage, divorce, décès, funérailles. Après la mort la branche va au paradis numérique l'apparition d'événements ultérieurs, à l'exception des funérailles, est impossible dans la branche. Sur le serveur, vous pouvez protéger cette branche (ne vous inquiétez pas: il est possible de la "ressusciter" à l'avenir, si nécessaire).
L'événement "Mariage" a deux ancêtres - les conjoints. Le "divorce" a un ancêtre - le "mariage" précédent. La famille et la parentalité sont du travail, nous pouvons donc dire qu'après le mariage, un nouveau descendant apparaît également - une «relation» qui se termine après un divorce (ou la mort d'un conjoint). Il reprend après le prochain mariage. De plus, plusieurs personnes peuvent participer à une relation (fusion de plusieurs branches).
Finalisation
La cerise sur le gâteau: nous créons un référentiel de sauvegarde et téléchargeons tous les participants sur GitHub, GitLab ou tout autre serveur prenant en charge Git. Nous pouvons pousser les branches une par une, mais en utilisant la commande magique, nous les pousserons toutes, ce qui est beaucoup plus rapide et plus simple:
git remote add origin https://gitlab.com/KvanTTT/Family.git git push origin --all -u
Pour générer un arbre généalogique commun, vous devez passer le drapeau --only-birth-events
lors du démarrage du générateur. Dans ce cas, un commit par personne (naissance) sera créé. Sinon, un réseau social un graphique social sera généré.
Des exemples
À titre d'exemple, qui fonctionnera au moins partout, j'ai créé mon arbre généalogique, et un grand exemple est l'arbre des présidents américains (2145 personnes). Ils sont disponibles respectivement dans les référentiels Kochurkins et Presidents . Pour créer ma propre arborescence, j'ai utilisé le service geni.com , à partir duquel j'ai exporté l'arborescence vers GEDCOM. Un script généré pour créer un référentiel généalogique est disponible sur Gist .

Sur GitHub (et GitLab également), vous pouvez parcourir les ancêtres et les descendants. Ceci est similaire aux systèmes wiki généalogiques Familypedia ou WeRelate . Cependant, GitHub / GitLab est plus avancé: les arbres sont facilement téléchargeables depuis celui-ci (à l'aide de la commande --clone
). Et surtout, vous pouvez ouvrir le graphique entier en même temps. (Dans les programmes généalogiques existants, pour une raison quelconque, il est difficile d'ouvrir même de petits graphiques.) Et vous pouvez le faire en utilisant différents outils (service Web, Git Extesions , Sourcetree , GitKraken et autres). De plus, ces services peuvent être utilisés gratuitement, contrairement à la plupart des services généalogiques.
Il est à noter que sur GitHub / GitLab même une sorte d'analyse est disponible: vous pouvez découvrir qui a le plus compte Instagram suivi vie mouvementée. Ou le plus public: l'onglet Insights
affiche une liste de personnes par ordre décroissant de commits.
Malheureusement, GitHub et GitLab n'affiche pas correctement les grands arbres, mais ils sont stockés correctement - vous pouvez ouvrir le référentiel et vérifier. Voici mon arbre dans l'interface Web de GitLab:
Problèmes
Il n'est pas très clair comment compléter l'histoire à partir des racines. Pour l'instant, vous devez le générer depuis le début à partir du fichier GEDCOM. Cela peut probablement être fait avec l'aide de rebase
vous pouvez essayer de le dire dans les commentaires. Il serait également préférable de réécrire le code pour le rendre "orienté commit", et non "orienté événement", car il ressemble plus à Git: en fait, la branche est une séquence de validations, pas une entité séparée. J'ai aussi pensé à implémenter des tags et des sous - modules , mais pour l'instant je ne sais pas comment faire mieux.
Conclusion
Si vous étendez l'idée d'arbres généalogiques aux services Web pour les développeurs, vous pouvez créer des tâches globales et les répartir en fonction de jalons : enfance, jeunesse, âge adulte, vieillesse.
Outre les arbres généalogiques, vous pouvez utiliser Git pour encoder les arbres généalogiques des langages de programmation (c'est encore plus geek), les arbres de syntaxe et toutes les structures d'arbres. Git peut également être utile pour les femmes au foyer pour établir des relations entre les personnages de feuilletons brésiliens :)
Avantage pratique: cet échauffement permet de mieux comprendre la structure de Git, ses commandes et le format GEDCOM pour décrire les données généalogiques.
Les sources de l'article sont disponibles sur GitHub - veuillez envoyer Pull Request si vous trouvez une erreur ou si vous souhaitez ajouter quelque chose. Pour la conversion au format habr.com, j'utilise la bibliothèque MarkConv .