Remarque: l'une des plus grandes différences entre Git et Mercurial est la présence explicite de l' index ou de la zone de préparation .
De Mercurial for Git User :
Git est le seul DistributedSCM qui expose le concept d'index ou de zone intermédiaire. Les autres peuvent l'implémenter et le masquer, mais dans aucun autre cas l'utilisateur n'est au courant ni n'a à s'en occuper.
L'équivalent approximatif de Mercurial est le DirState
, qui contrôle les informations d'état de la copie de travail pour déterminer les fichiers à inclure dans le prochain commit. Mais dans tous les cas, ce fichier est géré automatiquement.
De plus, il est possible d'être plus sélectif au moment de la validation en spécifiant les fichiers que vous souhaitez valider sur la ligne de commande ou en utilisant le RecordExtension
.
Si vous vous sentez mal à l'aise avec l'index, vous changez pour le mieux ;-)
L'astuce est que vous devez vraiment comprendre l'index pour exploiter pleinement Git. Comme nous le rappelle alors cet article de mai 2006 (et c'est toujours vrai maintenant):
"Si vous refusez l'index, vous refusez vraiment git lui-même."
Maintenant, cet article contient de nombreuses commandes qui sont désormais plus simples à utiliser (ne vous fiez donc pas trop à son contenu;)), mais l'idée générale demeure:
Vous travaillez sur une nouvelle fonctionnalité et commencez à apporter des modifications mineures à un fichier.
# working, add a few lines
$ git add myFile
# working, another minor modification
$ git add myFile
À ce stade, votre prochain commit embarquera 2 modifications mineures dans la branche actuelle
# working, making major modification for the new features
# ... damn! I cannot commit all this in the current branch: nothing would work
$ git commit
Enregistre uniquement les modifications ajoutées à la zone de préparation (index) à ce stade, et non les modifications majeures actuellement visibles dans votre répertoire de travail.
$ git branch newFeature_Branch
$ git add myFile
Le prochain commit enregistrera tous les autres changements majeurs dans la nouvelle branche 'newFrature_Branch'.
Désormais, l'ajout interactif ou même le fractionnement d'un commit sont des fonctionnalités disponibles avec Mercurial, via la hg record
commande ' ' ou d'autres extensions: vous devrez installer RecordExtension
, ou le CrecordExtension
.
Mais cela ne fait pas partie du flux de travail normal de Mercurial.
Git considère un commit comme une série de " modifications de contenu de fichier " et vous permet d'ajouter ces modifications une par une.
Vous devriez étudier cette fonctionnalité et ses conséquences: la plus grande partie de la puissance de Git (comme la possibilité de facilement annuler une fusion (ou couper en deux le problème, ou annuler un commit) , contrairement à Mercurial ) vient de ce paradigme du «contenu de fichier».
tonfa (dans le profil: "Hg dev, pythonist": chiffres ...) intervient, dans les commentaires:
Il n'y a rien de fondamentalement "git-ish" dans l'index, hg pourrait utiliser un index s'il était jugé utile, en fait mq
ou en shelve
faisait déjà partie.
Oh mec. On y va encore une fois.
Premièrement, je ne suis pas ici pour rendre un outil meilleur qu'un autre. Je trouve Hg génial, très intuitif, avec un bon support (notamment sur Windows, ma plateforme principale, bien que je travaille aussi sous Linux et Solaris8 ou 10).
L'index est en fait au centre de la manière dont Linus Torvalds travaille avec un VCS :
Git a utilisé des mises à jour d'index explicites à partir du jour 1, avant même d'effectuer la première fusion. C'est simplement comme ça que j'ai toujours travaillé. Je tendance à avoir des arbres sales, avec une pièce au hasard dans mon arbre que je ne pas envie de commettre, parce qu'il est juste une mise à jour Makefile pour la prochaine version
Maintenant, la combinaison de l'index (qui n'est pas une notion vue uniquement dans Git) et du paradigme "content is king" le rend assez unique et "git-ish" :
git est un suivi de contenu , et un nom de fichier n'a aucune signification à moins d'être associé à son contenu. Par conséquent, le seul comportement sain pour git add filename est d'ajouter le contenu du fichier ainsi que son nom à l'index.
Remarque: le "contenu", ici, est défini comme suit :
L'index de Git est essentiellement défini comme
- suffisant pour contenir le " contenu " total de l'arborescence (et cela inclut toutes les métadonnées: le nom de fichier, le mode et le contenu du fichier font tous partie du "contenu", et ils n'ont aucun sens en eux-mêmes! )
- des informations "statistiques" supplémentaires pour permettre les optimisations de comparaison de systèmes de fichiers évidentes et triviales (mais extrêmement importantes!).
Vous devriez donc vraiment voir l'index comme étant le contenu .
Le contenu n'est pas le "nom de fichier" ou le "contenu du fichier" en tant que parties distinctes. Vous ne pouvez vraiment pas séparer les deux .
Les noms de fichiers en eux-mêmes n'ont aucun sens (ils doivent également avoir un contenu de fichier), et le contenu de fichier en lui-même est également insensé (vous devez savoir comment y accéder).
Ce que j'essaie de dire, c'est que git ne vous permet fondamentalement pas de voir un nom de fichier sans son contenu. Toute la notion est insensée et non valable. Cela n'a aucun rapport avec la «réalité».
D'après la FAQ , les principaux avantages sont:
- s'engager avec une granularité fine
- vous aider à conserver une modification non validée dans votre arbre pendant une période raisonnablement longue
- effectuez plusieurs petites étapes pour un commit, vérifiez ce que vous avez fait
git diff
et validez chaque petite étape avec git add
ou git add -u
.
- permet une excellente gestion des conflits de fusion:
git diff --base
, git diff --ours
, git diff --theirs
.
- permet
git commit --amend
de modifier uniquement le message du journal si l'index n'a pas été modifié entre-temps
Je pense personnellement que ce comportement ne devrait pas être le comportement par défaut, vous voulez que les gens commettent quelque chose qui est testé ou au moins compilé
Bien que vous ayez raison en général (à propos de la partie "testée ou compilée"), la façon dont Git vous permet de créer des branches et de fusionner (sélection ou rebasage) vous permet de vous engager aussi souvent que vous le souhaitez dans une branche privée temporaire (poussée uniquement vers un référentiel de "sauvegarde" distant), tout en refaisant ces "commits laids" sur une branche publique, avec tous les bons tests en place.