<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Amend on Zwindler's Reflection</title><link>https://blog.zwindler.fr/tags/amend/</link><description>Recent content in Amend on Zwindler's Reflection</description><generator>Hugo -- gohugo.io</generator><language>fr-fr</language><copyright>Licensed under CC BY-SA 4.0</copyright><lastBuildDate>Fri, 24 Mar 2017 13:00:31 +0000</lastBuildDate><atom:link href="https://blog.zwindler.fr/tags/amend/index.xml" rel="self" type="application/rss+xml"/><item><title>Fusionner plusieurs dépôts Git tout en gardant l’historique</title><link>https://blog.zwindler.fr/2017/03/24/fusionner-plusieurs-repos-git-avec-historique/</link><pubDate>Fri, 24 Mar 2017 13:00:31 +0000</pubDate><guid>https://blog.zwindler.fr/2017/03/24/fusionner-plusieurs-repos-git-avec-historique/</guid><description>&lt;img src="https://blog.zwindler.fr/2017/03/git_logo.webp" alt="Featured image of post Fusionner plusieurs dépôts Git tout en gardant l’historique" /&gt;&lt;h2 id="je-découvre-git"&gt;Je découvre Git
&lt;/h2&gt;&lt;p&gt;L’avantage de travailler en &lt;strong&gt;#DevOps&lt;/strong&gt; (et c’est d’ailleurs tout le principe), est que la proximité avec les Devs (et inversement les Ops) incite à comprendre les méthodes de travail et à utiliser les outils des autres. Et bien sûr, en cas de difficulté, je n’ai qu’à me retourner et demander un coup de main aux experts ;-). Dans mon exemple, j’avais un petit souci avec Git.&lt;/p&gt;
&lt;p&gt;J’avais initialement stocké des playbooks Ansible dans des dépôts Git distincts et bien sûr quand j’ai commencé à en avoir beaucoup (~20) j’ai changé d’avis. Cela devenait trop contraignant à exploiter sachant que les playbooks (découpés en rôles) sont parfois interdépendants.&lt;/p&gt;
&lt;p&gt;Le plus simple aurait été de regrouper l’ensemble des sources à la version actuelle dans un même dossier, puis de tout simplement recréer un dépôt. Cependant, de cette manière, je perdais l’ensemble de l’historique des commits. Idem si j’avais copié les fichiers dans un des dépôts existant (je n’aurai gardé que l’historique d’un seul dépôt).&lt;/p&gt;
&lt;p&gt;N’étant pas expert Git, il y a probablement plusieurs façon, cependant, je peux attester que celle a fonctionné dans mon cas ;-).&lt;/p&gt;
&lt;h2 id="regarder-comment-git-fonctionne"&gt;Regarder comment Git fonctionne
&lt;/h2&gt;&lt;p&gt;Je ne vais pas vous faire un cours pour vous expliquer comment Git fonctionne, il existe de nombreuses ressources qui mettent en avant les avantages de Git par rapport à d’autres logiciels de gestion de version.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note : Si vous débutez sur ce &lt;a class="link" href="https://fr.wikipedia.org/wiki/Logiciel_de_gestion_de_versions" target="_blank" rel="noopener"
&gt;VCS&lt;/a&gt;, je vous conseille vivement de commencer par dérouler un tutoriel pour comprendre les bases et pourquoi par faire quelques tutoriels interactifs (sous la forme de petites « énigmes »). Je donne quelques exemples en fin d’article.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Je me contenterais simplement rappeler que Git est un logiciel de gestion de version qui, à la différence de SVN, n’a pas de serveur centralisé. Ce point, pas forcément intuitif si vous venez de SVN, est extrêmement important.&lt;/p&gt;
&lt;p&gt;Au delà du fait que ce caractère décentralisé est un des points qui a fait la popularité de ce VCS, cela va nous permettre de régler mon problème :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;je vais créer un nouveau dépôt vierge&lt;/li&gt;
&lt;li&gt;lui ajouter l’URL dans sa configuration les dépôts existants en tant que &lt;strong&gt;remote&lt;/strong&gt;, lui faisant croire que ce sont des dépôts provenant du même code source&lt;/li&gt;
&lt;li&gt;recréer artificiellement entre les deux dépôts un historique « commun » avec &lt;strong&gt;git rebase&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="au-travail-maintenant"&gt;Au travail maintenant
&lt;/h2&gt;&lt;p&gt;La première étape consiste donc à créer un nouveau dépôt git. Créez un dossier vide, mettez vous dedans et initialisez un nouveau dépôt grâce à la commande suivante :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git init #pour créer un nouveau repo dans le dossier courant
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Que fait Git ?&lt;/p&gt;
&lt;p&gt;Et bien dans le cas présent, il se contente de créer un dossier &lt;strong&gt;.git&lt;/strong&gt; dans lequel il stockera ses métadata, ainsi qu’un fichier &lt;strong&gt;config&lt;/strong&gt; dans lequel on retrouve toutes les options du dépôt. Ouvrez le avec votre éditeur de texte préféré, voilà à quoi ça devrait ressembler :&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[core]
repositoryformatversion = 0
filemode = false
bare = false
logallrefupdates = true
symlinks = false
ignorecase = true
hideDotFiles = dotGitOnly
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On va donc maintenant y ajouter les URLs des dépôts en tant que « remotes ». Dans mon cas, les dépôts sont accessibles via des URL HTTPS via Gitlab, mais ce n’est aucunement un prérequis. Vous devez juste pouvoir renseigner les « remotes » dans votre fichier &lt;strong&gt;.git/config&lt;/strong&gt;.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[remote &amp;#34;depot_ansible_1&amp;#34;]
url = https://@IPgitlab/automatisation/depot_ansible_1.g1t
fetch = +refs/heads/*:refs/remotes/origin/*
[remote &amp;#34;depot_ansible_2&amp;#34;]
url = https://@IPgitlab/automatisation/depot_ansible_2.g1t
fetch = +refs/heads/*:refs/remotes/origin/*
[remote &amp;#34;depot_ansible_3&amp;#34;]
url = https://@IPgitlab/automatisation/depot_ansible_3.g1t
fetch = +refs/heads/*:refs/remotes/origin/*
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Dans l’exemple suivant, j’ai donc ajouté des dépôts, nommés &lt;strong&gt;depot_ansible_1&lt;/strong&gt;, &lt;strong&gt;depot_ansible_2&lt;/strong&gt; et &lt;strong&gt;depot_ansible_3&lt;/strong&gt;, tous accessibles depuis mon Gitlab aux URLs données.&lt;/p&gt;
&lt;p&gt;Comme on part d’un dépôt vide, le premier git pull vers &lt;strong&gt;depot_ansible_1&lt;/strong&gt; devrait bien se passer. Git se contente d’intégrer l’ensemble du code et des commits du dépôt &lt;strong&gt;depot_ansible_1&lt;/strong&gt; comme si on avait fait un « clone ».&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git pull depot_ansible_1 master
&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;So far, so good&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="ca-se-complique-un-peu"&gt;Ca se complique « un peu »
&lt;/h2&gt;&lt;p&gt;Évidemment on ne peut plus reproduire la manœuvre précédente. Si vous tentez de le faire, vous recevrez un message qui vous dira que les deux dépôts ne partagent pas d’historique commun. On va donc faire un pull avec l’option &lt;strong&gt;rebase&lt;/strong&gt;. Mais avant tout un petit coup d’œil au &lt;strong&gt;man&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.zwindler.fr/2017/03/git_pull_rebase.avif"
loading="lazy"
&gt;&lt;/p&gt;
&lt;p&gt;Dans mon cas, c’est précisément ce que je souhaite faire. Pour autant, je vous engage moi aussi à faire attention ;-).&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git pull -r depot_ansible_2 master
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A partir de ce moment là, git tente de trouver un point commun entre les deux arbres des 2 premiers dépôts (potentiellement jusqu’à l’initialisation du dépôt), puis recréée un historique à partir des deux dépôts en rejouant un à un les commits des deux dépôts.&lt;/p&gt;
&lt;p&gt;Un dernier point, si vous tombez, lors du rebase, sur un conflit, vous devez le résoudre manuellement. Ajoutez les fichiers corrigés avec « add », puis continuez avec « rebase &amp;ndash;continue »&lt;/p&gt;
&lt;h2 id="cest-fini-on-nettoie-un-peu"&gt;C’est fini, on nettoie un peu
&lt;/h2&gt;&lt;p&gt;Mission accomplie pour ces deux dépôts, qui sont maintenant fusionnés dans un seul dépôts avec leurs historiques de commits respectifs ! Vous n’avez plus qu’à reproduire la procédure pour chacun des dépôts (si vous en avez d’autre, &lt;strong&gt;depot_ansible_3&lt;/strong&gt; dans mon exemple).&lt;/p&gt;
&lt;p&gt;Cependant, si vous avez des messages du genre « premier commit » dans chacun de vos dépôts, ces messages n’ont pas vraiment de sens. On peut donc réutiliser le principe du rebase pour réécrire une nouvelle fois l’historique. Le rebase vous proposera la liste des commits dans un éditeur et vous pourrez sélectionner manuellement ceux que vous voulez garder (pick) ou modifier (reword).&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git rebase -i HEAD~X #puis sélectionner les commit à modifier et les corriger un à un
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Par exemple, si j’ai 4 commits, et que je veux réécrire le 1er de depot_ansible_2&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git rebase -i HEAD~3
pick 8c98724 commit 1 de depot_ansible_1
reword 5ad60bb commit 1 de depot_ansible_2
pick 82b0cc3 commit de depot_ansible_2
# Rebase dff1fb2..82b0cc3 onto dff1fb2 (3 command(s))
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# [...]
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="documentation-complémentaire"&gt;Documentation complémentaire
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://@IPgit-scm.com/book/fr/v2" target="_blank" rel="noopener"
&gt;Pro Git : la référence des livres sur Git&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://try.github.io/levels/1/challenges/1" target="_blank" rel="noopener"
&gt;Un tutoriel interactif de GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://delicious-insights.com/fr/articles/bien-utiliser-git-merge-et-rebase/" target="_blank" rel="noopener"
&gt;Un article intéressant sur la différence entre git merge et git rebase&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>