Upstreams et forks Git : guide pratique et astuce sympa
NICOLA PAOLUCCI
Expert en développement
La duplication de projets pour apporter vos propres changements permet d'intégrer facilement vos propres contributions. Mais si vous ne renvoyez pas ces changements vers l'amont (c'est-à-dire vers le dépôt parent), vous risquez d'en perdre la trace, ce qui peut provoquer des lignes divergentes dans votre dépôt. Pour vous assurer que tous les contributeurs partent du même point de départ, vous devez connaître certains principes de l'interaction entre git forking et git upstream. Dans ce billet de blog, je vais vous présenter les bases, les pièges à éviter et je vais même vous confier une astuce sympa pour vous permettre de prendre de l'avance.
Git upstream : restez à jour et apportez votre contribution
Je tiens tout d'abord à vous présenter une configuration courante ainsi qu'un workflow des plus basiques pour interagir avec les dépôts upstream
.
Toute configuration standard comporte généralement un remote
origin
et upstream. Ce dernier est le gardien du projet ou la source d'informations fiable à laquelle vous souhaitez contribuer.
Premièrement, vérifiez que vous avez déjà créé un remote pour le dépôt upstream
, avec en prime une branche origin
:
git remote -v
origin git@bitbucket.org:my-user/some-project.git (fetch)
origin git@bitbucket.org:my-user/some-project.git (push)
Si vous n'avez pas de branche upstream
, vous pouvez simplement l'ajouter en utilisant la commande remote
:
git remote add upstream git@bitbucket.org:some-gatekeeper-maintainer/some-project.git
Ressource connexe
Comment déplacer un dépôt Git complet
DÉCOUVRIR LA SOLUTION
Découvrir Git avec Bitbucket Cloud
Vérifiez que la branche distante est correctement ajoutée :
git remote -v
origin git@bitbucket.org:my-user/some-project.git (fetch)
origin git@bitbucket.org:my-user/some-project.git (push)
upstream git@bitbucket.org:some-gatekeeper-maintainer/some-project.git (fetch)
upstream git@bitbucket.org:some-gatekeeper-maintainer/some-project.git (push)
À présent, vous pouvez collecter les derniers changements du dépôt upstream
avec fetch
. Répétez cette action à chaque fois que vous voulez recevoir des mises à jour :
(Si le projet dispose de tags qui n'ont pas été mergés à la branche main, vous devez également exécuter : git fetch upsteam --tags)
git fetch upstream
En règle générale, vous souhaitez que votre branche main
locale soit un parfait miroir de la branche upstream
main
et vous voulez travailler dans des branches de fonctionnalité, car elles pourraient bien devenir des pull requests.
Pour le moment, que vous utilisiez merge
ou rebase
n'a pas d'importance, puisque le résultat sera le même. Utilisons merge
:
git checkout main
git merge upstream/main
Lorsque vous souhaitez partager votre travail avec les mainteneurs upstream
, vous créez une branche à partir de main
, puis une branche de fonctionnalité. Une fois que vous êtes satisfait, pushez-la vers votre dépôt distant.
Vous pouvez également utiliser rebase
, puis merge
pour vous assurer que la branche upstream
dispose d'un ensemble de commits nettoyé (idéalement, un seul) à évaluer :
git checkout -b feature-x
#some work and some commits happen
#some time passes
git fetch upstream
git rebase upstream/main
Publication grâce à un fork Git
Une fois que vous aurez effectué les étapes ci-dessus, publiez votre travail dans votre fork distant en utilisant un simple push
:
git push origin feature-x
git push -f origin feature-x
Personnellement, je préfère conserver l'historique aussi propre que possible et utiliser la troisième option, mais les workflows varient en fonction des équipes. Remarque : ne procédez de la sorte que lorsque vous travaillez avec votre propre fork. Vous ne devez JAMAIS procéder à la réécriture de l'historique des dépôts et des branches partagés.
Astuce du jour : nombres de commits avant/après une branche dans l'invite
Après un fetch
, git status
vous montrera combien de commits se trouvent avant ou après la branche remote
synchronisée. Ne serait-ce pas merveilleux si vous pouviez consulter ces informations avec cette bonne vieille invite de commande ? C'est la raison pour laquelle j'ai concocté un petit quelque chose avec bash
.
Une fois la configuration effectuée, voici à quoi ressemblera votre invite :
nick-macbook-air:~/dev/projects/stash[1|94]$
Voici ce que vous devez ajouter à votre fichier .bashrc
ou à un fichier équivalent, c'est-à-dire une seule fonction :
function ahead_behind {
curr_branch=$(git rev-parse --abbrev-ref HEAD);
curr_remote=$(git config branch.$curr_branch.remote);
curr_merge_branch=$(git config branch.$curr_branch.merge | cut -d / -f 3);
git rev-list --left-right --count $curr_branch...$curr_remote/$curr_merge_branch | tr -s '\t' '|';
}
export PS1="\h:\w[\$(ahead_behind)]$"
Fonctionnement interne
Pour ceux qui souhaitent plus d'informations et d'explications, voici comment cela fonctionne :
Nous obtenons le nom symbolique du HEAD courant, c'est-à-dire, de la branche courante :
curr_branch=$(git rev-parse --abbrev-ref HEAD);
Nous obtenons la branche distante vers laquelle la branche courante pointe :
curr_remote=$(git config branch.$curr_branch.remote);
Nous obtenons la branche sur laquelle ce remote doit être mergé (avec un petit truc Unix pour tout ignorer, même la dernière barre oblique [ / ]) :
curr_merge_branch=$(git config branch.$curr_branch.merge | cut -d / -f 3);
À présent, nous avons ce dont nous avons besoin pour compter le nombre de commits qui se trouvent avant ou après la branche :
git rev-list --left-right --count $curr_branch...$curr_remote/$curr_merge_branch | tr -s '\t' '|';
Nous utilisons l'ancienne commande Unix tr
pour convertir TAB
en séparateur |
.
Premiers pas avec git upstream
Il s'agit d'une présentation de base de git upstream
: comment configurer un git upstream, créer une branche, collecter les changements, publier avec git fork et une astuce pour savoir combien de commits vous avez en avance/retard sur votre branche distante.
Bitbucket Data Center inclut la synchronisation des forks, ce qui évite aux développeurs de devoir garder leurs forks à jour, et Bitbucket Cloud permet une synchronisation facile en une étape. À tester !
Partager cet article
Thème suivant
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.