web-dev-qa-db-fra.com

Quand utiliser l'option de fusion '--no-ff' dans Git

n modèle de branchement Git réussi recommande d'utiliser --no-ff lors de la fusion de branches:

Le --no-ff flag fait que la fusion crée toujours un nouvel objet de validation, même si la fusion peut être effectuée avec une avance rapide. Cela évite de perdre des informations sur l'existence historique d'une branche de fonctionnalité et regroupe toutes les validations qui ont ajouté la fonctionnalité ensemble. […]

Oui, cela créera quelques autres objets de validation (vides), mais le gain est beaucoup plus important que ce coût. Malheureusement, je n'ai pas trouvé de moyen de faire --no-ff le comportement par défaut de git merge pour le moment, mais il devrait vraiment l'être.

Comprendre le workflow Git , cependant, recommande de ne pas utiliser --no-ff:

Vous ajoutez donc une nouvelle règle: "Lorsque vous fusionnez dans votre branche de fonctionnalité, utilisez –-no-ff pour forcer un nouveau commit. "Cela fait le travail et vous continuez. […]

Le --no-ff le pansement, cassé bisect et blame les mystères sont tous des symptômes que vous utilisez un tournevis comme marteau. […]

Les deux approches semblent raisonnables pour des scénarios différents, mais qu'est-ce qui est considéré comme une "bonne pratique"?

Quand utilisez-vous --no-ff, quand n'en avez-vous pas, pourquoi?

59
Leif

Cela dépend vraiment de ce que vous essayez de faire. Ma règle d'or est que si la fusion "signifie quelque chose", j'utilise l'option --no-ff. Lorsque la fusion ne signifie vraiment rien et que vous avez peut-être utilisé un rebase, il n'y a aucune raison d'utiliser --no-ff

Le truc avec git, c'est que c'est un outil très puissant, et vous pouvez l'utiliser de plusieurs façons - dont la plupart n'ont pas tort. Demander quelle est la "bonne façon" de faire, c'est comme demander quelle est la bonne façon de peindre une image.

Au moins pour moi, c'est un ensemble évolutif de façons dont j'aime le faire, avec des discussions fréquentes au sein de l'équipe sur la façon dont nous voulons collaborer sur le code - à partir de cela, nous essayons de dériver une sorte de standard "comment c'est fait ici", mais c'est juste notre façon de le faire.

44
Tomas

Dans le cas d'une branche terminée avec un seul commit, n'utilisez pas --no-ff, avancez-la rapidement, car l'historique sera beaucoup plus simple et moins encombré. Il est difficile de prétendre que --no-ff vous offre des avantages dans ce cas, car il n'est pas intéressant de voir une branche de développement parallèle avec un seul commit, par rapport à un seul commit dans une ligne séquentielle:

# No fast-forward
$ git merge --no-ff awesome-feature
*   3aa649c Merge branch 'awesome-feature'
|\
| * 35ec88f Add awesome feature
|/
* 89408de Modify feature-001.txt and fix-001.txt
* c1abcde Add feature-003

# versus fast-forward
$ git merge awesome-feature
* 35ec88f Add awesome feature
* 89408de Modify feature-001.txt and fix-001.txt
* c1abcde Add feature-003

Dans le cas d'une branche terminée avec plus d'un seul commit, c'est à vous de décider si vous souhaitez ou non garder le fait que le développement ramifié s'est produit en parallèle vs séquentiel. J'utiliserais probablement --no-ff pour plus d'un commit, juste pour que je puisse voir visuellement ce travail ramifié, et pour que je puisse le manipuler facilement avec un seul git revert -m 1 <sha-of-merge-commit> si je devais.

# No fast-forward
$ git merge --no-ff epic-feature
*   d676897 Merge branch 'epic-feature'
|\
| * ba40d93 Add octocat.txt
| * b09d343 Add bye.txt
| * 75e18c8 Add hello.txt
|/
* 89408de Modify feature-001.txt and fix-001.txt
* c1abcde Add feature-003

# versus fast-forward
$ git merge epic-feature
* ba40d93 Add octocat.txt
* b09d343 Add bye.txt
* 75e18c8 Add hello.txt
* 89408de Modify feature-001.txt and fix-001.txt
* c1abcde Add feature-003

Voyez comment dans ce cas de fusion rapide, sans informations supplémentaires dans les messages de validation eux-mêmes, il est difficile de dire que les 3 dernières validations appartiennent réellement ensemble comme une seule fonctionnalité?

43
user456814

Cela dépend vraiment de votre flux de travail et de la façon dont vous utilisez les branches.

Disons que vous avez un "master" et deux branches de fonctionnalités, "foo" et "bar", en cours de développement.

Dans ce cas, les branches n'existent que pour permettre à différents développeurs de travailler sans conflit, lorsque les fonctionnalités sont terminées, elles doivent être fusionnées en maître, et il n'est pas important de savoir si ces fonctionnalités ont été implémentées dans différentes branches.

Mais vous pourriez avoir un flux de travail différent, si les branches, "foo" et "bar", font référence à des modules indépendants de votre système.

Dans ce cas, certaines validations peuvent modifier des fichiers en dehors de la portée du module. Lorsque vous fusionnez ces deux branches au maître, le journal des fichiers, en dehors du module spécifique, peut devenir déroutant et difficile de savoir d'où viennent ces changements.

Vous devez décider si l’historique de la fusion de la branche est important pour votre flux de travail.

Et après les commentaires, je préfère les rebase et pull --rebase workflow.

2
Jonatan Goebel