Close

Travailler avec Git et Perforce : workflow d'intégration

Voici donc le scénario : votre équipe travaille indépendamment sur un dépôt Git, mais une partie de l'organisation utilise toujours Perforce pour gérer des parties de la même base de code. Ces équipes sur Perforce ne prévoient pas de migrer, mais votre équipe est déjà passée à Git (pour de nombreuses raisons). Il est important que vous puissiez maintenir un processus de partage du code bidirectionnel entre les bases de code afin que les améliorations développées dans les deux versions puissent être partagées, en espérant que cela ne vous fasse pas trop perdre de temps ou que votre équipe ne soit pas trop gênée.

C'est ici que ce guide entre en jeu. Chez TomTom, cette opération de synchronisation est effectuée à chaque nouvelle version, ce qui, dans leur cas, se produit une fois tous les mois et demi.

— Ce billet a été rédigé en collaboration avec Andrea Carlevato, Adolfo Bulfoni et Krzysztof Karczewski qui ont eu la gentillesse de partager le processus Git utilisé par l'unité NavApps de TomTom. —


Hypothèses avant de commencer


Nous partons du principe que vous connaissez déjà l'utilisation de base de Git et que vous êtes familier avec le workflow de branche de fonctionnalité. Si ce n'est pas le cas, prenez le temps de visionner un tutoriel pratique ou un webinaire, et revenez quand vous serez prêt. Nous vous attendrons.

Il existe quelques subtilités à garder à l'esprit dans le processus. Nous vous suggérons donc d'être très prudent lorsque vous effectuez ces intégrations. Nous pouvons commencer dès que vous serez prêt !

Installation de git p4


La première étape consiste à installer le pont. Vous pouvez vérifier qu'il est déjà installé en saisissant cette commande sur une ligne de commande :

git p4

Si le système vous signale que git p4 n'est pas installé, téléchargez git-p4.py et placez-le dans un dossier de votre PATH, par exemple ~/bin (évidemment, Python doit également être installé pour que cela fonctionne).

Rendez-le exécutable avec :

chmod +x git-p4.py

Modifiez le fichier ~/.gitconfig en ajoutant :

[alias]
    p4 = !~/bin/bit-p4.py

Puis, exécutez à nouveau git p4. Vous ne devriez pas avoir d'erreur. L'outil est installé.

Bases de données
Ressource connexe

Comment déplacer un dépôt Git complet

Logo Bitbucket
DÉCOUVRIR LA SOLUTION

Découvrir Git avec Bitbucket Cloud

Aperçu du workflow


Clonage initial

Étant donné que les projets dans P4 peuvent générer d'énormes historiques, l'équipe peut choisir un point de coupure à partir duquel se synchroniser. Cela permet de gagner beaucoup d'espace et de temps. git p4 vous permet de choisir la liste des changements à partir de laquelle démarrer le suivi :

git p4 clone //depot/path/project@<earlier-cutoff-point>,<latest-changelist>
  • Nous pouvons maintenant exécuter une synchronisation et vérifier que nous avons reçu tous les ensembles de changements localement :
git p4 sync

La commande sync trouve les nouveaux changements dans P4 et les importe en tant que commits Git.

  • Nous nommons p4-integ la branche que nous utiliserons pour interfacer directement avec Perforce. À ce stade, nous voulons simplement créer une branche à partir de remotes/p4/main :
git checkout -b p4-integ origin/p4/main

Synchronisation rapide de suivi (ou synchronisation « en deux temps »)

Une fois la première importation terminée, les synchronisations git-> p4 suivantes peuvent être effectuées avec les commandes suivantes :

git checkout p4-integ
git p4 sync

Le code ci-dessus fonctionne, mais il peut être lent. Un moyen beaucoup plus rapide d'exécuter la synchronisation consiste à recréer des références (refs) identiques à celles utilisées dans la dernière intégration. C'est également un bon moyen de s'assurer que tout nouveau développeur chargé de l'intégration commence au niveau du bon commit ou de la bonne liste de changements.

Voici comment procéder :

  • Supprimez les anciennes refs d'origine (ou caduques) pour le remote p4 (en option) :
git symbolic-ref -d refs/remotes/p4/HEAD
git update-ref -d refs/remotes/p4/main
  • Créez des refs remote artificielles (ou fausses) qui pointent vers le dernier commit sur p4-integ dans origin :
git update-ref refs/remotes/p4/main remotes/origin/p4-integ
git symbolic-ref refs/remotes/p4/HEAD refs/remotes/p4/main

Le seul inconvénient de cette synchronisation beaucoup plus rapide est que nous devons spécifier explicitement la branche dans git p4. Voici donc la commande finale :

git p4 sync --branch=refs/remotes/p4/main

La façon dont git p4 suit le mappage entre les identifiants de commit Git et ceux de P4 consiste à annoter les commits avec des métadonnées :

Merge pull request #340 in MOB/project from bugfix/PRJ-3185 to develop

    Squashed commit of the following:

    commit c2843b424fb3f5be1ba64be51363db63621162b4
    Author: Some Developer
    Date:   Wed Jan 14 09:26:45 2015 +0100

        [PRJ-3185] The app shows ...

    commit abc135fc1fccf74dac8882d70b1ddd8a4750f078
    Author: Some Developer
    Date:   Tue Jan 13 14:18:46 2015 +0100

        [PRJ-3185] The app shows the rating ...

    [git-p4: depot-paths = "//depot-mobile/project/": change = 1794239]

Notez que dans une version plus récente de git p4, les métadonnées permettant d'associer un commit Git à une liste de changements P4 sont stockées dans une note de commit et non dans le message de commit. L'équipe de TomTom n'a pas apprécié ce changement, car il compliquait un peu la vérification des numéros de la liste des changements lorsque cela était nécessaire.

Déplacement des changements de Git vers Perforce


Une fois l'opération de synchronisation rapide ci-dessus terminée, vous êtes maintenant prêt à pusher les changements de git vers Perforce.

La première étape consiste à exécuter un rebase de p4-integ avec les changements provenant de remotes/p4/main :

git checkout p4-integ
git p4 rebase

Après cela, tous les nouveaux changements de Perforce devraient être sur p4-integ, afin que nous puissions mettre à jour main :

  • Après cela, vous pouvez simplement utiliser cette commande :
git checkout main
git merge develop
  • Assurez-vous d'avoir les derniers tags en local :
git fetch --tags
  • Utilisez un cleanup temporaire au cas où vous auriez besoin de supprimer des commits déjà dans P4 (voir le tag P4 dans le commit). Dans le cas où aucun commit ne doit être ignoré, un rebase automatique qui linéarisera l'historique :
git checkout -b cleanup #branching off from main
git rebase -s recursive -X theirs tag/last-p4-integ
  • Grâce à un rebase interactif, vous pouvez le faire à la place avec :
git rebase -i tag/last-p4-integ
  • Utilisez cherry-pick pour sélectionner les nouveaux commits et les placer sur la branche p4-integ. Nous le faisons de cette manière, car nous ne supposons pas que les branches git main et develop puissent être conservées en tant que véritables ancêtres de la branche p4-integ. En fait, ce n'est plus le cas chez TomTom.
git checkout p4-integ
git cherry-pick tag/last-p4-integ..cleanup
  • Envoyez à P4 et synchronisez p4-integ :
git p4 submit
git p4 sync --branch=refs/remotes/p4/main
git reset --hard refs/remotes/p4/main
  • Supprimez la branche de rebase temporaire :
git branch -D cleanup
  • Supprimez le pointeur vers le dernier point d'intégration (tag) en local et sur le remote :
git tag -d tag/last-p4-integ
git push origin :refs/tags/tag/last-p4-integ
  • Mettez à jour le tag last-p4-integ pour qu'elle pointe vers le nouveau point d'intégration dans P4 :
git checkout develop
git tag -a tag/last-p4-integ -m "tag pointer to last develop commit integrated with p4"
git push origin main
git push origin tag/last-p4-integ
git push origin p4-integ

Exécutez des tests sur la base de code P4 pour vérifier que l'intégration n'a pas introduit de problèmes.

Déplacement des changements de Perforce vers Git


Cela doit être fait une fois que le push git-> P4 a déjà été fait. Une fois les tests réussis sur P4, nous pouvons maintenant déplacer les changements de P4 vers git avec le code ci-dessous :

git checkout p4-integ
git p4 sync --branch=refs/remotes/p4/main
git p4 rebase
  • Le code ci-dessous est une petite astuce pour effectuer une stratégie de merge « theirs » (à eux) robuste, réduisant les changements entrants à un seul commit :
git checkout -b p4mergebranch #branching off from p4-integ
git merge -s ours main ## ignoring all changes from main
git checkout main
git merge p4mergebranch --squash
git commit -m "Type your integration message"
git branch -D p4mergebranch
  • Une fois que nous avons terminé avec ce qui précède, mergez les changements apportés à develop :
 <p>Bitbucket has the following space stations:</p>
 <p>
     <b>Earth's Moon</b><br>
     Headquarters
 </p>

Étant donné que des changements ont pu avoir lieu depuis que nous avons récupéré les changements de develop, il peut être nécessaire de les merger en premier. Il est important, cependant, de mettre à jour le tag last-p4-integ vers le bon commit, et surtout pas le commit de merge vers develop. Pour le faire en toute sécurité, il est préférable de taguer l'état actuel de main :

  • Supprimez l'ancien tag en local et sur le remote :
git tag -d tag/last-p4-integ
git push origin :refs/tags/tag/last-p4-integ
  • Créez un tag à la nouvelle position :
git checkout main
git tag -a tag/last-p4-integ -m "tag pointer to last develop commit integrated with p4"
  • Pushez maintenant main, develop, p4-integ et tag/last-p4-integ vers origin :

Conclusions


C'est ainsi que vous synchronisez deux équipes de développement actives à l'aide de Git et Perforce. Le processus ci-dessus a évolué au fil du temps chez TomTom, et il est maintenant opérationnel depuis un certain temps sans problèmes majeurs. Cela fonctionne, mais cela implique des frais généraux assez importants pour la maintenance. Si vous en avez la possibilité, nous vous recommandons de migrer complètement vers Git.

Dans tous les cas, si vous suivez une approche différente pour maintenir une synchronisation bidirectionnelle, je serais très curieux de la lire dans les commentaires ci-dessous. Ou bien, envoyez un tweet à @durdn ou à @atlassiandev.

Merci encore à Andrea Carlevato, Adolfo Bulfoni et Krzysztof Karczewski.

Partager cet article

Lectures recommandées

Ajoutez ces ressources à vos favoris pour en savoir plus sur les types d'équipes DevOps, ou pour les mises à jour continues de DevOps chez Atlassian.

Des personnes qui collaborent à l'aide d'un mur rempli d'outils

Le blog Bitbucket

Illustration DevOps

Parcours de formation DevOps

Démos Des démos avec des partenaires d'Atlassian

Fonctionnement de Bitbucket Cloud avec Atlassian Open DevOps

Inscrivez-vous à notre newsletter DevOps

Thank you for signing up