670 votes

Pourquoi-ce que git avance fusionne par défaut ?

Venant de mercurial, j'ai utiliser les branches d'organiser des fonctionnalités. Naturellement, je veux voir ce flux de travail dans mon histoire.

J'ai commencé mon nouveau projet à l'aide de git et fini mon premier long métrage. Lors de la fusion de la fonction, j'ai réalisé git utilise fast-forward, c'est à dire qu'il s'applique mes modifications directement sur la branche master, si possible, et oublie de ma branche.

Donc, penser à l'avenir: je suis le seul à travailler sur ce projet. Si j'utilise git par défaut de l'approche (avance rapide de fusion), mon histoire se traduirait par un géant de la branche master. Personne ne sait que j'ai utilisé une branche distincte pour chaque fonction, parce que dans la fin, je vais avoir seulement que le géant de la branche principale. Ne pas que l'air manque de professionnalisme?

Par ce raisonnement, je ne veux pas d'avance rapide, de fusion et ne vois pas pourquoi c'est la valeur par défaut. Ce qui est bon à ce sujet?

738voto

VonC Points 414372

Avance rapide de la fusion de sens que pour une courte durée branches, mais en plus complexe de l'histoire, non d'avance rapide, de la fusion peut rendre l'histoire plus facile à comprendre, et de le rendre plus facile pour rétablir un groupe de commits.

alt text
(À partir de nvie.com, Vincent Driessen, poster "Un succès Git ramification modèle")

Intégrant un fini fonctionnalité à développer

Fini les caractéristiques peuvent être fusionnés dans le fait de développer direction de l'ajouter dans la prochaine version:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff myfeature
Updating ea1b82a..05e9557
(Summary of changes)
$ git branch -d myfeature
Deleted branch myfeature (was 05e9557).
$ git push origin develop

L' --no-ff indicateur provoque la fusion de toujours créer un nouveau commit objet, même si la fusion peut être réalisée avec une avance rapide. Cela évite de perdre des informations sur l'existence historique de la branche, et regroupe tous les commits qui, ensemble, ajout de la fonctionnalité.

Jakub Narębski aussi mentionne la config merge.ff:

Par défaut, Git ne pas créer un supplément de fusion s'engager lors de la fusion d'un commit qui est un descendant du commit courant. Au lieu de cela, l'extrémité de la branche courante est l'avance rapide.
Lorsque la valeur false, cette variable indique à Git pour créer un supplément de fusion s'engager dans un tel cas (équivalent à donner l' --no-ff option de la ligne de commande).
Lorsque la valeur 'only', avance rapide fusionne sont autorisés (équivalent à donner l' --ff-only option de la ligne de commande).


L'avance rapide est la valeur par défaut parce que:

  • de courte durée, les branches sont très faciles à créer et à utiliser dans Git
  • de courte durée branches souvent d'isoler de nombreux s'engage à ce que peut être réorganisé librement à l'intérieur de la branche
  • ces commits sont en fait une partie de la branche principale: une fois réorganisé, la branche principale est l'avance rapide pour les inclure.

Mais si vous prévoyez un processus itératif de flux de travail sur un sujet/branche (c'est à dire, je les fusionner, puis-je revenir à cette branche, et ajouter plus valide), puis il est utile d'inclure uniquement l'opération de fusion dans la branche principale, plutôt que tous les intermédiaires commits de la branche.

Dans ce cas, vous pouvez finir par ce type de fichier de configuration:

[branch "master"]
# This is the list of cmdline options that should be added to git-merge 
# when I merge commits into the master branch.

# The option --no-commit instructs git not to commit the merge
# by default. This allows me to do some final adjustment to the commit log
# message before it gets commited. I often use this to add extra info to
# the merge message or rewrite my local branch names in the commit message
# to branch names that are more understandable to the casual reader of the git log.

# Option --no-ff instructs git to always record a merge commit, even if
# the branch being merged into can be fast-forwarded. This is often the
# case when you create a short-lived topic branch which tracks master, do
# some changes on the topic branch and then merge the changes into the
# master which remained unchanged while you were doing your work on the
# topic branch. In this case the master branch can be fast-forwarded (that
# is the tip of the master branch can be updated to point to the tip of
# the topic branch) and this is what git does by default. With --no-ff
# option set, git creates a real merge commit which records the fact that
# another branch was merged. I find this easier to understand and read in
# the log.

mergeoptions = --no-commit --no-ff

L'OP ajoute dans les commentaires:

Je vois un certain sens, en avance rapide [de courte durée] les branches, mais ce qui en fait l'action par défaut signifie que git suppose que vous... ont souvent [de courte durée] les branches. Est-elle raisonnable?

Jefromi réponses:

Je pense que la durée de vie de branches varie fortement d'un utilisateur à l'autre. Parmi les utilisateurs expérimentés, cependant, il y a probablement une tendance à avoir beaucoup plus de courte durée branches.

Pour moi, une courte durée de vie de la branche est celui que j'ai créer dans le but de rendre une opération plus facile (rebasage, probablement, ou rapide, l'application de correctifs et d'essais), puis supprimez-le immédiatement une fois que je suis fait.
Cela signifie qu'il est probable doit être absorbé par le sujet branche fourchue de, et le thème de la branche seront fusionnés en une seule branche. Personne n'a besoin de savoir ce que j'ai fait à l'interne dans le but de créer la série de commits mise en œuvre de cette fonctionnalité donnée.

Plus généralement, j'ajoute:

cela dépend vraiment de votre processus de développement:

  • si elle est linéaire, une branche de sens.
  • Si vous avez besoin d'isoler des caractéristiques et de travailler sur eux pour une longue période de temps et à plusieurs reprises les fusionner, plusieurs branches du sens.

Voir "Quand devez-vous branche?"

En fait, lorsque vous pensez à l'Mercurial direction de modèle, il est, à sa base, une branche par dépôt (même si vous pouvez créer des têtes anonymes, des signets et même les branches nommées)
Voir "Git et Mercurial - Comparer et de Contraste".

Mercurial, par défaut, utilise anonyme léger codelines, qui, dans sa terminologie sont appelés "têtes".
Git utilise léger nommé branches, avec injective mappage pour mapper les noms de branches dans le dépôt distant à des noms de distance de suivi des branches.
Git "forces" vous nom branches (bien, à l'exception d'un seul sans nom de la branche, qui est un situation appelé un "détaché de la TÊTE"), mais je pense que cela fonctionne mieux avec de la branche lourde les processus tels que le sujet de la branche de flux de travail, sens de plusieurs branches dans un référentiel unique de paradigme.

45voto

Jakub Narębski Points 87537

Permettez-moi de m'étendre un peu sur un VonC's réponse très complète:


Tout d'abord, si je me souviens bien, le fait que Git par défaut ne crée pas de fusion s'engage dans le fast-forward cas est venu de considérer que seule la branche "de l'égalité des référentiels", où mutuelle de traction est utilisé pour synchroniser ces deux référentiels (un flux de travail que vous pouvez trouver comme premier exemple dans la plupart de l'utilisateur de la documentation, y compris "Le Git Manuel de l'Utilisateur" et "Contrôle de Version par Exemple"). Dans ce cas, vous n'utilisez pas de tirer de fusionner entièrement réalisé direction générale, vous l'utiliser pour garder en place avec d'autres travaux. Vous ne voulez pas avoir éphémère et sans importance en fait, lorsque vous arriver à faire une synchronisation enregistrée et stockée dans le dépôt, enregistré pour l'avenir.

Notez que l'utilité de branches et d'avoir de multiples branches dans un seul dépôt est venu que plus tard, avec une utilisation beaucoup plus large de la cité du vatican avec une bonne fusion de soutien, et à essayer les différents fusion à base de flux de travail. C'est pourquoi, par exemple Mercurial initialement pris en charge qu'une seule section par le référentiel (plus anonyme des conseils pour le suivi à distance des branches), comme on le voit dans les anciennes révisions de "Mercurial: The Definitive Guide".


Deuxièmement, en suivant les meilleures pratiques de l'aide de branches, à savoir que les branches doivent tous commencer à partir de la version stable (généralement à partir de la dernière version), pour être en mesure de choisir et de sélectionner les fonctionnalités à inclure en sélectionnant les branches de fusion, vous ne sont généralement pas en avance rapide de la situation... ce qui rend cette question discutable. Vous avez besoin de s'inquiéter à propos de la création d'une véritable fusion et pas rapide vers l'avant lors de la fusion d'une première branche (en supposant que vous ne mettez pas seul-de valider les modifications directement sur le 'master'); tous les autres plus tard fusionne sont bien sûr hors de l'avance rapide de la situation.

HTH

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X