GitBonnesPratiques » Historique » Version 57
Daniel Dehennin, 29/02/2012 08:47
Ajout d’un lien sur la future version de git qui requiert un message de merge
| 1 | 40 | Daniel Dehennin | {{toc}} |
|---|---|---|---|
| 2 | 1 | Redmine Admin | |
| 3 | 54 | Klaas TJEBBES | L'ancienne page GitBonnesPratiques est ici http://dev-eole.ac-dijon.fr/projects/eole/wiki/RecueilGit |
| 4 | 54 | Klaas TJEBBES | |
| 5 | 40 | Daniel Dehennin | h1. Les bonnes pratiques c’est quoi ? |
| 6 | 1 | Redmine Admin | |
| 7 | 40 | Daniel Dehennin | Ce document n’est pas une référence git, nous n’allons pas réécrire le |
| 8 | 40 | Daniel Dehennin | "progit book":http://progit.org/book/fr, ni les autres références disponibles sur Internet. |
| 9 | 1 | Redmine Admin | |
| 10 | 40 | Daniel Dehennin | Nous allons partir du principe qu’un minimum de connaissance de l’outil git est acquis, notamment |
| 11 | 42 | Daniel Dehennin | le "démarrage rapide":http://progit.org/book/fr/ch1-0.html et les "bases de git":http://progit.org/book/fr/ch2-0.html du livre "progit book":http://progit.org/book/fr. |
| 12 | 1 | Redmine Admin | |
| 13 | 40 | Daniel Dehennin | Nous allons essayer de décrire ici une méthodologie de travail basée sur le |
| 14 | 40 | Daniel Dehennin | système de gestion de version décentralisé "git":https://fr.wikipedia.org/wiki/Git avec les objectifs suivants : |
| 15 | 1 | Redmine Admin | |
| 16 | 40 | Daniel Dehennin | * Communiquer entre développeur |
| 17 | 40 | Daniel Dehennin | * S’y retrouver dans ses développements, ou comment gérer des ajouts fonctionnels et des corrections de bug en parallèle |
| 18 | 40 | Daniel Dehennin | * Publier des modifications clairement identifiables et analysables, par des humains et des outils de tests automatiques |
| 19 | 35 | Daniel Dehennin | |
| 20 | 41 | Daniel Dehennin | Ce document ne représente en rien _LA_ bonne méthode de travail, il s’agit juste d’une façon de faire, |
| 21 | 41 | Daniel Dehennin | appuyée par l’expérience d’autres personnes que l’on trouve un peu partout sur Internet. |
| 22 | 1 | Redmine Admin | |
| 23 | 41 | Daniel Dehennin | Il est tout à fait possible de trouver autant, voir plus, de références prônant un point de vue opposé ou orthogonal au mien. |
| 24 | 14 | Klaas TJEBBES | |
| 25 | 35 | Daniel Dehennin | |
| 26 | 1 | Redmine Admin | h1. De la méthode agile |
| 27 | 35 | Daniel Dehennin | |
| 28 | 35 | Daniel Dehennin | Comme il est défini dans le "manifeste agile":https://fr.wikipedia.org/wiki/Manifeste_agile#Les_4_valeurs, la première valeur est |
| 29 | 1 | Redmine Admin | « Les individus et leurs interactions ». |
| 30 | 35 | Daniel Dehennin | |
| 31 | 35 | Daniel Dehennin | Afin de travailler correctement en équipe, il faut communiquer, et |
| 32 | 35 | Daniel Dehennin | l’outil de gestion de version "git":https://fr.wikipedia.org/wiki/Git, utilisé à EOLE, peut-être un excellent |
| 33 | 23 | Redmine Admin | outil de communication. |
| 34 | 23 | Redmine Admin | |
| 35 | 35 | Daniel Dehennin | |
| 36 | 23 | Redmine Admin | h1. De l’écriture des "ChangeLog":https://fr.wikipedia.org/wiki/ChangeLog |
| 37 | 35 | Daniel Dehennin | |
| 38 | 35 | Daniel Dehennin | Afin de communiquer avec les autres membres d’une équipe sur le |
| 39 | 35 | Daniel Dehennin | travail que chacun effectue, l’écriture d’un ChangeLog, ou plus |
| 40 | 35 | Daniel Dehennin | précisément d’un « commit message » dans la littérature en anglaise |
| 41 | 35 | Daniel Dehennin | (qui pourrait être traduit par « message de consignation ») se doit |
| 42 | 1 | Redmine Admin | d’être fait correctement(sic). |
| 43 | 35 | Daniel Dehennin | |
| 44 | 23 | Redmine Admin | Que penser d’un message comme « "typo":http://dev-eole.ac-dijon.fr/projects/eole-sso/repository/revisions/f2e5c52482c896b84e57333ba61654286b856f02 » ou encore « "correction d'une coquille":http://dev-eole.ac-dijon.fr/projects/cdc/repository/revisions/0dc6d59ca9c5294790ae1ebe0b035d8a3296ed22 » ? |
| 45 | 35 | Daniel Dehennin | |
| 46 | 1 | Redmine Admin | Nous pouvons établir une règle simple et souple, par exemple : |
| 47 | 35 | Daniel Dehennin | |
| 48 | 23 | Redmine Admin | Un message de commit comprend : |
| 49 | 35 | Daniel Dehennin | |
| 50 | 23 | Redmine Admin | * Une première ligne résumant le pourquoi du patch ; |
| 51 | 35 | Daniel Dehennin | * Une description longue optionnelle permettant d’expliciter le |
| 52 | 1 | Redmine Admin | contexte du résumé donné en première ligne ; |
| 53 | 34 | Bruno Boiget | * Une liste de fichier et leur modification. |
| 54 | 35 | Daniel Dehennin | |
| 55 | 35 | Daniel Dehennin | Une ligne vide sépare les différentes parties : la première est |
| 56 | 23 | Redmine Admin | obligatoire et la troisième est optionnelle pour les changements triviaux |
| 57 | 35 | Daniel Dehennin | |
| 58 | 14 | Klaas TJEBBES | Par exemple : |
| 59 | 1 | Redmine Admin | |
| 60 | 35 | Daniel Dehennin | <pre> |
| 61 | 1 | Redmine Admin | Le répertoire /usr/share/eole/noyau/ est nécessaire (Fixes: #2405). |
| 62 | 35 | Daniel Dehennin | |
| 63 | 1 | Redmine Admin | * debian/dirs: Création du répertoire. |
| 64 | 1 | Redmine Admin | </pre> |
| 65 | 1 | Redmine Admin | |
| 66 | 35 | Daniel Dehennin | <pre> |
| 67 | 35 | Daniel Dehennin | Simplification de la gestion des noyaux (ref: #2406). |
| 68 | 35 | Daniel Dehennin | |
| 69 | 35 | Daniel Dehennin | * creole/fonctionseole.py: Suppression du code effectué par |
| 70 | 35 | Daniel Dehennin | eole-kernel-version depuis sa version 2.3-eole37~2. |
| 71 | 1 | Redmine Admin | Renommage de la variable 'boot_ok' en 'need_boot'. |
| 72 | 1 | Redmine Admin | </pre> |
| 73 | 35 | Daniel Dehennin | |
| 74 | 1 | Redmine Admin | Cela impose la règle suivante : |
| 75 | 35 | Daniel Dehennin | |
| 76 | 1 | Redmine Admin | « Ne jamais utiliser l’option "-m" de la commande "git commit" » |
| 77 | 1 | Redmine Admin | |
| 78 | 35 | Daniel Dehennin | |
| 79 | 1 | Redmine Admin | h1. De la cohérence de l’histoire du monde |
| 80 | 35 | Daniel Dehennin | |
| 81 | 35 | Daniel Dehennin | Un système de gestion de version permet avant tout de conserver un |
| 82 | 14 | Klaas TJEBBES | livre d’histoire d’un projet. |
| 83 | 35 | Daniel Dehennin | |
| 84 | 35 | Daniel Dehennin | Dans les premiers systèmes de gestion de version, cette histoire était |
| 85 | 35 | Daniel Dehennin | centralisée. Il fallait avoir le droit d’écrire dans le « livre des |
| 86 | 35 | Daniel Dehennin | comptes et légendes » afin d’y ajouter un morceau, impossible donc de |
| 87 | 1 | Redmine Admin | réécrire l’histoire sans être tout puissant sur le registre. |
| 88 | 35 | Daniel Dehennin | |
| 89 | 35 | Daniel Dehennin | Grâce aux systèmes décentralisés comme "git":https://fr.wikipedia.org/wiki/Git, tout le monde peut avoir |
| 90 | 35 | Daniel Dehennin | une copie privée de l’histoire publique d’un projet, pour cela il |
| 91 | 1 | Redmine Admin | suffit de « cloner » l’histoire originale : |
| 92 | 1 | Redmine Admin | |
| 93 | 35 | Daniel Dehennin | <pre> |
| 94 | 14 | Klaas TJEBBES | moi@work:~/src$ git clone git://far-far.away.example.net/bidule.git |
| 95 | 14 | Klaas TJEBBES | </pre> |
| 96 | 35 | Daniel Dehennin | |
| 97 | 35 | Daniel Dehennin | À partir de là il est possible de vouloir y ajouter ses propres |
| 98 | 1 | Redmine Admin | morceaux, et cela sans rien demander à personne. |
| 99 | 35 | Daniel Dehennin | |
| 100 | 35 | Daniel Dehennin | On modifie le projet et on consigne les nouveaux événements dans |
| 101 | 35 | Daniel Dehennin | notre copie locale de l’histoire du projet : |
| 102 | 1 | Redmine Admin | |
| 103 | 35 | Daniel Dehennin | <pre> |
| 104 | 35 | Daniel Dehennin | moi@work:~/src/bidule(master)$ $EDITOR src/bidule.c # On modifie un fichier du projet |
| 105 | 35 | Daniel Dehennin | moi@work:~/src/bidule(master)$ git add src/bidule.c # On ajoute un événement à enregistrer dans le livre d’histoire |
| 106 | 1 | Redmine Admin | moi@work:~/src/bidule(master)$ git commit # On consigne ce nouvel événement |
| 107 | 1 | Redmine Admin | </pre> |
| 108 | 35 | Daniel Dehennin | |
| 109 | 35 | Daniel Dehennin | Mais l’histoire, c’est un sujet sensible. On ne badine pas avec |
| 110 | 1 | Redmine Admin | l’histoire et on ne la réécrit sous aucun prétexte. |
| 111 | 35 | Daniel Dehennin | |
| 112 | 35 | Daniel Dehennin | Peu importe si la vérité est ailleurs, l’important c’est que tout le |
| 113 | 1 | Redmine Admin | monde soit d’accord sur la même version des faits. |
| 114 | 35 | Daniel Dehennin | |
| 115 | 35 | Daniel Dehennin | Si un plaisantin modifie l’histoire et la publie à tout vent, il y |
| 116 | 17 | Gérald Schwartzmann | aura conflit. |
| 117 | 35 | Daniel Dehennin | |
| 118 | 1 | Redmine Admin | Nous allons donc édicter la règle suivante : |
| 119 | 35 | Daniel Dehennin | |
| 120 | 16 | Gaston TJEBBES | « On ne réécrit pas l’histoire connue » |
| 121 | 35 | Daniel Dehennin | |
| 122 | 35 | Daniel Dehennin | Cela sous entend donc que nous pouvons réécrire comme il nous plaît |
| 123 | 35 | Daniel Dehennin | toute l’histoire qui nous est privée, c’est à dire inconnue de tous |
| 124 | 1 | Redmine Admin | les autres. |
| 125 | 35 | Daniel Dehennin | |
| 126 | 1 | Redmine Admin | Mais dès qu’un événement est rendu public, ça n'est plus possible. |
| 127 | 8 | Gaston TJEBBES | |
| 128 | 35 | Daniel Dehennin | |
| 129 | 8 | Gaston TJEBBES | h1. Trop de pull, c’est trop chaud ! |
| 130 | 35 | Daniel Dehennin | |
| 131 | 35 | Daniel Dehennin | Que se passe-t-il si un jour nous souhaitons apprendre les nouvelles |
| 132 | 8 | Gaston TJEBBES | histoires de par le monde ? |
| 133 | 35 | Daniel Dehennin | |
| 134 | 35 | Daniel Dehennin | Que ce passe-t-il si un jour nous souhaitons partager nos petites |
| 135 | 1 | Redmine Admin | histoires avec le reste du monde ? |
| 136 | 35 | Daniel Dehennin | |
| 137 | 35 | Daniel Dehennin | La plupart du temps, la réponse donnée à ces questions commence par |
| 138 | 1 | Redmine Admin | quelque chose comme « fais-toi donc un pull ». |
| 139 | 35 | Daniel Dehennin | |
| 140 | 11 | Gaston TJEBBES | Cela se traduit, en terme git, par : |
| 141 | 1 | Redmine Admin | |
| 142 | 35 | Daniel Dehennin | <pre> |
| 143 | 1 | Redmine Admin | moi@work:~/src/bidule(master)$ git pull |
| 144 | 1 | Redmine Admin | </pre> |
| 145 | 35 | Daniel Dehennin | |
| 146 | 1 | Redmine Admin | Cela est strictement équivalent aux deux commandes suivantes : |
| 147 | 1 | Redmine Admin | |
| 148 | 35 | Daniel Dehennin | <pre> |
| 149 | 35 | Daniel Dehennin | moi@work:~/src/bidule(master)$ git fetch origin |
| 150 | 1 | Redmine Admin | moi@work:~/src/bidule(master)$ git merge origin/master |
| 151 | 1 | Redmine Admin | </pre> |
| 152 | 35 | Daniel Dehennin | |
| 153 | 35 | Daniel Dehennin | Mais il existe quelques soucis avec cette méthode, la première étant |
| 154 | 29 | Joël Cuissinat | « qu’une histoire entre en conflit avec l’une des vôtres ». |
| 155 | 35 | Daniel Dehennin | |
| 156 | 35 | Daniel Dehennin | Un autre problème est que cette méthode « mélange » littéralement |
| 157 | 35 | Daniel Dehennin | l’histoire publique avec vos histoires privées, même s’il n’y a pas de |
| 158 | 35 | Daniel Dehennin | conflit, il peut-être difficile de savoir si le résultat aura un sens |
| 159 | 1 | Redmine Admin | ou non. |
| 160 | 1 | Redmine Admin | |
| 161 | 35 | Daniel Dehennin | Dans git, chaque commit a une généalogie, le parent du commit que je |
| 162 | 1 | Redmine Admin | m’apprête à faire est le dernier commit enregistré dans le dépôt. |
| 163 | 35 | Daniel Dehennin | |
| 164 | 21 | Joël Cuissinat | Lors d’un pull sur un dépôt contenant des modifications, git créé un |
| 165 | 41 | Daniel Dehennin | commit ayant deux parents dont le seul but est de mélanger la généalogie. |
| 166 | 37 | Daniel Dehennin | |
| 167 | 41 | Daniel Dehennin | Il est donc préférable d’utiliser la méthode décomposée en deux commandes. |
| 168 | 37 | Daniel Dehennin | |
| 169 | 37 | Daniel Dehennin | Cela permet de vérifier au préalable si des changements |
| 170 | 37 | Daniel Dehennin | sont à intégrer, et lesquels, avec les commandes suivantes : |
| 171 | 37 | Daniel Dehennin | |
| 172 | 37 | Daniel Dehennin | * ChangeLog des différences |
| 173 | 38 | Daniel Dehennin | <pre> |
| 174 | 37 | Daniel Dehennin | moi@work:~/src/bidule(master)$ git log master..origin/master |
| 175 | 37 | Daniel Dehennin | </pre> |
| 176 | 44 | Fabrice Barconnière | * Liste des fichiers modifiés |
| 177 | 38 | Daniel Dehennin | <pre> |
| 178 | 37 | Daniel Dehennin | moi@work:~/src/bidule(master)$ git diff --stat master..origin/master |
| 179 | 37 | Daniel Dehennin | </pre> |
| 180 | 37 | Daniel Dehennin | * Modification du code |
| 181 | 38 | Daniel Dehennin | <pre> |
| 182 | 37 | Daniel Dehennin | moi@work:~/src/bidule(master)$ git diff master..origin/master |
| 183 | 21 | Joël Cuissinat | </pre> |
| 184 | 35 | Daniel Dehennin | |
| 185 | 21 | Joël Cuissinat | Mais cela n’empêche nullement : |
| 186 | 35 | Daniel Dehennin | |
| 187 | 35 | Daniel Dehennin | * D’être potentiellement désastreux : chaque « fusion » (merge) et |
| 188 | 35 | Daniel Dehennin | « consignation » de « fusion » (merge commit) sont à la charge de |
| 189 | 21 | Joël Cuissinat | chaque développeur ; |
| 190 | 35 | Daniel Dehennin | * Votre histoire devient illisible. Elle intègre tout un tas de |
| 191 | 21 | Joël Cuissinat | « fusion » inexplicables ; |
| 192 | 35 | Daniel Dehennin | * Retrouver à quel moment précis et quel modification a entraîné un |
| 193 | 35 | Daniel Dehennin | changement de comportement devient impossible du fait des |
| 194 | 1 | Redmine Admin | « fusions » |
| 195 | 1 | Redmine Admin | |
| 196 | 1 | Redmine Admin | Tout mélanger dans la même branche, qui devient alors un tronc, pose |
| 197 | 1 | Redmine Admin | des soucis quant à la lecture de l’histoire du projet. |
| 198 | 21 | Joël Cuissinat | |
| 199 | 21 | Joël Cuissinat | |
| 200 | 35 | Daniel Dehennin | |
| 201 | 21 | Joël Cuissinat | h1. Pour s’y retrouver, il faut s’accrocher aux branches |
| 202 | 35 | Daniel Dehennin | |
| 203 | 35 | Daniel Dehennin | Une branche est une ligne d’histoire divergente d’un projet, leur |
| 204 | 44 | Fabrice Barconnière | utilisation dans git est très simple et légère. |
| 205 | 35 | Daniel Dehennin | |
| 206 | 1 | Redmine Admin | La création d’une branche peut se faire de deux façons : |
| 207 | 35 | Daniel Dehennin | |
| 208 | 35 | Daniel Dehennin | # Créer une branche que j’utiliserais plus tard : |
| 209 | 40 | Daniel Dehennin | <pre> |
| 210 | 1 | Redmine Admin | moi@work:~/src/projet(master)$ git branch mabranche |
| 211 | 40 | Daniel Dehennin | moi@work:~/src/projet(master)$ # on commit dans la branche « master » |
| 212 | 40 | Daniel Dehennin | </pre> |
| 213 | 40 | Daniel Dehennin | # Créer une branche et commencer à travailler dedans : |
| 214 | 40 | Daniel Dehennin | <pre> |
| 215 | 40 | Daniel Dehennin | moi@work:~/src/projet(master)$ git checkout -b mabranche |
| 216 | 40 | Daniel Dehennin | moi@work:~/src/projet(mabranche)$ # on commit dans la branche « mabranche » |
| 217 | 35 | Daniel Dehennin | </pre> |
| 218 | 35 | Daniel Dehennin | |
| 219 | 41 | Daniel Dehennin | Chacune de ces commandes permet de définir, en dernier argument, le point de départ de la nouvelle branche. |
| 220 | 35 | Daniel Dehennin | |
| 221 | 1 | Redmine Admin | Par défaut ce point de départ est le dernier commit de la branche courante. |
| 222 | 35 | Daniel Dehennin | |
| 223 | 1 | Redmine Admin | Tout les commit effectués sur cette branche sont localisés à cette branche. |
| 224 | 1 | Redmine Admin | |
| 225 | 35 | Daniel Dehennin | Cela permet de se focaliser sur une activité : |
| 226 | 1 | Redmine Admin | |
| 227 | 1 | Redmine Admin | * Sans risquer d’impacter la vision que les autres ont de l’histoire ; |
| 228 | 1 | Redmine Admin | * Sans se soucier de ce qui peut arriver sur les autres branches ; |
| 229 | 1 | Redmine Admin | * Sans fusionner les modifications de la branche principale dans la |
| 230 | 35 | Daniel Dehennin | branche courante. |
| 231 | 1 | Redmine Admin | |
| 232 | 41 | Daniel Dehennin | Il faut travailler ensuite à intégrer cette nouvelle histoire à la ligne principale. |
| 233 | 1 | Redmine Admin | |
| 234 | 35 | Daniel Dehennin | h2. Les voies du temps sont interpénétrables |
| 235 | 35 | Daniel Dehennin | |
| 236 | 41 | Daniel Dehennin | C’est le principe utilisé par le pull, ce qui est nommé dans la littérature le « merge workflow ». |
| 237 | 36 | Daniel Dehennin | |
| 238 | 41 | Daniel Dehennin | Ce qui est fait lors d’un @git pull@ entre une branche locale et une branche sur un dépôt distant, |
| 239 | 41 | Daniel Dehennin | « remote » en jargon git, est applicable entre deux branches d’un dépôt local. |
| 240 | 35 | Daniel Dehennin | |
| 241 | 41 | Daniel Dehennin | En pratique, on se positionne sur la branche qui doit intégrer les modifications d’une autre, |
| 242 | 41 | Daniel Dehennin | par exemple une branche publique, et on fusionne la branche privée de développement dans cette branche publique : |
| 243 | 1 | Redmine Admin | |
| 244 | 1 | Redmine Admin | <pre> |
| 245 | 36 | Daniel Dehennin | moi@work:~/src/projet(master)$ git merge mabranche |
| 246 | 1 | Redmine Admin | </pre> |
| 247 | 35 | Daniel Dehennin | |
| 248 | 1 | Redmine Admin | Pour ensuite publier ces modifications par @git push@. |
| 249 | 35 | Daniel Dehennin | |
| 250 | 35 | Daniel Dehennin | Ceci induit les mêmes inconvénients que l’utilisation des pull. |
| 251 | 35 | Daniel Dehennin | |
| 252 | 41 | Daniel Dehennin | Lorsque l’on passe du temps à travailler sur une branche privée, |
| 253 | 41 | Daniel Dehennin | il est tentant de « fusionner » régulièrement une branche publique de référence, afin de se mettre à jour. |
| 254 | 35 | Daniel Dehennin | |
| 255 | 41 | Daniel Dehennin | Mais cette pratique ne fait que rendre illisible l’histoire privée de cette branche. |
| 256 | 35 | Daniel Dehennin | |
| 257 | 35 | Daniel Dehennin | Cela rend très difficile la relecture de chaque modification apportée |
| 258 | 35 | Daniel Dehennin | par cette branche car son histoire n’est plus simplement une suite |
| 259 | 1 | Redmine Admin | logique d’étapes afin d’arriver à un résultat voulu. |
| 260 | 35 | Daniel Dehennin | |
| 261 | 1 | Redmine Admin | h2. On ne construit que sur les épaules de géants |
| 262 | 35 | Daniel Dehennin | |
| 263 | 35 | Daniel Dehennin | Il existe une autre approche à la problématique généalogique des |
| 264 | 1 | Redmine Admin | commits, nommé dans la littérature « rebase workflow ». |
| 265 | 35 | Daniel Dehennin | |
| 266 | 35 | Daniel Dehennin | Ce principe utilise la réécriture de l’historique, par conséquent, |
| 267 | 1 | Redmine Admin | elle ne peut être utilisée que sur des commits non publiés. |
| 268 | 35 | Daniel Dehennin | |
| 269 | 1 | Redmine Admin | Le principe est le même que le greffage en botanique : |
| 270 | 35 | Daniel Dehennin | |
| 271 | 35 | Daniel Dehennin | # On coupe la branche ; |
| 272 | 1 | Redmine Admin | # On la greffe sur une autre. |
| 273 | 35 | Daniel Dehennin | |
| 274 | 45 | Fabrice Barconnière | En pratique, c’est surtout utilisé pour préparer l’intégration de nos |
| 275 | 1 | Redmine Admin | modifications dans une branche publique. |
| 276 | 35 | Daniel Dehennin | |
| 277 | 1 | Redmine Admin | C’est un peu le miroir du « merge workflow ». |
| 278 | 35 | Daniel Dehennin | |
| 279 | 35 | Daniel Dehennin | Dans le « merge workflow », la fusion se fait sur la branche publique |
| 280 | 1 | Redmine Admin | et les conflits sont gérés dans l’histoire de la branche publique. |
| 281 | 35 | Daniel Dehennin | |
| 282 | 35 | Daniel Dehennin | Dans le « rebase workflow », c’est l’inverse, tout se fait dans la |
| 283 | 1 | Redmine Admin | branche que l’on souhaite intégrer à la branche publique. |
| 284 | 35 | Daniel Dehennin | |
| 285 | 35 | Daniel Dehennin | La procédure est décomposée comme suit : |
| 286 | 35 | Daniel Dehennin | |
| 287 | 35 | Daniel Dehennin | # Mise de côté de tous les commits de la branche depuis sa création : |
| 288 | 35 | Daniel Dehennin | on revient dans le tronc de développement (branche privée) à la |
| 289 | 35 | Daniel Dehennin | version sur laquelle notre branche est basée ; |
| 290 | 35 | Daniel Dehennin | # Intégration de tous les changements de la branche publique survenus |
| 291 | 35 | Daniel Dehennin | depuis ; |
| 292 | 35 | Daniel Dehennin | # Application de tous les commits mis de côté, il faut gérer les |
| 293 | 35 | Daniel Dehennin | éventuels conflits. |
| 294 | 35 | Daniel Dehennin | |
| 295 | 35 | Daniel Dehennin | Avant la procédure, la branche privée était basée sur la branche |
| 296 | 45 | Fabrice Barconnière | publique à un certain instant dans le passé. |
| 297 | 35 | Daniel Dehennin | |
| 298 | 35 | Daniel Dehennin | Après la procédure, la branche privée est basée sur le dernier commit |
| 299 | 35 | Daniel Dehennin | de la branche publique. |
| 300 | 35 | Daniel Dehennin | |
| 301 | 35 | Daniel Dehennin | On a donc changé la base de la branche, d’où le nom de cette méthode. |
| 302 | 35 | Daniel Dehennin | |
| 303 | 35 | Daniel Dehennin | Tout cela se fait simplement par : |
| 304 | 1 | Redmine Admin | |
| 305 | 35 | Daniel Dehennin | <pre> |
| 306 | 1 | Redmine Admin | moi@work:~/src/projet(mabranche)$ git rebase master |
| 307 | 1 | Redmine Admin | </pre> |
| 308 | 35 | Daniel Dehennin | |
| 309 | 35 | Daniel Dehennin | Il est possible de faire fréquemment des rebases des branches privées |
| 310 | 45 | Fabrice Barconnière | par rapport à la branche publique où seront intégrées les |
| 311 | 1 | Redmine Admin | modifications. |
| 312 | 35 | Daniel Dehennin | |
| 313 | 35 | Daniel Dehennin | On minimise ainsi les conflits ou, plus précisément, on les dilue dans |
| 314 | 1 | Redmine Admin | le temps. |
| 315 | 35 | Daniel Dehennin | |
| 316 | 35 | Daniel Dehennin | Ce principe de rebase est à utiliser, au moins avant l’intégration à |
| 317 | 35 | Daniel Dehennin | la branche publique, afin d'avoir une histoire plus propre de la |
| 318 | 1 | Redmine Admin | branche et ce en fusionnant certains commits. |
| 319 | 35 | Daniel Dehennin | |
| 320 | 45 | Fabrice Barconnière | Dans ce cas on ne rebase pas par rapport à une branche publique, mais |
| 321 | 19 | Joël Cuissinat | par rapport à un commit de la branche privée. |
| 322 | 35 | Daniel Dehennin | |
| 323 | 35 | Daniel Dehennin | Par exemple, ne pas avoir un commit ajoutant une fonctionnalité et les |
| 324 | 19 | Joël Cuissinat | 30 suivants qui corrigent les inévitables erreurs typographiques. |
| 325 | 19 | Joël Cuissinat | |
| 326 | 35 | Daniel Dehennin | |
| 327 | 1 | Redmine Admin | h1. « Le blabla c’est bien, mais en pratique ? » par moi©®™ |
| 328 | 35 | Daniel Dehennin | |
| 329 | 1 | Redmine Admin | h2. Puisque je vous dis que les branches ça ne coûte rien ! |
| 330 | 35 | Daniel Dehennin | |
| 331 | 36 | Daniel Dehennin | Dans git, une branche est simplement un fichier dans l’arborescence du |
| 332 | 1 | Redmine Admin | répertoire @.git/refs/heads/@. |
| 333 | 35 | Daniel Dehennin | |
| 334 | 35 | Daniel Dehennin | Ce fichier contient l’identifiant du dernier commit de cette branche, |
| 335 | 35 | Daniel Dehennin | c’est le "SHA1":http://fr.wikipedia.org/wiki/SHA1 du contenu de l’objet (les détails sont accessibles dans |
| 336 | 1 | Redmine Admin | "Les tripes de Git":http://progit.org/book/fr/ch9-0.html). |
| 337 | 35 | Daniel Dehennin | |
| 338 | 36 | Daniel Dehennin | L’identifiant de commit référence un fichier dans l’arborescence du |
| 339 | 1 | Redmine Admin | répertoire @.git/objects/@, avec : |
| 340 | 35 | Daniel Dehennin | |
| 341 | 35 | Daniel Dehennin | * les deux premiers caractères (1 octet noté en hexadécimal) sont le |
| 342 | 1 | Redmine Admin | nom d’un sous répertoire ; |
| 343 | 1 | Redmine Admin | * le reste des caractères sont le nom du fichier. |
| 344 | 35 | Daniel Dehennin | |
| 345 | 35 | Daniel Dehennin | Connaître l’identifiant du dernier commit est suffisant pour remonter |
| 346 | 1 | Redmine Admin | l’arbre généalogique. |
| 347 | 35 | Daniel Dehennin | |
| 348 | 35 | Daniel Dehennin | Faire une nouvelle branche se résume donc à créer un fichier ne |
| 349 | 1 | Redmine Admin | contenant qu’un identifiant. |
| 350 | 35 | Daniel Dehennin | |
| 351 | 1 | Redmine Admin | On créé une branche dédiée pour le développement à faire : |
| 352 | 35 | Daniel Dehennin | <pre> |
| 353 | 1 | Redmine Admin | moi@work:~/src/projet(master)$ git checkout -b issue/42 master |
| 354 | 1 | Redmine Admin | </pre> |
| 355 | 35 | Daniel Dehennin | |
| 356 | 1 | Redmine Admin | h2. Le clonage déontologiquement correcte |
| 357 | 35 | Daniel Dehennin | |
| 358 | 35 | Daniel Dehennin | Afin de tester nos modifications avant publication, nous pouvons |
| 359 | 35 | Daniel Dehennin | copier les fichiers sur une machine de test, par quelque moyen que ce |
| 360 | 1 | Redmine Admin | soit. |
| 361 | 35 | Daniel Dehennin | |
| 362 | 35 | Daniel Dehennin | Un de ces moyens, et le plus simple dans notre cas, est d’utiliser |
| 363 | 1 | Redmine Admin | git. |
| 364 | 35 | Daniel Dehennin | |
| 365 | 1 | Redmine Admin | Étant donné que : |
| 366 | 35 | Daniel Dehennin | |
| 367 | 35 | Daniel Dehennin | * Nous souhaitons tester les modifications apportées par le |
| 368 | 1 | Redmine Admin | développement enregistré dans une branche non publiée ; |
| 369 | 35 | Daniel Dehennin | * Nous ne souhaitons pas publier cette branche privée tant que tout ne |
| 370 | 1 | Redmine Admin | sera pas propre ; |
| 371 | 35 | Daniel Dehennin | |
| 372 | 1 | Redmine Admin | Nous allons créer une copie conforme de notre dépôt, sur la machine de test. |
| 373 | 35 | Daniel Dehennin | |
| 374 | 1 | Redmine Admin | Le fonctionnement est simple, un dépôt git, qu’il soit sur un serveur |
| 375 | 1 | Redmine Admin | http ou dans notre répertoire, peut servir de base à un clone. |
| 376 | 35 | Daniel Dehennin | |
| 377 | 1 | Redmine Admin | Et un clone, ça peut se faire par "SSH":http://fr.wikipedia.org/wiki/SSH. |
| 378 | 35 | Daniel Dehennin | |
| 379 | 2 | samuel morin | Nous avons besoin : |
| 380 | 35 | Daniel Dehennin | |
| 381 | 1 | Redmine Admin | * D’une machine de test ; |
| 382 | 53 | Daniel Dehennin | * D’un accès "SSH":http://fr.wikipedia.org/wiki/SSH sur cette machine ; |
| 383 | 53 | Daniel Dehennin | * De l’outil git installé sur cette machine. |
| 384 | 35 | Daniel Dehennin | |
| 385 | 35 | Daniel Dehennin | Aucun fichier ne sera éditer sur cette machine, cela évite de |
| 386 | 1 | Redmine Admin | s’éparpiller. |
| 387 | 35 | Daniel Dehennin | |
| 388 | 35 | Daniel Dehennin | Nous mettrons à jour ce dépôt par des pull, ce qui ne posera aucun |
| 389 | 35 | Daniel Dehennin | soucis comme expliqué plus haut du fait qu’il n’y aura aucune |
| 390 | 1 | Redmine Admin | modification locale à la machine de test. |
| 391 | 1 | Redmine Admin | |
| 392 | 35 | Daniel Dehennin | <pre> |
| 393 | 35 | Daniel Dehennin | moi@work:~/src/projet(master)$ ssh user@test-machine |
| 394 | 35 | Daniel Dehennin | user@test-machine:~$ git clone ssh://moi@work/home/moi/src/projet && cd projet |
| 395 | 1 | Redmine Admin | user@test-machine:~/projet(master)$ git checkout -b issue/42 origin/issue/42 |
| 396 | 1 | Redmine Admin | user@test-machine:~/projet(issue/42)$ # On est prêt |
| 397 | 1 | Redmine Admin | </pre> |
| 398 | 1 | Redmine Admin | |
| 399 | 1 | Redmine Admin | On garde un shell sur la machine de test, on y reviendra souvent, à |
| 400 | 1 | Redmine Admin | moins d’être très fort et de tout réussir du premier coup. |
| 401 | 35 | Daniel Dehennin | |
| 402 | 1 | Redmine Admin | h2. Les commits, c’est radioactif ? |
| 403 | 1 | Redmine Admin | |
| 404 | 1 | Redmine Admin | Un commit, c’est un instantané du code à un instant « T ». |
| 405 | 1 | Redmine Admin | |
| 406 | 1 | Redmine Admin | Si nous souhaitons tester l’impact de chaque commit sur un projet, il |
| 407 | 1 | Redmine Admin | est préférable que chacun d’eux soit fonctionnel. |
| 408 | 1 | Redmine Admin | |
| 409 | 1 | Redmine Admin | Par exemple, si on modifie le nom d’une fonction ou d’une variable, on |
| 410 | 46 | Fabrice Barconnière | doit, dans le même commit, modifier toutes les utilisations de l’ancien |
| 411 | 35 | Daniel Dehennin | nom. |
| 412 | 1 | Redmine Admin | |
| 413 | 35 | Daniel Dehennin | Chaque commit se doit d’être le plus « atomique » possible. |
| 414 | 1 | Redmine Admin | |
| 415 | 1 | Redmine Admin | h2. Cycle de développement et tests |
| 416 | 1 | Redmine Admin | |
| 417 | 1 | Redmine Admin | # On code : |
| 418 | 1 | Redmine Admin | <pre> |
| 419 | 47 | Daniel Dehennin | moi@work:~/src/projet(issue/42)$ ${EDITOR} src/bidule.py |
| 420 | 35 | Daniel Dehennin | moi@work:~/src/projet(issue/42)$ git add src/bidule.py |
| 421 | 35 | Daniel Dehennin | moi@work:~/src/projet(issue/42)$ git commit |
| 422 | 35 | Daniel Dehennin | </pre> |
| 423 | 35 | Daniel Dehennin | # On nettoie la machine de test : |
| 424 | 40 | Daniel Dehennin | <pre> |
| 425 | 40 | Daniel Dehennin | user@test-machine:~/projet(issue/42)$ make uninstall |
| 426 | 40 | Daniel Dehennin | </pre> |
| 427 | 40 | Daniel Dehennin | # On met à jour le dépôt de la machine de test : |
| 428 | 35 | Daniel Dehennin | <pre> |
| 429 | 40 | Daniel Dehennin | user@test-machine:~/projet(issue/42)$ git pull origin |
| 430 | 40 | Daniel Dehennin | </pre> |
| 431 | 40 | Daniel Dehennin | # On met en place la nouvelle version du code à tester : |
| 432 | 35 | Daniel Dehennin | <pre> |
| 433 | 40 | Daniel Dehennin | user@test-machine:~/projet(issue/42)$ make install |
| 434 | 40 | Daniel Dehennin | </pre> |
| 435 | 48 | Daniel Dehennin | # On test, si des problèmes persistent, on boucle sur 1 et on peut même utiliser un [[GitTrucsEtAstuces#Tu-balises-quand-tu-commit|petit truc]] pour s’y retrouver dans toutes ces itérations. |
| 436 | 35 | Daniel Dehennin | |
| 437 | 40 | Daniel Dehennin | h2. Publication du développement |
| 438 | 40 | Daniel Dehennin | |
| 439 | 41 | Daniel Dehennin | # On détermine le nombre de modification de notre branche par rapport à la branche « master »: |
| 440 | 35 | Daniel Dehennin | <pre> |
| 441 | 41 | Daniel Dehennin | moi@work:~/src/projet(issue/42)$ git log --oneline master..HEAD | wc -l |
| 442 | 41 | Daniel Dehennin | 5 |
| 443 | 41 | Daniel Dehennin | </pre> |
| 444 | 41 | Daniel Dehennin | # On nettoie notre histoire privée, dans notre exemple, à partir du 5e commit avant la fin: |
| 445 | 41 | Daniel Dehennin | <pre> |
| 446 | 41 | Daniel Dehennin | moi@work:~/src/projet(issue/42)$ git rebase -i HEAD~5 |
| 447 | 40 | Daniel Dehennin | </pre> |
| 448 | 35 | Daniel Dehennin | # On rebase sur la dernière version de la branche publique : |
| 449 | 40 | Daniel Dehennin | <pre> |
| 450 | 40 | Daniel Dehennin | moi@work:~/src/projet(issue/42)$ git fetch origin |
| 451 | 40 | Daniel Dehennin | moi@work:~/src/projet(issue/42)$ git rebase origin/master |
| 452 | 40 | Daniel Dehennin | </pre> |
| 453 | 35 | Daniel Dehennin | # On intègre à la branche publique : |
| 454 | 40 | Daniel Dehennin | <pre> |
| 455 | 40 | Daniel Dehennin | moi@work:~/src/projet(issue/42)$ git checkout master |
| 456 | 40 | Daniel Dehennin | moi@work:~/src/projet(master)$ git merge issue/42 |
| 457 | 40 | Daniel Dehennin | </pre> |
| 458 | 56 | Daniel Dehennin | # On [[GitTagging|tag]] un numéro de version, dans cet exemple, nous utilisons un "timestamp":http://fr.wikipedia.org/wiki/Timestamp : |
| 459 | 40 | Daniel Dehennin | <pre> |
| 460 | 40 | Daniel Dehennin | moi@work:~/src/projet(master)$ git tag -s -m "release/$(date +%Y%m%d.%H%M)" release/$(date +%Y%m%d.%H%M) |
| 461 | 40 | Daniel Dehennin | </pre> |
| 462 | 35 | Daniel Dehennin | # On publie : |
| 463 | 40 | Daniel Dehennin | <pre> |
| 464 | 40 | Daniel Dehennin | moi@work:~/src/projet(master)$ git push origin |
| 465 | 40 | Daniel Dehennin | </pre> |
| 466 | 35 | Daniel Dehennin | |
| 467 | 35 | Daniel Dehennin | |
| 468 | 35 | Daniel Dehennin | h1. Webographie |
| 469 | 52 | Daniel Dehennin | |
| 470 | 50 | Daniel Dehennin | * "Afficher le status de git dans la ligne de commande BASH":http://volnitsky.com/project/git-prompt/ |
| 471 | 50 | Daniel Dehennin | * "Le prompt Bash qui change la vie avec Git":http://www.git-attitude.fr/2010/07/14/le-prompt-bash-qui-change-la-vie-avec-git/ |
| 472 | 43 | Daniel Dehennin | * "Avoiding Git Disasters: A Gory Story":http://www.randyfay.com/node/89 |
| 473 | 35 | Daniel Dehennin | * "A rebase workflow":http://www.randyfay.com/node/91 |
| 474 | 35 | Daniel Dehennin | * "Simpler Rebasing (avoiding unintentional merge commits)":http://randyfay.com/node/103 |
| 475 | 35 | Daniel Dehennin | * "A git workflow for agile teams":http://reinh.com/blog/2009/03/02/a-git-workflow-for-agile-teams.html |
| 476 | 35 | Daniel Dehennin | * "The case for git rebase":http://darwinweb.net/articles/the-case-for-git-rebase |
| 477 | 35 | Daniel Dehennin | * "Pro git book":http://progit.org/book/ch5-3.html |
| 478 | 35 | Daniel Dehennin | * "Maintaining a project":http://progit.org/book/ch5-3.html |
| 479 | 35 | Daniel Dehennin | * "Packaging software using Git":http://www.golden-gryphon.com/software/misc/packaging.html |
| 480 | 1 | Redmine Admin | * "Packaging with git":http://wiki.debian.org/PackagingWithGit/ |
| 481 | 55 | Daniel Dehennin | * "Software Branching and Parallel Universes":http://www.codinghorror.com/blog/2007/10/software-branching-and-parallel-universes.html |
| 482 | 57 | Daniel Dehennin | * "Anticipating Git 1.7.10":http://git-blame.blogspot.com/2012/02/anticipating-git-1710.html |