1 // -*- mode: doc; mode: flyspell; coding: utf-8; fill-column: 79; -*-
2 == Appendix A: Les lacunes de Git ==
4 Git présente quelques problèmes que j'ai soigneusement cachés. Certains peuvent
5 être résolus par des scripts et des hooks, d'autres nécessitent une
6 réorganisation ou une redéfinition du projet et pour les quelques rares ennuis
7 restants, il vous suffit d'attendre. Ou mieux encore, de donner un coup de
10 === Les faiblesses de SHA1 ===
12 Avec le temps, les spécialistes de cryptographie découvrent de plus en plus de
13 faiblesses de SHA1. À ce jour, la découverte de collisions d'empreintes semble
14 à la portée d'organisations bien dotée. Et d'ici quelques années, peut-être que
15 même un simple PC aura assez de puissance de calcul pour corrompre de manière
16 indétectable un dépôt Git.
18 Heureusement Git aura migrer vers une fonction de calcul d'empreintes de
19 meilleure qualité avant que de futures recherches détruisent SHA1.
21 === Microsoft Windows ===
23 Git sur Microsoft Windows peut être jugé encombrant :
25 - http://cygwin.com/[Cygwin] est un environnement de type Linux dans Windows
26 proposant http://cygwin.com/packages/git/[un portage de Git].
28 - http://code.google.com/p/msysgit/[Git on MSys] est un autre choix nécessitant
29 beaucoup moins de place. Néanmoins quelques commandes doivent encore être
32 === Des fichiers sans relation ===
34 Si votre projet est très gros et contient de nombreux fichiers sans relation
35 entre eux et changeant constamment, Git peut être plus défavorisé que d'autres
36 systèmes puisque les fichiers pris séparément ne sont pas pistés. Git piste les
37 changement de l'ensemble du projet, ce qui est habituellement bénéfique.
39 Une solution consiste à découper votre projet en plusieurs parties, chacune
40 réunissant des fichiers en relation entre eux. Utilisez *git submodule* si vous
41 souhaitez conserver tout cela dans un seul dossier.
43 === Qui modifie quoi ? ===
45 Certains systèmes de gestion de versions vous oblige à marquer explicitement un
46 fichier avant de pouvoir le modifier. Bien que particulièrement ennuyeux
47 puisque pouvant impliquer une communication avec un serveur central, cela
48 présente deux avantages :
50 1. Les diffs sont plus rapides puisque seuls les fichiers marqués doivent
53 2. Quelqu'un peut savoir qui travaille sur un fichier en demandant au serveur
54 central qui l'a marqué pour modification.
56 Avec quelques scripts appropriés, vous pouvez obtenir la même chose avec
57 Git. Cela nécessite la coopération du développeur qui doit exécuter un script
58 particulier avant toute modification d'un fichier.
60 === L'historique d'un fichier ===
62 Puisque Git enregistre les modifications de manière globale au projet, la
63 reconstruction de l'historique d'un seul fichier demande plus de travail
64 qu'avec un système de gestion de versions qui traque les fichiers
67 Ce surplus est généralement négligeable et en vaut la peine puisque cela permet
68 aux autres opérations d'être incroyablement efficaces. Par exemple, `git
69 checkout` est plus rapide que `cp -a` et un delta de versions globale au projet
70 se compresse mieux qu'une collection de delta fichier par fichier.
72 === Le clone initial ===
74 La création d'un clone est plus coûteuse que l'extraction de code des autres
75 systèmes quand il y a un historique conséquent.
77 Ce coût initial s'avère payant dans le temps puisque la plupart des opérations
78 futures s'effectueront rapidement et hors-ligne. En revanche, dans certains
79 situations, il est préférable de créer un clone superficiel grâce à l'option
80 `--depth` (qui limite la profondeur de l'historique). C'est plus rapide mais le
81 clone ainsi créé offre des fonctionnalités réduites.
83 === Les projets versatiles ===
85 Git a été conçu pour être rapide au regard de la taille des changements. Les
86 humains font de petits changement de version en version. Une correction de bug
87 en une ligne ici, une nouvelle fonctionnalité là, un commentaire amendé
88 ailleurs... Mais si vous fichiers changent radicalement à chaque révision
89 alors, à chaque commit, votre historique grossit d'un poids équivalent à celui
92 Il n'y a rien que puisse faire un système de gestion de versions pour éviter
93 cela, mais les utilisateurs de Git en souffrent plus puisque chaque clone
94 contient habituellement l'historique complet.
96 Il faut rechercher les raisons de ces changements radicaux. Peut-être faut-il
97 changer les formats des fichiers. Des modifications mineures ne devraient
98 modifier que très peu de chose dans très peu de fichiers.
100 Peut-être une base données ou une solution d'archivage est-elle plus adaptée
101 solution qu'un système de gestion de versions. À titre d'exemple, un système de
102 gestion de versions n'est certainement pas bien taillé pour gérer des photos prises
103 périodiquement par une webcam.
105 Si les fichiers doivent absolument se transformer constamment et s'il faut
106 absolument les gérer par version, une possibilité peut être une utilisation
107 centralisée d'un dépôt Git. Chacun ne crée qu'un clone superficiel ne contenant
108 qu'un historique récent voire inexistant du projet. Évidemment de nombreux
109 outils Git ne seront plus utilisables et les corrections devront être fournies
110 sous forme de patches. C'est sans doute acceptable sans en savoir plus sur les
111 raisons réelles de la conservation de l'historique de nombreux fichiers
114 Un autre exemple serait un projet dépendant d'un firmware qui prend la forme
115 d'un énorme fichier binaire. L'historique de ce firmware n'intéresse pas les
116 utilisateur et les mises à jour se compressent difficilement et donc les
117 révisions de ce firmware vont faire grossir inutilement le dépôt.
119 Dans ce cas, le code source devrait être stocké dans le dépôt Git et les
120 fichiers binaires conservés séparément. Pour rendre la vie meilleure, on peut
121 distribuer un script qui utilisera un clone Git pour le code et rsync ou un
122 clone Git superficiel pour le firmware.
124 === Compteur global ===
126 Certains systèmes de gestion de versions centralisés gère un entier positif qui
127 augmente à chaque commit accepté. Git fait référence à un changement par son
128 empreinte ce qui est mieux pour de nombreuses raisons.
130 Mais certains aiment voir ce compteur. Par chance, il est très facile d'écrire
131 un script qui se déclenchera à chaque mise à jour du dépôt Git central et
132 incrémentera un compteur, peut-être dans un tag, qu'il associera à l'empreinte
135 Chaque clone peut gérer un tel compteur mais c'est probablement sans intérêt
136 puisque seul le compteur du dépôt central compte.
138 === Les dossiers vides ===
140 Les sous-dossiers vides ne peuvent pas être suivis. Placez-y des fichiers
141 sans intérêt pour remédier à ce problème.
143 Cette limitation n'est pas une fatalité due à la conception de Git mais un
144 choix de l'implémentation actuelle. Avec un peu de chance, si de nombreux
145 utilisateurs le demandent, cette fonctionnalité pourrait être ajoutée.
147 === Le premier commit ===
149 Un informaticien typique compte à partir de 0 plutôt que de 1. Malheureusement,
150 concernant les commits, Git n'adhère pas à cette convention. Plusieurs
151 commandes ne fonctionnent pas avant le tout premier commit. De plus, certains
152 cas limites doivent être gérés spécifiquement : par exemple, un rebasage vers
153 une branche avec un commit initial différent.
155 Git bénéficierait à définir le commit zéro : dès la création d'un dépôt, HEAD
156 serait défini comme la chaîne contenant 20 octets nuls. Ce commit spécial
157 représenterait un arbre vide, sans parent, qui serait présent dans tous les
160 Ainsi l'appel à git log, par exemple, pourrait indiquer à l'utilisateur
161 qu'aucun commit n'a été fait au lieu de se terminer par une erreur fatale. Il
162 en serait de même pour les autres outils.
164 Le commit initial serait un descendant implicite de ce commit zéro.
166 Mais ce n'est pas le cas et donc certains problèmes peuvent se poser. Si
167 plusieurs branches avec des commits initiaux différents sont fusionnées alors
168 le rebasage du résultat requiert de nombreuses interventions manuelles.
170 === Bizarreries de l'interface ===
172 Étant donné deux commits A et B, le sens des expressions "A..B" et "A...B"
173 diffère selon que la commande attend deux extrémités ou un intervalle. Voir
174 *git help diff* et *git help rev-parse*.
176 // LocalWords: Appendix Git hooks SHA PC indétectable Microsoft Windows
177 // LocalWords: Cygwin à-la-Linux MSys git submodule diffs checkout cp depth
178 // LocalWords: bug faut-il webcam patches firmware rsync tag Placez-y log
179 // LocalWords: l'implémentation commits rebasage HEAD help diff rev-parse