Synchroniser de façon réfléchie
- Leçon 5
- 40 min
- Module 2 : Travailler avec les branches et les dépôts distants
Leçon 5 sur 15 · L'essentiel de Git et du développement en équipeSynchroniser de façon réfléchie
1. Comprendre un dépôt
2. Travailler avec les branches et les dépôts distants
3. Collaborer par la revue de code
4. Résoudre et récupérer
5. Mises en production et correctifs urgents
Ce que vous saurez faire
Partagez vos commits (instantanés enregistrés) avec une équipe et récupérez les siens, sans surprises. Après cette leçon, vous pourrez dire exactement ce que chaque commande a changé : votre dépôt ou le dépôt distant.
Avant de commencerCe qu’il faut savoir et avoir sous la main
Ce que vous devez savoir
- Comment créer des branches et changer de branche avec
git switch -cetgit switch. Consultez Bases des branches : une branche est une étiquette sur un commit. - Ce que sont un clone et
origin, présentés dans Configurer Git : exemple détaillé : cloner un dépôt.
Ce qu’il vous faut sur votre ordinateur
-
Le dépôt
~/projects/ticket-notesavec les branchesmainetadd-priorities. Vous avez crééadd-prioritiesdans Bases des branches : exercice guidé : travailler sur une branche. Si elle manque, refaites cet exercice guidé. -
Dans le dépôt,
git statusafficheworking tree clean(arbre de travail propre). -
Pour la tâche « À vous de jouer », la branche
add-contacts. Vous l’avez créée dans Bases des branches : à vous de jouer : une deuxième branche. Si vous ne l’avez pas, la tâche explique comment la créer. -
Si le dépôt manque ou ne fonctionne plus, un script peut recréer l’état de départ de cette leçon. Dans
~/projects, exécutez :Fenêtre de terminal git clone https://github.com/Nextia-Intelligence/nextia-learning-labs.gitsh nextia-learning-labs/C14/setup.sh m02-l02 --resetExécutez la commande
git cloneune seule fois. Si vous avez déjà le dossiernextia-learning-labs, exécutez plutôtgit -C nextia-learning-labs pull. Les étapes d’une demande de tirage : préparer le laboratoire d’exercice explique le script en détail. Le script crée~/projects/c14-lab/ticket-notesavecmainàd8ae027etadd-prioritiesà999a7c4, les mêmes empreintes que dans cette leçon. Ce dépôt n’a ni dépôt distant ni brancheadd-contacts. Les commits que vous créez dans cette leçon, comme Amira ou Sam, ont des empreintes différentes de celles présentées, par exemple1d45995. C’est normal. Utilisez ensuite~/projects/c14-labà la place de~/projectsdans cette leçon.--resetsupprime d’abord un ancien dossierc14-lab, mais votre dépôt~/projects/ticket-notesne change pas. -
Vous n’avez pas besoin d’un compte sur un site Web. Dans cette leçon, le dépôt distant est un dossier sur votre ordinateur. Vous le créez dans Créer un dépôt distant d’exercice.
Votre copie du dépôt distant
Section intitulée « Votre copie du dépôt distant »Dans Configurer Git, vous avez appris qu’un dépôt distant est une copie du dépôt à un autre endroit. Votre équipe l’utilise pour partager son travail. Git ne reste pas connecté au dépôt distant. Il se connecte seulement quand vous exécutez l’une de ces trois commandes :
| Commande | Ce qu’elle change |
|---|---|
git fetch |
Récupère les nouveaux commits du dépôt distant. Met à jour seulement votre représentation du dépôt distant. Vos branches et fichiers ne changent pas. |
git pull |
Exécute git fetch, puis met à jour votre branche courante avec les nouveaux commits. |
git push |
Envoie vos nouveaux commits au dépôt distant et déplace la branche sur ce dépôt. |
Votre « représentation du dépôt distant » est un ensemble de branches de suivi à distance, avec des noms comme origin/main. origin/main indique où se trouvait main sur le dépôt distant lors de votre dernière connexion. Elle ne se met pas à jour toute seule. Si un collègue pousse des commits, origin/main reste inchangée jusqu’à ce que vous exécutiez git fetch.
Votre branche main est liée à origin/main. Ce lien fait de origin/main la branche en amont de main, et de main une branche de suivi. Grâce à ce lien, git status, git pull et git push savent quelle branche distante comparer et utiliser.
Créer un dépôt distant d’exercice
Section intitulée « Créer un dépôt distant d’exercice »Une équipe garde généralement son dépôt distant sur un serveur, comme GitHub. Le serveur conserve un dépôt nu : un dépôt avec seulement l’historique, sans arbre de travail. Personne n’y modifie de fichiers. On y pousse seulement des commits, ou on en récupère.
Vous pouvez créer un dépôt nu dans un dossier et l’utiliser comme dépôt distant. Git le traite comme un serveur.
-
Créez le dépôt nu à côté de
ticket-notes:Fenêtre de terminal cd ~/projectsgit init --bare team-remote.gitInitialized empty Git repository in /Users/amira/projects/team-remote.git/Par convention, le nom se termine par
.gitpour indiquer que le dossier est un dépôt nu. -
Ouvrez
ticket-noteset reliez-le au nouveau dépôt distant sous le nomorigin:Fenêtre de terminal cd ticket-notesgit remote add origin ../team-remote.gitgit remote -vorigin ../team-remote.git (fetch)origin ../team-remote.git (push)..désigne le dossier parent. Le chemin pointe donc vers~/projects/team-remote.git. -
Configurez Git pour que
git pullfasse une mise à jour seulement quand elle est sans risque. L’exemple détaillé explique pourquoi.Fenêtre de terminal git config --global pull.ff only
Exemple détaillé : Amira et Sam partagent leur travail
Section intitulée « Exemple détaillé : Amira et Sam partagent leur travail »Amira pousse ses commits
Section intitulée « Amira pousse ses commits »Amira envoie main au dépôt distant. L’option -u définit origin/main comme branche en amont de main. Vous avez besoin de -u seulement la première fois que vous poussez une branche.
git push -u origin mainTo ../team-remote.git * [new branch] main -> mainbranch 'main' set up to track 'origin/main'.Elle pousse aussi sa branche de fonctionnalité pour que son équipe puisse la voir :
git push -u origin add-prioritiesgit branch -vvTo ../team-remote.git * [new branch] add-priorities -> add-prioritiesbranch 'add-priorities' set up to track 'origin/add-priorities'. add-priorities 999a7c4 [origin/add-priorities] Add priority levels* main d8ae027 [origin/main] Add first ticket notegit branch -vv affiche chaque branche, son commit et sa branche en amont entre crochets.
Sam pousse un nouveau commit
Section intitulée « Sam pousse un nouveau commit »Sam est le collègue d’Amira. Il clone le dépôt distant, ajoute un billet (de soutien) à tickets.txt, crée un commit et le pousse. Après le clonage, la branche en amont est déjà définie. Sam n’a donc pas besoin de -u :
git clone team-remote.git sam-notescd sam-notesgit commit -am "Add ticket 102"git pushTo /Users/sam/projects/team-remote.git d8ae027..1d45995 main -> maingit commit -am prépare tous les fichiers suivis qui ont changé et crée un commit en une seule étape. d8ae027..1d45995 signifie que main sur le dépôt distant est passée de d8ae027 à 1d45995.
Amira récupère les commits, puis met sa branche à jour
Section intitulée « Amira récupère les commits, puis met sa branche à jour »Amira ne connaît pas encore le commit de Sam. git status indique toujours qu’elle est à jour, car il compare sa branche avec son ancienne origin/main. Elle récupère les commits :
git fetchgit statusFrom ../team-remote d8ae027..1d45995 main -> origin/mainOn branch mainYour branch is behind 'origin/main' by 1 commit, and can be fast-forwarded. (use "git pull" to update your local branch)La récupération a déplacé seulement origin/main. Sa branche main et ses fichiers n’ont pas changé. Avant d’intégrer le nouveau commit, elle vérifie ce qu’il change. La comparaison des différences compare sa branche main avec origin/main :
git diff main origin/maindiff --git a/tickets.txt b/tickets.txtindex c1b66eb..e2b0391 100644--- a/tickets.txt+++ b/tickets.txt@@ -1 +1,2 @@ Ticket 101: printer offline. Restarted the spooler.+Ticket 102: password reset email not received.Le changement est correct. Elle met donc sa branche à jour :
git pullUpdating d8ae027..1d45995Fast-forward tickets.txt | 1 + 1 file changed, 1 insertion(+)L’avance rapide signifie que Git a seulement déplacé l’étiquette main jusqu’au commit de Sam. C’est possible parce qu’Amira n’avait aucun nouveau commit à elle sur main. Aucun nouveau commit n’a été créé.
Les deux personnes créent un commit en même temps
Section intitulée « Les deux personnes créent un commit en même temps »Sam pousse maintenant un deuxième billet. En même temps, Amira crée un commit avec un nouveau fichier, contacts.txt, sur sa branche main. Elle essaie de le pousser :
git pushTo ../team-remote.git ! [rejected] main -> main (fetch first)error: failed to push some refs to '../team-remote.git'hint: Updates were rejected because the remote contains work that you do nothint: have locally. ...Le dépôt distant refuse l’envoi. S’il l’acceptait, le commit de Sam disparaîtrait de main. Amira tente de mettre sa branche à jour :
git pullFrom ../team-remote 1d45995..7d54ed4 main -> origin/mainhint: Diverging branches can't be fast-forwarded, ...fatal: Not possible to fast-forward, aborting.La récupération a fonctionné, mais Git n’a pas changé main. Les historiques ont divergé : chaque côté a un commit que l’autre n’a pas. git log --oneline --graph --all montre la séparation :
* 01f2b94 (HEAD -> main) Add contacts| * 7d54ed4 (origin/main, origin/HEAD) Add ticket 103|/* 1d45995 Add ticket 102C’est pourquoi vous avez défini pull.ff only. Sans ce réglage, git pull peut réunir les deux historiques automatiquement, sans que vous le remarquiez. Avec ce réglage, Git s’arrête et vous choisissez quoi faire.
Amira décide de faire une fusion (merge). Elle réunit les deux lignes d’historique avec un nouveau commit qui a les deux comme parents. L’option --no-edit conserve le message que Git suggère :
git pull --no-rebase --no-editgit log --oneline --graph -4Merge made by the 'ort' strategy. tickets.txt | 1 + 1 file changed, 1 insertion(+)* 7f87ca6 (HEAD -> main) Merge branch 'main' of ../team-remote|\| * 7d54ed4 (origin/main, origin/HEAD) Add ticket 103* | 01f2b94 Add contacts|/Sa branche main contient maintenant les deux commits. Elle peut donc les pousser sans risque :
git pushTo ../team-remote.git 7d54ed4..7f87ca6 main -> mainExercice guidé : jouer les deux rôles
Section intitulée « Exercice guidé : jouer les deux rôles »Vous jouez Amira dans ticket-notes et Sam dans un deuxième clone.
-
Créez le dépôt distant d’exercice et reliez-le, comme dans Créer un dépôt distant d’exercice.
-
Dans
ticket-notes, poussez les deux branches :Fenêtre de terminal git push -u origin maingit push -u origin add-priorities -
Exécutez
git branch -vv. Chaque branche affiche sa branche en amont entre crochets. -
Créez le clone de Sam et ouvrez-le :
Fenêtre de terminal cd ~/projectsgit clone team-remote.git sam-notescd sam-notes -
Ajoutez une ligne à
tickets.txtdanssam-notes, puis créez un commit et poussez-le :Fenêtre de terminal git commit -am "Add ticket 102"git push -
Retournez dans
ticket-noteset exécutezgit status. Il indique encoreup to date(à jour), car vous n’avez pas récupéré les commits. -
Récupérez les commits et vérifiez de nouveau :
Fenêtre de terminal cd ~/projects/ticket-notesgit fetchgit statusLa sortie indique
behind 'origin/main' by 1 commit(un commit de retard sur origin/main). -
Exécutez
git diff main origin/main. La sortie montre la nouvelle ligne. -
Exécutez
git pull. La sortie contientFast-forward(avance rapide). -
Exécutez
git log --oneline -1. Le commit le plus récent est celui de l’étape 5.
À vous de jouer : partager une branche de fonctionnalité
Section intitulée « À vous de jouer : partager une branche de fonctionnalité »L’équipe veut examiner votre branche add-contacts de la leçon Bases des branches. Si vous ne l’avez pas, créez-la à partir de main maintenant.
- Poussez
add-contactsvers le dépôt distant et définissez sa branche amont. - Dans
sam-notes, récupérez la branche avecgit fetch, puis exécutezgit switch add-contacts. Git crée une branche locale qui suitorigin/add-contacts. - Dans
sam-notes, ajoutez un nom àcontacts.txt, créez un commit (enregistrement des changements), puis poussez-le. - Dans
ticket-notes, intégrez le nouveau commit à votre brancheadd-contacts.
Écrivez ensuite une phrase pour chaque commande utilisée : a-t-elle modifié votre historique local, le dépôt distant ou seulement votre copie de référence du dépôt distant?
Afficher une réponse modèle
git push -u origin add-contacts(dansticket-notes) : a modifié le dépôt distant. Elle y a crééadd-contacts.git fetch(danssam-notes) : a modifié seulement la copie de référence du dépôt distant : elle a ajoutéorigin/add-contacts.git switch add-contacts(danssam-notes) : a modifié l’historique local dans le clone de Sam. Elle a créé une nouvelle branche locale.git commit(danssam-notes) : a modifié l’historique local dans le clone de Sam.git push(danssam-notes) : a modifié le dépôt distant.git switch add-contacts, puisgit pull(dansticket-notes) : la commande pull a récupéré les changements, puis modifié l’historique local. Elle a fait avancer votre brancheadd-contactspar une avance rapide.
Erreur courante
Envoi refusé : récupérer d'abord
Symptôme : git push affiche ! [rejected] main -> main (fetch first) (envoi refusé, récupérer d’abord), ou (non-fast-forward) (avance rapide impossible).
Cause : la branche distante contient des commits que vous n’avez pas. Git refuse l’envoi pour éviter de perdre ces commits.
Solution :
- Exécutez
git pull. - Si la commande pull affiche
Fast-forward(avance rapide), exécutez de nouveaugit push. - Si elle affiche
Not possible to fast-forward(avance rapide impossible), exécutezgit log --oneline --graph --allpour voir les deux historiques. Exécutez ensuitegit pull --no-rebase --no-editpour les fusionner, puis poussez de nouveau.
Ne forcez jamais l’envoi pour « corriger » un refus. Un envoi forcé remplace la branche distante par la vôtre. Les commits de votre collègue disparaissent alors de cette branche. Le module 4 explique quand il est acceptable de réécrire un historique partagé.
Erreur courante
Aucune branche amont
Symptôme : git push affiche fatal: The current branch add-contacts has no upstream branch. (la branche actuelle add-contacts n’a aucune branche amont). Ou git pull affiche There is no tracking information for the current branch. (aucune information de suivi pour la branche actuelle).
Cause : cette branche n’est pas encore liée à une branche distante. Habituellement, vous l’avez créée localement sans jamais la pousser.
Solution : poussez-la une fois avec -u, par exemple git push -u origin add-contacts. Ensuite, git push et git pull fonctionnent sans options supplémentaires.
Vérifiez votre compréhension
Prédisez : Sam pousse un commit. Amira exécute git fetch. Les fichiers de son arbre de travail changent-ils? Sa branche main change-t-elle?
Afficher la réponse
Non dans les deux cas. git fetch modifie seulement origin/main, sa copie de référence du dépôt distant. Ses fichiers et sa branche main restent inchangés jusqu’à ce qu’elle exécute git pull (ou fusionne elle-même origin/main).
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
Vérification finale : dans l'exemple détaillé, quelles commandes ont modifié l'historique local d'Amira, et lesquelles ont mis à jour le dépôt distant?
Afficher la réponse
- L’historique local :
git commit(Add contacts, soit « Ajouter des contacts »),git pullpar avance rapide etgit pull --no-rebase --no-edit, qui a créé un commit de fusion. - Le dépôt distant : chaque
git push. Les deux premiers ont créé de nouvelles branches dans le dépôt distant. Le dernier a déplacé la branche distantemainvers le commit de fusion. - Ni l’un ni l’autre :
git fetcha mis à jour seulementorigin/main. Legit pullqui a échoué a fait de même : la récupération a fonctionné, puis il s’est arrêté avant de modifiermain. Legit pushrefusé n’a rien modifié.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Récapitulatif
origin/mainest votre copie de référence du dépôt distant. Seulgit fetch(ougit pull) la met à jour.git fetchne modifie aucune de vos branches.git pullrécupère les changements, puis met à jour votre branche actuelle.git pushmet à jour le dépôt distant.-ulie une branche à sa branche amont la première fois que vous la poussez.- Une avance rapide déplace seulement une étiquette. Quand les historiques ont divergé, vous devez les réunir, par exemple avec une fusion.
- Avec
pull.ff only, Git ne réunit jamais des historiques divergents sans votre décision.
Leçon suivante : Garder le dépôt propre