Git : comment travailler avec plusieurs remotes

Git : comment travailler avec plusieurs remotes

Parce que c'est meilleur à plusieurs

Avatar de l'auteur
David Legrand

Publié dans

Logiciel

08/10/2020 5 minutes
13

Git : comment travailler avec plusieurs remotes

Pour faciliter le travail depuis plusieurs machines ou en équipe, Git permet d'utiliser des dépôts locaux ou distants. Dans ce second cas, on parle de « remotes ». S'il est courant d'en utiliser un seul à la fois, ce n'est pas une limite inscrite dans le marbre, loin de là.

L'aspect distribué de Git se manifeste par différents aspects. Le fait qu'il puisse être utilisé comme client ou serveur tout d'abord, mais aussi que l'on puisse « pousser » ou récupérer des données vers/depuis des tiers.

Comme nous l'avons vu dans la partie précédente de ce dossier, lorsque l'on clone un dépôt distant, il est considéré comme un remote du dépôt local. Mais Git a cela de particulier qu'il permet de ne pas se limiter à un seul et que l'on peut ajouter autant de remotes qu'on le souhaite. Ce qui peut avoir des avantages non négligeables.

Mais comme souvent avec cet outil, il y a quelques particularités à côté desquelles il ne faut pas passer.

Notre dossier sur la maîtrise de Git et de ses plateformes :

Un dépôt, deux remotes

Dans cet article nous partirons du principe que vous disposez des bases concernant les concepts de Git et que vous l'avez d'installé sur votre machine. Si ce n'est pas le cas, nous vous invitons à lire notre précédent tutoriel.

Pour commencer nous allons cloner le dépôt d'un projet depuis GitHub :

git clone https://github.com/davlgd/pwa-static-winget.git

Comme nous l'avons vu dans l'article précédent, cela crée un dépôt local, y place les données et définit l'URL comme celle du remote principal, nommé origin par convention. On peut le voir avec la commande suivante :

cd pwa-static-winget
git remote -v

Vous pouvez très bien modifier son nom (git remote rename) ou son URL (git remote --set-url) à tout moment. Attention dans le premier cas, il faudra alors penser à indiquer le nom du remote dans vos différentes commandes. Avec origin ce n'est pas toujours nécessaire puisqu'il est considéré comme remote par défaut.

Nous allons maintenant créer un dépôt secondaire qui sera utilisé comme un remote. Pour vous éviter d'avoir à utiliser plusieurs machines, nous allons le faire en local, sur votre ordinateur. C'est peu utile, mais possible.

cd ..
git clone --bare https://github.com/davlgd/pwa-static-winget.git

Vous obtenez deux dossiers : pwa-static-winget, un dépôt local classique cloné depuis GitHub et pwa-static-winget.git un dépôt nu (bare) cloné depuis GitHub mais pouvant être utilisé comme remote.

C'est ce que nous allons faire, en le nommant « second » :

cd pwa-static-winget
git remote add second ../pwa-static-winget.git
git remote -v

Cette fois, vous devriez avoir deux remotes liés à votre dépôt local et obtenir le résultat suivant :

Git remote

Pousser des modifications vers le second remote

On va maintenant modifier les données du dépôt local et les envoyer à notre nouveau remote :

echo > "Hello, World !" > Hello.md
git add Hello.md
git commit -a -m "Ajout d'un message"
git push second master

Dans la dernière ligne, on précise que l'on envoie la branche principale (master). Ce n'est pas nécessaire, mais autant prendre l'habitude de le faire si vous travaillez régulièrement avec différentes branches.

Gérer plusieurs remotes en une seule commande

Lorsque vous utilisez plusieurs dépôts distants, vous pourrez être amené à récupérer leurs données ou y effectuer des push. Dans ce second cas, il peut être intéressant de le faire sur plusieurs dépôts d'un coup, par exemple si vous en maintenez un interne et un autre public, sur GitHub/GitLab, etc. 

Git a néanmoins une particularité : si les commandes fetch/pull acceptent un argument --all permettant de récupérer les données depuis tous les remotes enregistrés, le même argument appliqué à push n'indique pas à Git que vous voulez pousser une branche vers tous les remotes, mais toutes les branches vers un remote particulier.

Il existe néanmoins une solution : créer un remote contenant plusieurs URL pour la commande push. Il faut pour cela commencer par le créer de manière classique (ici a vec le nom « all »), puis lui ajouter les URL nécessaires :

git remote add all https://github.com/davlgd/pwa-static-winget.git
git remote set-url --add all ../pwa-static-winget.git
git remote -v

Vous verrez ainsi un nouveau remote disposant de deux URL pour envoyer des données, d'une seule pour les récupérer. Pour l'utiliser avec la branche principale il suffit d'utiliser la commande git push all master.

Git remote add

Écrit par David Legrand

Tiens, en parlant de ça :

Sommaire de l'article

Introduction

Un dépôt, deux remotes

Pousser des modifications vers le second remote

Gérer plusieurs remotes en une seule commande

next n'a pas de brief le week-end

Le Brief ne travaille pas le week-end.
C'est dur, mais c'est comme ça.
Allez donc dans une forêt lointaine,
Éloignez-vous de ce clavier pour une fois !

Fermer

Commentaires (13)


Questions :




  • On peut ajouter un dépot distant supplémentaire directement sur origin (si on sait que l’on veut toujours envoyer sur l’ensemble des dépots) ?


  • Que se passe-t-il si un des dépots n’est pas disponible au moment du push ? Est-ce que lorsque le dépot redevient disponible, git status montrera que la copie locale est en avance par rapport à ce dépot distant ?



Super série d’articles :yes:


Je n’ai pas testé mais tu peux sans doute ajouter une URL à origin oui, c’est un remote comme un autre, c’est juste que quand aucun n’est mentionné, c’est lui qui est utilisé.



En cas d’indispo de mémoire tu as une simple erreur, si l’un ne répond pas rien n’est envoyé. Après je ne sais plus comment ça se passe en cas d’erreur pendant le push qui serait de faire partiel (mais bon tu peux résoudre le souci en second temps pour repartir propre au pire.



Et merci pour les retours sur la série :chinois:


Mais vous régalez en fait. Merci pour cette série sur Git.



tomdom a dit:


Questions :




  • On peut ajouter un dépot distant supplémentaire directement sur origin (si on sait que l’on veut toujours envoyer sur l’ensemble des dépots) ?




En gros, ton repo local pointe sur origin, et origin pointe sur un autre repo ?



Si oui, ça s’appelle du mirroring.



Toute la question est de savoir comment se passe la synchronisation.



Si tu as un repo bare + mirror (git clone –mirror), alors les branches du repo sont écrasées par les modifications de son remote, dés lors que tu fetch le remote manuellement (eg: git –git-dir “lerepobare.git” fetch)



Les outils comme BitBucket/GitLab/GitHub/etc, proposent plus de choix.





  • Que se passe-t-il si un des dépots n’est pas disponible au moment du push ? Est-ce que lorsque le dépot redevient disponible, git status montrera que la copie locale est en avance par rapport à ce dépot distant ?



Super série d’articles :yes:




Rien : ça échoue et ta référence origin/develop restera à l’état où elle était.



Par ailleurs, comme alternative aux remote bare, il y a aussi les bundle (git bundle) qui permet de travailler avec des repo hors lignes :)


Git bundle de mémoire c’est surtout pour générer une archive qui sera ensuite poussée sur un autre dépôt (quand il n’y a pas de lien possible directement entre les deux) non ?



David_L a dit:


Git bundle de mémoire c’est surtout pour générer une archive qui sera ensuite poussée sur un autre dépôt (quand il n’y a pas de lien possible directement entre les deux) non ?




C’est vendu comme permettant de créer une archive en cas de non accès au réseau: https://git-scm.com/docs/git-bundle




Some workflows require that one or more branches of development on one machine be replicated on another machine, but the two machines cannot be directly connected, and therefore the interactive Git protocols (git, ssh, http) cannot be used.




Le problème des repo bare (dans la news), c’est pourquoi tu veux t’en servir : sur une clef USB, modulo la rapidité, ça peut passer, mais sur un disque en ligne (grogle drive, onedrive, etc), j’ai plutôt eu des écueils car la synchronisation peut parfois casser l’intégrité du repo : git va de temps à autre effectuer un garbage collector, qui aura pour effet de créer un fichier pack des objets dans GIT_DIR/objects. Or, ça, ça modifie/supprime pas mal de fichier et c’est là que le drive risque d’échouer.



Un bundle en revanche, c’est comme un zip du repo, mais en limitant le scope à ce que tu veux (même si –all quoi :D) et si la doc fait un clone, tu peux en fait rajouter un bundle comme remote et profiter de ses références :)



(et pour conclure, je ne parlerais pas git fast-export :D)


Je peux voir l’état de ma branche locale directement dans la ligne de commande grâce à __git_ps1.



Dans le .bashrc, il suffit d’ajouter.



export GIT_PS1_SHOWDIRTYSTATE=1
export GIT_PS1_SHOWSTASHSTATE=1
export GIT_PS1_SHOWUPSTREAM=auto



Et ensuite, par exemple,



PS1=’\({debian_chroot:+(\)debian_chroot)}[\033[00;34m]\u@\h:[\033[00m][[\033[01;34m]\w[\033[00m]][\033[0;32m]\((__git_ps1)[\033[00m\] \\) ‘;;



C’est la mise en forme de la ligne affichée quand tu te connectes à un terminal.



Apparaîtra alors à côté du nom de la branche son statut par rapport à l’origine :



branche>, je suis en avance
branche<, je suis en retard
branche=, nous sommes égaux.


Oui on en reparlera sous peu, mais outre la retouche à la main du PS1 tu as aussi les thèmes Zsh qui ouvrent pas mal de possibilités sans trop se casser la tête là dessus par exemple.


David_L

Oui on en reparlera sous peu, mais outre la retouche à la main du PS1 tu as aussi les thèmes Zsh qui ouvrent pas mal de possibilités sans trop se casser la tête là dessus par exemple.


Ah pardon, je ne veux pas spoiler le prochain article :D


Je ne vois pas de usecase ou cela serait nécessaire?
Vous avez des exemples ?


Il y a des projets de logiciels libres qui hébergent et maintiennent leur code sur leur propre instance Gitlab (ou équivalent), mais publient en parallèle sur un GitHub en read only pour bénéficier de la visibilité de ce dernier.



David_L a dit:


Oui on en reparlera sous peu, mais outre la retouche à la main du PS1 tu as aussi les thèmes Zsh qui ouvrent pas mal de possibilités sans trop se casser la tête là dessus par exemple.




+1 pour zsh et les thèmes.
Je vois pas trop l’intérêt de s’embêter à configurer le PS1 à la main aujourd’hui. Il y a forcément un thème qui couvre ton besoin.


Certains aiment bien mettre la main dans le cambouis et au moins tu sais ce que tu fais. Pas mal utilisent zsh et des thèmes “parce qu’un tuto youtube” sans même savoir ce qu’est PS1 :D