Close

Pull request git fetch : compétence débloquée

Photo de Nicola Paolucci
Nicola Paolucci

Expert en développement


Aujourd'hui, pour apporter des corrections à un projet, il suffit de faire un fork (le fork est une copie distante complète du projet que vous pouvez hacker), de sélectionner le fichier à modifier, d'appuyer sur Edit, puis de faire des commits de vos corrections.

Et qu'en est-il si vous vous trouvez à l'extrémité de réception d'une pull request ? Une interface Web améliorée est pratique et répond souvent à tous vos besoins. Cliquez sur le bouton Approve (Approuver), puis Merge (Faire un merge). Vous avez alors terminé.

Mais ce n'est pas toujours le cas ! Il arrive fréquemment qu'il soit nécessaire de télécharger les changements inclus localement dans une pull request, d'exécuter quelques tests et de voir le résultat dans votre IDE pour les comprendre.

En théorie, les étapes nécessaires au chargement – c'est-à-dire fetch et checkout – des pull requests de vos collègues ou de vos contributeurs sont très simples, mais elles le seront encore plus avec quelques conseils et astuces supplémentaires.

Laissez-moi vous aider à mieux comprendre les fonctionnalités que Git vous propose pour gérer facilement les pull requests à partir de la ligne de commande.

Avant de commencer : ajouter l'état et le nom de branche dans l'invite shell


Je suis toujours surpris du nombre de développeurs qui utilisent une invite de commande brute sans afficher la branche git sur laquelle ils travaillent ou si leur répertoire de travail contient des fichiers modifiés/non commités. Si vous vous dites : « Hé, mais c'est de moi qu'il parle ! », ce que je vais vous apprendre va vous aider et vous couper le souffle par la même occasion !

Rendez-vous service et installez un module comme Liquid Prompt, qui vous indiquera efficacement l'état de votre répertoire de travail Git (et qui prendra aussi en charge tout autre logiciel de contrôle de version) :

(La capture d'écran ci-dessus vous montre mon invite, qui m'indique que je suis sur la branche newbranch, que j'ai ajouté 5 lignes aux fichiers que je tracke dans mon répertoire de travail et que j'en ai supprimé 0)

Logo Git
Ressource connexe

Installation de Git

Logo Bitbucket
DÉCOUVRIR LA SOLUTION

Découvrir Git avec Bitbucket Cloud

Tout le monde travaille dans le même dépôt


Si votre équipe et vous-même travaillez sur le même dépôt, le checkout des pull requests est très simple ; il vous suffit de lancer un fetch et un checkout de la branche à partir de laquelle la pull request a été faite :

  • Récupérez toutes les branches qui ont été publiées sur votre dépôt partagé :
git fetch origin
  • Créer une branche locale qui tracke la branche distante qui vous intéresse :
git checkout -b PRJ-1234 origin/PRJ-1234
  • À présent que vous pouvez exécuter diff et merge, admirez le travail :
git diff main ./run-tests.sh
  • Lorsque vous êtes satisfait, revenez simplement à l'interface Web et indiquez votre feedback ou approuvez le changement.

Contributeurs travaillant dans leurs propres forks


Le processus change légèrement lorsque certains contributeurs travaillent dans des forks séparés. Dans ce cas, vous pouvez récupérer (fetch) la branche distante dans laquelle la contribution ou la fonctionnalité a été commitée :

  • Ajoutez d'abord le remote du contributeur :
git remote add jsmith http://bitbucket.org/jsmith/coolproject.git
  • Commencez par collecter toutes les dernières mises à jour à partir d'origin, votre dépôt principal :
git checkout main git fetch origin git merge main
  • Récupérez toutes les branches qui ont été publiées sur le fork du contributeur :
git fetch jsmith
  • Créer une branche locale qui tracke la branche distante qui vous intéresse :
git checkout -b jsmith-PRJ-1234 jsmith/PRJ-1234
  • À présent que vous pouvez exécuter diff et merge, admirez le travail :
git diff main ./run-tests.sh

Réduire la charge de travail en utilisant des réfs de pull request


La solution ci-dessus fonctionne, mais différents éléments peuvent vous compliquer la vie :

  • Que se passe-t-il si vous avez de nombreux collaborateurs et que chacun a ses propres forks ? Ce n'est pas pratique d'ajouter leurs forks et de les gérer individuellement.
  • Que faire si vous n'avez accès qu'à certains forks et que vous ne pouvez pas faire un checkout de la branche source ?

La solution aux deux problèmes exposés ci-dessus consiste à utiliser les réfs des pull requests fournies par certains serveurs Git. La procédure que je vais vous montrer est prise en charge par certains serveurs Git et varie légèrement suivant celui que vous utilisez. Dans les lignes qui suivent, je vous expliquerai comment fetcher toutes les pull requests sur Stash (à présent connu sous le nom de Bitbucket Server) et Github.

N'ayez pas peur des refspecs

La première condition est de vous familiariser avec les refspecs. Les refspecs ne sont pas bien méchants ; ils ne vont pas vous manger ! Il s'agit simplement de mappages des branches distantes vers des références locales. En d'autres termes, c'est une manière directe de dire à Git que « cette branche distante (ou cette plage de branches distantes) devrait être mappée vers ces noms en local, dans cet espace de noms. »

Par exemple, une commande comme :

git fetch +refs/heads/main:refs/remotes/origin/main

Va mapper la branche main distante située sur votre dépôt distant origin vers une branche origin/main locale. Ainsi, vous pourrez saisir :

git checkout origin/main

Vous vous référez toujours à cette branche distante. Le signe « plus » (+) de la définition permet d'ordonner à Git de mettre à jour la référence, même si ce n'est pas en fast-forward.

Pour télécharger toutes les pull requests, nous effectuons un mapping afin d'indiquer comment le remote stocke les PR HEAD et nous les mappons vers un espace de noms local pour nous y référer facilement.

À condition que vous ayez défini un dépôt distant origin (ou upstream), voici ce que vous devez faire.

Remarque : comme l'ont très justement noté des développeurs Stash (à présent connu sous le nom de Bitbucket Server), les réfs que je vais vous présenter ci-dessous sont considérées comme non documentées et privées, et peuvent changer à tout moment.

Télécharger toutes les pull requests : Stash

  • Faites un fork d'un dépôt.
  • Clonez votre fork en local :
git clone git@stash.atlassian.com:durdn/tis.git
  • Ajoutez le dépôt d'origine upstream comme upstream.
git remote add upstream git@stash.atlassian.com:tpettersen/tis.git
  • Obtenez les derniers heads du mainteneur « upstream »
git fetch upstream
  • Ajoutez le refspec qui va mapper les heads des pull requests distantes vers un espace de noms pr local. Pour ce faire, vous pouvez utiliser la commande config :
git config --add remote.origin.fetch '+refs/pull-requests/*/from:refs/remotes/origin/pr/*'
  • Si vous consultez .git/config, les entrées fetch deviennent :
[remote "upstream"]
    url = git@stash.atlassian.com:docker/libswarm.git
    fetch = +refs/heads/*:refs/remotes/upstream/*
    fetch = +refs/pull-requests/*/from:refs/remotes/upstream/pr/*
  • À présent, vous pouvez facilement faire un fetch de toutes les branches des pull requests :
$ git fetch upstream

remote: Counting objects: 417, done.
remote: Compressing objects: 100% (274/274), done.
remote: Total 417 (delta 226), reused 277 (delta 128)
Receiving objects: 100% (417/417), 105.28 KiB | 0 bytes/s, done.
Resolving deltas: 100% (226/226), done.

From stash.atlassian.com:docker/libswarm
 * [new ref]         refs/pull-requests/10/from-> upstream/pr/10
 [...]
 * [new ref]         refs/pull-requests/100/from -> upstream/pr/100
 * [new ref]         refs/pull-requests/101/from -> upstream/pr/101
 [...]
 * [new ref]         refs/pull-requests/109/from -> upstream/pr/109
 * [new ref]         refs/pull-requests/110/from -> upstream/pr/110
 [...]
  • Maintenant, pour basculer vers une pull request particulière, vous pouvez simplement :
git checkout pr/102

Télécharger toutes les pull requests : Github

Si les forks ou les upstreams sont sur GitHub, le fonctionnement est exactement le même que ci-dessus, à cela près que la commande config est remplacée par :

 git config --add remote.origin.fetch '+refs/pull//head:refs/remotes/origin/pr/'

Et le dépôt distant situé dans .git/config changera pour intégrer une configuration fetch supplémentaire de manière à mapper les heads de pull request vers un espace de noms local nommé pr :

[remote "upstream"] url = git@github.com:docker/libswarm.git fetch = +refs/heads/*:refs/remotes/upstream/* fetch = +refs/pull/*/head:refs/remotes/upstream/pr/*

Fetcher une PR unique avec des réfs

Si vous ne souhaitez pas configurer des entrées fetch dans votre .git/config et que vous voulez accéder rapidement à une pull request, une seule commande vous le permettra :

  • Faire un check-out d'une pull request unique dans Stash :
git fetch refs/pull-requests/your-pr-number/from:local-branch-name
  • Faire un checkout d'une pull request unique sur Github :
git fetch refs/pull/your-pr-number/head:local-branch-name

Si vous utilisez beaucoup la fonctionnalité ci-dessus, vous pouvez simplifier le process en créant un alias git :

# For Stash
git config alias.spr '!sh -c "git fetch origin pull-requests/${1}/from:pr/${1}" -'

# For Github
git config alias.gpr '!sh -c "git fetch origin pull/${1}/head:pr/${1}" -'

Avec cet alias configuré, nous pouvons faire un fetch d'une pull request avec une simple commande (merci les Inuits) :

Conclusions


J'espère que ces informations vous auront été utiles ! Finalement, vous pourrez facilement surveiller le travail de vos pairs et de vos contributeurs si vous créez quelques alias très simples ou ajoutez les bonnes refspecs à votre .git/config. Je serai ravi de répondre à toutes vos questions sur Twitter : @durdn ou @AtlDevtools.

Nicola Paolucci

Nicola is an all-round hacker who loves exploring and teaching bleeding edge technologies. He writes and talks about Git, development workflows, code collaboration and more recently about Docker. Prior to his current role as Developer Instigator at Atlassian he led software teams, built crowd sourcing applications for geo-spacial data, worked on huge e-commerce deployments. Little known facts about Nicola: he gesticulates a lot while speaking (being Italian), lives in Amsterdam and rides a Ducati.


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