Git workflow | Comparing workflows

Comparaison de workflows

 

Un workflow Git est une recette ou une recommandation expliquant comment utiliser Git pour accomplir une tâche de façon cohérente et productive. Les workflows Git encouragent les utilisateurs à exploiter Git de façon efficace et cohérente. Git procure une grande flexibilité en matière de gestion des changements. Git étant axé sur la flexibilité, il n'existe aucun processus standardisé pour interagir avec lui. Lorsque vous travaillez en équipe sur un projet géré dans Git, il est important de vous assurer que l'équipe est sur la même longueur d'onde quant à la méthode utilisée pour appliquer les changements. Pour vous assurer que c'est le cas, vous devriez développer ou sélectionner un workflow Git accepté par tous. Plusieurs workflows Git publiés pourraient répondre aux besoins de votre équipe. Dans cet article, nous allons voir certaines de ces options de workflow.

Dans la mesure où il peut y avoir différents workflows possibles, il peut s'avérer difficile de savoir quand commencer l'implémentation de Git sur le lieu de travail. Cette page pose les bases en examinant les workflows Git les plus courants pour les équipes de développement.

Lorsque vous la lirez, gardez à l'esprit que ces workflows sont conçus pour servir de références et ne constituent pas des règles concrètes. Nous voulons vous montrer ce qui est possible. Vous pouvez donc combiner différents workflows pour répondre à vos besoins spécifiques.

Qu'est-ce qu'un bon workflow Git ?

Lorsque vous évaluez un workflow pour votre équipe, le plus important est de tenir compte de votre culture. Votre workflow doit améliorer l'efficacité de votre équipe, sans toutefois compromettre la productivité. Voici quelques points à prendre en considération lorsque vous évaluez un workflow Git :

  • Ce workflow s'adapte-t-il à la taille d'équipe ?
  • Est-il facile d'annuler les erreurs avec ce workflow ?
  • Ce workflow impose-t-il une surcharge cognitive inutile à l'équipe ?

Workflow centralisé

git workflow | Central and local repositories

Le workflow centralisé est idéal pour les équipes qui migrent de SVN vers Git. À l'instar de Subversion, le workflow centralisé utilise un dépôt centralisé qui sert de point d'entrée unique pour tous les changements apportés au projet. Au lieu de trunk, la branche de développement par défaut se nomme master, et tous les changements sont commités dans cette branche. Ce workflow ne requiert pas d'autres branches que master.

Migrer vers un système de contrôle de version distribué peut sembler intimidant, mais vous n'avez pas besoin de changer votre workflow existant pour profiter des avantages de Git. Votre équipe peut développer des projets en travaillant de la même manière qu'avec Subversion.

Cependant, l'utilisation de Git pour renforcer votre workflow de développement présente un certain nombre d'avantages par rapport à SVN. Tout d'abord, il fournit à chaque développeur sa propre copie locale du projet global. Cet environnement isolé permet à chaque développeur de travailler sans tenir compte de tous les autres changements apportés à un projet. Il est possible d'ajouter des commits dans le dépôt local et d'ignorer les développements amont jusqu'à ce qu'ils s'avèrent utiles.

En second lieu, vous avez accès au puissant modèle de création de merges et de branches de Git. Contrairement à SVN, les branches Git sont conçues comme un mécanisme de sécurité pour l'intégration du code et le partage des changements entre les dépôts. Le workflow centralisé est similaire aux autres workflows, puisqu'il fait appel à un dépôt distant hébergé côté serveur à partir duquel les développeurs font des push et des pull. Comparé aux autres workflows, le workflow centralisé ne comprend pas de modèle de pull request ou de création de fork défini. Il est généralement plus adapté aux équipes qui migrent de SVN vers Git ainsi qu'aux équipes de petite taille.

Fonctionnement

Les développeurs commencent par cloner le dépôt centralisé. Dans leurs propres copies locales du projet, ils modifient les fichiers et commitent des changements comme ils le feraient avec SVN ; néanmoins, ces nouveaux commits sont stockés localement. Ils sont totalement isolés du dépôt centralisé. Les développeurs peuvent ainsi reporter la synchronisation amont jusqu'à ce qu'ils atteignent un point d'arrêt pratique.

Pour publier les changements dans le projet officiel, les développeurs font un « push » de leur branche master locale vers le dépôt centralisé. Cette opération est similaire à svn commit, à cela près que tous les commits locaux qui n'ont pas encore été intégrés à la branche master centrale sont ajoutés.

Initialiser le dépôt centralisé

Git Workflow: Initialize Central Bare Repository

En premier lieu, un utilisateur doit créer le dépôt centralisé sur un serveur. S'il s'agit d'un nouveau projet, vous pouvez initialiser un dépôt vide. Sinon, vous devez importer un dépôt Git ou SVN existant.

Les dépôts centralisés doivent toujours être des dépôts bruts (ils ne doivent pas avoir de répertoire de travail) et peuvent être créés comme suit :

ssh user@host git init --bare /path/to/repo.git

Assurez-vous d'utiliser un nom d'utilisateur SSH valide pour user, le domaine ou l'adresse IP de votre serveur pour host, et l'emplacement dans lequel vous souhaitez stocker votre dépôt pour /path/to/repo.git. Remarque : l'extension .git est habituellement utilisée pour indiquer que le dépôt est brut.

Dépôts centralisés hébergés

Les dépôts centralisés sont souvent créés par des services d'hébergement Git tiers, comme Bitbucket Cloud ou Bitbucket Server. Le processus d'initialisation d'un dépôt brut abordé ci-dessus est géré pour vous par le service d'hébergement. Celui-ci vous fournit ensuite l'adresse du dépôt centralisé, afin de vous permettre d'y accéder depuis votre dépôt local.

Cloner le dépôt centralisé

Ensuite, chaque développeur crée une copie de tout le projet en local. Cette opération s'effectue via la commande git clone :

git clone ssh://user@host/path/to/repo.git

Lorsque vous clonez un dépôt, Git crée automatiquement un raccourci nommé origin qui pointe vers le dépôt « parent », au cas où vous souhaiteriez interagir avec lui à une étape ultérieure. 

Apporter des changements et commiter

Une fois le dépôt cloné en local, un développeur peut apporter des changements à l'aide du processus de commit Git standard. Si vous n'êtes pas familier de la zone de staging, celle-ci vise à préparer un commit sans avoir à inclure chaque changement dans le répertoire de travail. Ainsi, vous pouvez créer des commits très ciblés, même si vous avez effectué un grand nombre de changements locaux.

git status # Vous affichez l'état du dépôt
git add <fichier> # Vous stagez un fichier
git commit # Vous commitez un fichier </fichier>

N'oubliez pas que, puisque ces commandes créent des commits locaux, Jean peut répéter ce processus autant de fois qu'il le souhaite sans avoir à se soucier de ce qu'il se passe dans le dépôt centralisé. Cela peut s'avérer très utile pour les fonctionnalités volumineuses, qui nécessitent d'être divisées en blocs plus simples.

Faire un push des nouveaux commits vers le dépôt centralisé

Une fois que le dépôt local comprend de nouveaux changements commités, vous devez en faire un push pour les partager avec les autres développeurs travaillant sur le projet.

git push origin master

Cette commande fait un push des nouveaux changements commités vers le dépôt centralisé. Lorsque vous faites un push de changements vers le dépôt centralisé, il est possible que des mises à jour d'un autre développeur, dont il a déjà fait un push, contiennent du code qui entre en conflit avec les vôtres. Git émet alors un message indiquant ce conflit. Dans cette situation, vous devrez d'abord exécuter la commande git pull. Ce scénario de conflit sera développé dans la section suivante.

Gestion des conflits

Le dépôt centralisé représente le projet officiel. L'historique des commits doit donc être considéré comme sacré et immuable. Si les commits locaux d'un développeur diffèrent du dépôt centralisé, Git refusera de faire un push des changements, car cela écraserait les commits officiels.

Git Workflows: Managing conflicts

Dans la mesure où les développeurs peuvent publier leur fonctionnalité, ils doivent faire un fetch des commits centralisés mis à jour et faire un rebase de leurs changements sur ces commits. Cela revient à dire : « Je veux ajouter mes changements à tout ce qui été fait par les autres ». Résultat : un historique parfaitement linéaire, comme dans les workflows SVN traditionnels.

Si des changements apportés en local entrent en conflit direct avec les commits réalisés en amont, Git interrompt le rebase pour vous permettre de résoudre les conflits manuellement. L'avantage de Git est qu'il utilise les commandes git status et git add pour générer des commits et résoudre les conflits de merge. Ainsi, les développeurs débutants peuvent gérer leurs propres merges plus facilement. Avec Git, il est en outre très facile d'abandonner complètement un rebase pour effectuer une nouvelle tentative (ou demander de l'aide) en cas de problème.

Exemple

Examinons étape par étape comment une petite équipe peut collaborer en utilisant ce workflow. Nous verrons comment deux développeurs, Jean et Marie, peuvent travailler sur des fonctionnalités distinctes et partager leurs contributions via un dépôt centralisé.

Jean travaille sur sa fonctionnalité

Git Workflows: Edit Stage Commit Feature Process

Dans son dépôt local, Jean peut développer des fonctionnalités en utilisant le processus de commit Git standard : édition, staging et commit.

N'oubliez pas que, puisque ces commandes créent des commits locaux, Jean peut répéter ce processus autant de fois qu'il le souhaite sans avoir à se soucier de ce qui se passe dans le dépôt centralisé.

Marie travaille sur sa fonctionnalité

Git Workflows: Edit Stage Commit Feature

Dans le même temps, Marie travaille sur sa propre fonctionnalité dans son dépôt local en utilisant le même processus (édition, staging et commit). Tout comme Jean, elle ne se préoccupe pas de ce qu'il se passe dans le dépôt centralisé et elle ne se soucie vraiment pas de ce que Jean fait dans son dépôt local, puisque tous les dépôts locaux sont privés.

Jean publie sa fonctionnalité

Git Workflows: Publish Feature

Une fois que Jean aura terminé de développer sa fonctionnalité, il devra publier ses commits locaux dans le dépôt centralisé pour que les autres membres de l'équipe puissent y accéder. Pour ce faire, il peut utiliser la commande git push comme suit :

git push origin master

Souvenez-vous que origin constitue la connexion distante avec le dépôt centralisé que Git a créé lorsque Jean l'a cloné. L'argument master indique à Git de faire de la branche master de origin sa branche master locale. Comme le dépôt centralisé n'a pas été mis à jour depuis que Jean l'a cloné, l'opération se déroulera sans conflit, et le push fonctionnera comme prévu.

Marie tente de publier sa fonctionnalité

Git Workflows: Push Command Error

Voyons ce qu'il se passe si Marie tente de faire un push de sa fonctionnalité après que Jean a publié ses changements dans le dépôt centralisé. Elle peut utiliser la même commande push :

git push origin master

Mais, comme son historique local diverge du dépôt centralisé, Git refusera la demande et renverra un message d'erreur détaillé :

error: failed to push some refs to '/path/to/repo.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Cela empêche Marie d'écraser les commits officiels. Elle doit faire un pull des mises à jour de Jean dans son dépôt, les intégrer avec ses changements locaux, puis réessayer.

Marie fait un rebase par-dessus le ou les commits de Jean

Git Workflows: Git Pull Rebase

Marie peut lancer git pull pour intégrer à son dépôt les changements effectués en amont. Cette commande est très similaire à svn update : elle fait un pull de tout l'historique du commit en amont dans le dépôt local de Marie et tente de l'intégrer à ses commits locaux :

git pull --rebase origin master

L'option --rebase indique à Git de déplacer tous les commits de Marie vers la pointe de la branche master après l'avoir synchronisée avec les changements issus du dépôt centralisé, comme l'illustre le schéma suivant :

Git workflows: Rebasing to Master

Le pull fonctionnera toujours si vous oubliez cette option, mais vous vous retrouverez avec un commit de merge superflu à chaque fois qu'un utilisateur devra synchroniser son dépôt avec le dépôt centralisé. Pour ce workflow, il est toujours préférable de procéder à un rebase plutôt que de générer un commit de merge.

Marie résout un conflit de merge

Git Workflows: Rebasing on Commits

Lors du rebase des projets, chaque commit local est individuellement transféré vers la branche master mise à jour. Cela signifie que vous traitez les conflits de merge commit par commit, plutôt que de les résoudre tous dans un seul grand commit de merge. Vos commits seront aussi orientés que possible, et l'historique de votre projet restera propre. Ainsi, il vous sera nettement plus facile de détecter l'origine de bugs et, si nécessaire, d'annuler les changements tout en limitant l'impact de ces opérations sur l'ensemble du projet.

Si Marie et Jean travaillent sur des fonctionnalités non liées, il est peu probable que le processus de rebase génère des conflits. Si c'est le cas, Git interrompt le rebase au commit actuel et affiche le message suivant avec des instructions pertinentes associées :

CONFLICT (content): Merge conflict in <fichier>
Git workflows: Conflict Resolution

Le grand avantage de Git est que chaque développeur peut résoudre ses propres conflits de merge. Dans notre exemple, Marie doit simplement exécuter la commande git status pour identifier l'origine du problème. Les fichiers en conflit apparaîtront dans la section Chemins non mergés :

# Chemins non mergés : # (utilisez "git reset HEAD <fichier>..." pour annuler le staging) # (utilisez "git add/rm <fichier>..." au besoin pour marquer la résolution)
#
# tous deux modifiés : <fichier>

Ensuite, elle modifiera le ou les fichiers à sa convenance. Une fois qu'elle sera satisfaite du résultat, elle pourra stager le ou les fichiers de la manière habituelle, puis laisser la commande git rebase faire le reste :

git add <fichier>
git rebase --continue

Le tour est joué. Git passe au commit suivant et répète le processus pour tous les commits qui génèrent des conflits.

Si vous n'avez pas la moindre idée de ce qu'il se passe à ce stade, pas de panique ! Il vous suffit d'exécuter la commande suivante pour revenir au point de départ :

git rebase --abort

Marie publie avec succès sa fonctionnalité

Git Workflows: Synchronize Central Repo

Après avoir synchronisé le dépôt centralisé, Marie pourra publier ses changements avec succès :

git push origin master

Marche à suivre

Comme vous pouvez le voir, il est possible de répliquer un environnement de développement Subversion classique avec seulement quelques commandes Git. C'est intéressant pour la migration d'équipes hors de SVN, mais cela n'exploite pas la nature distribuée de Git.

Le workflow centralisé est idéal pour les petites équipes. Le processus de résolution de conflits détaillé ci-dessus peut constituer un goulot d'étranglement à mesure que votre équipe s'agrandit. Si votre équipe est à l'aise avec le workflow centralisé, mais souhaite simplifier ses efforts de collaboration, il est sans doute intéressant d'étudier les avantages du workflow de branche par fonctionnalité. En dédiant une branche isolée à chaque fonctionnalité, il est possible d'entamer des discussions approfondies sur les nouveaux ajouts avant de les intégrer au projet officiel.

Autres workflows courants

En bref, le workflow centralisé est un élément de base d'autres workflows Git. Les workflows Git les plus populaires impliquent une forme quelconque de dépôt centralisé à partir duquel les développeurs font des push et des pull. Dans la section suivante, nous allons brièvement évoquer certains autres workflows Git populaires. Ces workflows étendus offrent davantage de modèles spécialisés en ce qui concerne la gestion des branches pour le développement de fonctionnalités et de correctifs et, enfin, la livraison.

Création de branches de fonctionnalités

La création de branches de fonctionnalité est une extension logique du workflow centralisé. Le principe de base du workflow de branche par fonctionnalité est que chaque fonctionnalité est développée dans une branche dédiée plutôt que dans la branche master. Grâce à cette encapsulation, plusieurs développeurs peuvent travailler aisément sur une même fonctionnalité sans modifier la base de code principale. Cela signifie également que la branche master ne contiendra jamais de code bogué : un avantage non négligeable pour les environnements d'intégration continue. 

Workflow Gitflow

Le workflow Gitflow a tout d'abord été publié dans un billet de blog très médiatisé de 2010, par Vincent Driessen de chez nvie. Le workflow Gitflow définit un modèle de création de branches strict conçu autour de la version du projet. Il n'ajoute aucun nouveau concept ni aucune nouvelle commande en dehors de ce qui est exigé pour le workflow de branche par fonctionnalité. Il attribue plutôt des rôles très spécifiques aux différentes branches et définit comment et quand elles doivent interagir. 

Workflow de duplication (fork)

Le workflow de duplication (fork) est fondamentalement différent des autres workflows abordés dans ce tutoriel. Au lieu d'utiliser un dépôt unique côté serveur qui fera office de base de code « centralisée », ce workflow fournit un dépôt côté serveur à chaque développeur. Par conséquent, chaque contributeur dispose non pas d'un, mais de deux dépôts Git : un local privé et un côté serveur public. 

Recommandations

Il n'existe pas de modèle unique de workflow Git adapté à toutes les circonstances. Comme nous l'avons déjà dit, il est important de développer un workflow Git qui améliore la productivité de votre équipe. Outre la culture d'équipe, un workflow doit compléter la culture d'entreprise. Les fonctionnalités Git comme les branches et les tags devraient compléter le planning de livraison de votre entreprise. Si votre équipe utilise un logiciel de gestion de projet et de suivi des tâches, vous souhaiterez peut-être utiliser des branches qui correspondent aux tâches en cours. En outre, voici quelques recommandations à prendre en compte lorsque vous déterminez le workflow à utiliser :

Branches éphémères

Plus une branche est séparée de la branche de production, plus le risque de conflits de merge et de difficultés de déploiement est élevé. Les branches éphémères favorisent des merges et des déploiements plus propres.

Minimiser et simplifier les reverts

Il est important d'avoir un workflow qui contribue à prévenir, de façon proactive, les merges qui devront être restaurés. Un workflow qui teste une branche avant de permettre qu'elle ne soit mergée dans la branche master, par exemple. Cependant, vous n'êtes pas à l'abri des accidents. Cela dit, il est utile de mettre en place un workflow qui permet des reverts faciles, sans interrompre le travail des autres membres de l'équipe.

Faire coïncider le workflow avec le planning de livraison

Un workflow doit compléter votre cycle de développement et de livraison. Si vous prévoyez de livrer plusieurs fois par jour, il vous faut conserver une branche master stable. Si votre planning de livraison est moins fréquent, vous souhaiterez peut-être utiliser des tags Git pour taguer une branche à une version.

Résumé

Dans ce document, nous avons abordé les workflows Git. Nous avons étudié en détail un workflow centralisé avec des exemples pratiques. Pour aller plus loin, nous avons vu des workflows spécialisés supplémentaires. Voici les enseignements clés de ce module :

  • Il n'existe pas de modèle unique de workflow Git adapté à toutes les circonstances.
  • Un workflow doit être simple et améliorer la productivité de votre équipe.
  • Vos exigences business devraient aider à façonner votre workflow Git.

Pour découvrir le prochain workflow Git, consultez notre décomposition détaillée du workflow de branche par fonctionnalité.

Prêt à découvrir Git ?

Essayez ce tutoriel interactif.

Démarrez maintenant