Chapitre 816 minDébutant
GitHub : clé SSH, git push, git pull et git clone
Par Josselyn C., prof de BTS SIO. Mis à jour le .
À la fin de ce chapitre, tu sauras
- t'authentifier sur GitHub en HTTPS ou avec une clé SSH ;
- publier un dépôt local et cloner un dépôt existant ;
- distinguer
git fetchetgit pull, et lireorigin/main; - corriger les erreurs de push courantes et contribuer par un fork.
4 exercices corrigés1 schéma
Pour travailler avec GitHub, tu relies ton dépôt local à un dépôt distant : git push y envoie tes commits, git pull récupère ceux des autres, git fetch télécharge sans rien intégrer, et git clone copie un dépôt existant sur ta machine. Avant cela, il faut t'authentifier, car GitHub refuse les mots de passe depuis 2021 : clé SSH, GitHub CLI ou jeton d'accès. Ce chapitre couvre le compte et l'authentification, la création du dépôt distant, les commandes d'échange, les branches de suivi et les erreurs que tu rencontreras forcément.
Créer son compte GitHub
Crée ton compte sur github.com avec une adresse que tu garderas après le BTS : ton GitHub te suivra en entretien d'embauche. Choisis un nom d'utilisateur professionnel (lina-morel, pas darkgamer93).
Deux réglages dès le départ :
- La double authentification (2FA), avec une application d'authentification ou une clé de sécurité. GitHub l'exige pour les comptes qui publient du code ; active-la tout de suite et range les codes de secours.
- Le pack étudiant (GitHub Student Developer Pack), sur education.github.com, avec ton adresse ou ton certificat de scolarité. Il donne gratuitement GitHub Pro (dépôts privés avec plus de fonctions, dont la protection de branche) et des offres de nombreux services pour développeurs.
Dans tes réglages, la page Emails propose de garder ton adresse privée : GitHub te donne alors une adresse de la forme 12345678+lina-morel@users.noreply.github.com à utiliser dans git config user.email, et ta vraie adresse n'apparaît pas dans les commits publics.
S'authentifier sur GitHub en HTTPS ou en SSH
Git échange avec GitHub par deux protocoles, et l'adresse du dépôt change selon le choix :
| Protocole | Adresse du dépôt | Authentification |
|---|---|---|
| HTTPS | https://github.com/ton-pseudo/sorbier-frais.git | Un gestionnaire d'identifiants (GitHub CLI, Git Credential Manager) ou un jeton d'accès personnel |
| SSH | git@github.com:ton-pseudo/sorbier-frais.git | Une paire de clés : la clé privée sur ton poste, la clé publique déclarée sur GitHub |
Méthode 1 : GitHub CLI, la plus simple. L'outil officiel gh (winget install --id GitHub.cli, brew install gh, ou le paquet gh de ta distribution) gère la connexion par le navigateur :
gh auth login
Réponds GitHub.com, HTTPS, Login with a web browser, copie le code affiché et colle-le dans la page qui s'ouvre. gh configure Git pour utiliser cette connexion, et tu n'as plus rien à taper. Sous Windows, Git for Windows fournit aussi Git Credential Manager, qui ouvre une fenêtre de connexion GitHub au premier push.
Méthode 2 : clé SSH, la plus répandue chez les professionnels. Génère une paire de clés de type Ed25519 :
ssh-keygen -t ed25519 -C "lina.morel@example.com"
Accepte l'emplacement proposé (~/.ssh/id_ed25519) et choisis une phrase de passe : sans elle, quiconque copie ton fichier de clé privée se connecte à ta place. La commande crée deux fichiers :
| Fichier | Rôle | À partager ? |
|---|---|---|
~/.ssh/id_ed25519 | Clé privée, qui prouve ton identité | Jamais. Ni par messagerie, ni dans un dépôt |
~/.ssh/id_ed25519.pub | Clé publique, qui permet de vérifier la preuve | Oui : c'est elle que tu donnes à GitHub |
Affiche la clé publique (cat ~/.ssh/id_ed25519.pub), copie la ligne entière, puis colle-la sur GitHub dans Settings, SSH and GPG keys, New SSH key. Teste :
ssh -T git@github.com
Hi lina-morel! You've successfully authenticated, but GitHub does not provide shell access.
La première fois, SSH te demande de confirmer l'empreinte du serveur de GitHub : compare-la avec celles publiées dans la documentation de GitHub avant de répondre yes. Pour ne pas retaper la phrase de passe à chaque push, l'agent SSH la garde en mémoire pendant ta session (ssh-add, et sous macOS l'option --apple-use-keychain).
Le cours Linux : administration explique SSH en détail : clés, agent, connexion à un serveur.
Méthode 3 : jeton d'accès personnel. Un jeton (personal access token) remplace le mot de passe en HTTPS. Préfère les jetons à portée fine (fine-grained) : tu choisis le ou les dépôts concernés, les droits (lecture du contenu, écriture…) et une date d'expiration. Crée-le dans Settings, Developer settings, Personal access tokens. Il n'est affiché qu'une fois : copie-le dans ton gestionnaire de mots de passe. C'est la méthode à réserver aux scripts et aux serveurs, avec les droits les plus faibles possible.
Publier un dépôt local sur GitHub
Sur GitHub, clique sur + puis New repository. Donne le nom sorbier-frais, choisis la visibilité (public ou privé), et ne coche rien (ni README, ni .gitignore, ni licence) : ton dépôt local a déjà un historique, et ces cases créeraient sur GitHub un premier commit qui n'a rien à voir avec le tien.
GitHub affiche alors les commandes à lancer. Relie ton dépôt local au dépôt distant et pousse :
git remote add origin git@github.com:ton-pseudo/sorbier-frais.git
git branch -M main
git push -u origin main
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Writing objects: 100% (9/9), 1.02 KiB | 1.02 MiB/s, done.
Total 9 (delta 0), reused 0 (delta 0), pack-reused 0
To github.com:ton-pseudo/sorbier-frais.git
* [new branch] main -> main
branch 'main' set up to track 'origin/main'.
| Élément | Signification |
|---|---|
git remote add origin <adresse> | Enregistre un dépôt distant sous le surnom origin, le nom conventionnel du distant principal |
git branch -M main | Renomme la branche courante en main, si elle s'appelait encore master |
git push -u origin main | Envoie la branche main vers origin ; -u (ou --set-upstream) mémorise le lien entre ta branche et la branche distante |
Grâce à -u, tu tapes ensuite simplement git push et git pull sur cette branche. Pour gérer les distants :
| Commande | Effet |
|---|---|
git remote -v | Liste les distants et leurs adresses |
git remote set-url origin <adresse> | Change l'adresse (passer de HTTPS à SSH, dépôt renommé) |
git remote rename origin github | Renomme un distant |
git remote remove origin | Supprime le lien (le dépôt sur GitHub n'est pas touché) |
Récupérer un dépôt existant avec git clone
Hugo rejoint le projet. Il n'a pas besoin de git init : il copie le dépôt existant, historique compris.
git clone git@github.com:ton-pseudo/sorbier-frais.git
cd sorbier-frais
Cloning into 'sorbier-frais'...
remote: Enumerating objects: 9, done.
remote: Counting objects: 100% (9/9), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 9 (delta 0), reused 9 (delta 0), pack-reused 0
Receiving objects: 100% (9/9), done.
git clone crée le dossier, télécharge tout l'historique, configure le distant origin et se place sur la branche par défaut. Tu peux choisir le nom du dossier (git clone <adresse> frais) ou une autre branche (git clone -b develop <adresse>).
Pour que Hugo puisse pousser, Lina l'ajoute comme collaborateur dans Settings, Collaborators, ou crée une organisation GitHub pour l'équipe, propriétaire du dépôt. git init et git clone ne se combinent jamais : on initialise un projet qui n'existe nulle part, on clone un projet qui existe déjà.
Branches de suivi : origin/main
Ton dépôt local garde une copie de l'état des branches distantes, telle qu'elle était lors de ta dernière communication avec le serveur : ce sont les branches de suivi (remote-tracking branches), nommées origin/main, origin/feature/export… Tu ne travailles jamais dessus directement : elles servent de repère.
git status compare ta branche à sa branche de suivi :
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
(use "git push" to publish your local commits)
| Message | Signification | Action |
|---|---|---|
Your branch is up to date with 'origin/main' | Rien à envoyer, rien de connu à récupérer | Rien, mais l'information date de ton dernier fetch |
Your branch is ahead of 'origin/main' by 2 commits | Tu as 2 commits non poussés | git push |
Your branch is behind 'origin/main' by 3 commits | Le serveur a 3 commits que tu n'as pas intégrés | git pull |
Your branch and 'origin/main' have diverged | Les deux ont avancé de leur côté | git pull (fusion ou rebase), puis git push |
git fetch ou git pull ?
git fetch télécharge les nouveaux commits et met à jour les branches de suivi (origin/main), sans modifier tes branches ni tes fichiers. Tu peux ensuite regarder ce qui a changé avant de l'intégrer :
git fetch
git log --oneline main..origin/main # les commits du serveur que tu n'as pas
git diff main origin/main # les modifications correspondantes
git pull fait un fetch puis intègre la branche de suivi dans ta branche courante : par une fusion (git merge origin/main), ou par un rebase si tu as réglé pull.rebase true.
git fetch | git pull | |
|---|---|---|
| Télécharge les commits | Oui | Oui |
Met à jour origin/main | Oui | Oui |
| Modifie ta branche et tes fichiers | Non | Oui |
| Peut provoquer un conflit | Non | Oui |
| Quand l'utiliser | Pour voir avant d'intégrer, ou mettre à jour toutes les branches de suivi (git fetch --all --prune) | Au quotidien, pour te mettre à jour |
L'option --prune (git fetch --prune) supprime les branches de suivi dont la branche a été supprimée sur le serveur, après la fusion d'une pull request par exemple.
Le rituel de l'équipe
git switch main
git pull # 1. partir de la dernière version
git switch -c feature/export # 2. une branche par sujet
# ... commits ...
git push -u origin feature/export # 3. publier la branche
# 4. ouvrir une pull request sur GitHub (chapitre 9)
Pull avant de commencer, push quand tu as fini : tu limites les divergences, et donc les conflits.
Les erreurs de push courantes
Le serveur a des commits que tu n'as pas.
! [rejected] main -> main (fetch first)
error: failed to push some refs to 'github.com:ton-pseudo/sorbier-frais.git'
hint: Updates were rejected because the remote contains work that you do not
hint: have locally. This is usually caused by another repository pushing to
hint: the same ref.
Quelqu'un a poussé avant toi. Récupère et intègre (git pull), résous les éventuels conflits, puis pousse de nouveau. Ne force pas : --force effacerait le travail de ton coéquipier.
Le dépôt GitHub a été créé avec un README. Les deux historiques n'ont aucun commit commun. Avec le réglage pull.rebase true du chapitre 1, git pull origin main rejoue simplement tes commits par-dessus le README (résous le conflit si ton dépôt a aussi un README.md). En mode fusion, Git refuse avec fatal: refusing to merge unrelated histories : ajoute alors --allow-unrelated-histories.
La branche est protégée. remote: error: GH006: Protected branch update failed : l'équipe interdit le push direct sur main. Pousse une branche et ouvre une pull request (chapitre 9).
Le fichier est trop gros. GitHub refuse les fichiers de plus de 100 Mo et avertit au-delà de 50 Mo. Un fichier aussi lourd n'a souvent rien à faire dans le dépôt (sauvegarde, vidéo, dépendances) : retire-le de l'historique. Pour les gros fichiers indispensables (maquettes, jeux de données), Git LFS les stocke à part.
Permission refusée en SSH. git@github.com: Permission denied (publickey) : ta clé n'est pas déclarée sur GitHub, ou SSH n'utilise pas la bonne. ssh -T git@github.com le confirme ; ssh -vT git@github.com montre les clés essayées.
Contribuer au dépôt d'un autre avec un fork
Tu n'as pas le droit de pousser sur le dépôt d'un projet dont tu n'es pas membre. Pour proposer une modification, tu crées un fork : une copie du dépôt dans ton compte GitHub, bouton Fork. Tu clones ton fork, tu travailles sur une branche, tu pousses vers ton fork, puis tu ouvres une pull request vers le dépôt d'origine.
Pour garder ton fork à jour, ajoute le dépôt d'origine comme second distant, appelé upstream par convention :
git remote add upstream https://github.com/projet-libre/outil.git
git fetch upstream
git switch main
git merge upstream/main
git push origin main
Le bouton Sync fork de GitHub fait la même chose depuis le navigateur. Le fork est la base de la contribution aux logiciels libres ; c'est aussi la façon de récupérer le sujet d'un TP publié par ton professeur sur GitHub.
Exercices
Exercice 1 sur 4 Fetch ou pull Réussi À revoir
git status affiche Your branch is up to date with 'origin/main', mais Hugo te dit qu'il vient de pousser trois commits sur main.
- Pourquoi
git statusne les voit-il pas ? - Quelle commande te montre ces commits sans modifier tes fichiers ?
- Après cette commande, que dit
git status? - Quelle commande les intègre à ta branche ?
Voir la réponseMasquer la réponse de l'exercice 1
git statuscompare ta branche àorigin/main, la copie locale de l'état du serveur. Elle date de ton dernier échange : Git ne contacte pas GitHub pour unstatus.git fetch, puisgit log --oneline main..origin/main.Your branch is behind 'origin/main' by 3 commits, and can be fast-forwarded.git pull. Comme tu n'as pas de commit local, c'est une avance rapide, sans fusion ni rebase.
Tu avais trouvé ?
Exercice 2 sur 4 Publier un projet existant Réussi À revoir
Tu as un dépôt local portfolio de 12 commits, sur une branche nommée master. Tu viens de créer sur GitHub le dépôt vide ton-pseudo/portfolio. Écris les commandes pour le publier en SSH, avec une branche main, de façon à n'avoir ensuite qu'à taper git push.
Voir la réponseMasquer la réponse de l'exercice 2
git remote add origin git@github.com:ton-pseudo/portfolio.git
git branch -M main
git push -u origin main
git branch -M main renomme master en main. -u mémorise le lien entre main et origin/main.
Tu avais trouvé ?
Exercice 3 sur 4 Diagnostiquer Réussi À revoir
Pour chaque message, donne la cause et la solution.
remote: Support for password authentication was removed on August 13, 2021.! [rejected] main -> main (fetch first)git@github.com: Permission denied (publickey).fatal: refusing to merge unrelated historiesremote: error: GH006: Protected branch update failed for refs/heads/main.
Voir la réponseMasquer la réponse de l'exercice 3
- Tu as tapé ton mot de passe GitHub en HTTPS. Connecte-toi avec
gh auth login, Git Credential Manager ou un jeton, ou passe en SSH. - Le serveur contient des commits que tu n'as pas.
git pull, résoudre les conflits éventuels, puisgit push. - GitHub ne reconnaît pas ta clé SSH : ajoute ta clé publique dans tes réglages, ou vérifie avec
ssh -vT git@github.comquelle clé est présentée. - Le dépôt distant a un historique sans rapport avec le tien, en général parce qu'il a été créé avec un README, et
git pullest en mode fusion.git pull --rebase origin mainrejoue tes commits par-dessus le README ; pour garder la fusion,git pull origin main --allow-unrelated-histories. mainest protégée : pousse ta branche et ouvre une pull request.
Tu avais trouvé ?
Exercice 4 sur 4 Clé SSH Réussi À revoir
- Quel fichier donnes-tu à GitHub :
id_ed25519ouid_ed25519.pub? Pourquoi ? - À quoi sert la phrase de passe ?
- Ton ordinateur portable est volé. Que fais-tu côté GitHub ?
Voir la réponseMasquer la réponse de l'exercice 4
id_ed25519.pub, la clé publique. Elle permet seulement de vérifier une signature ; la clé privéeid_ed25519, elle, permet de te faire passer pour toi et ne quitte jamais ton poste.- Elle chiffre la clé privée sur le disque : un voleur qui copie le fichier ne peut pas l'utiliser sans la phrase.
- Supprimer la clé SSH de ce portable dans Settings, SSH and GPG keys, révoquer les jetons créés pour lui, fermer les sessions ouvertes et changer le mot de passe du compte. Puis générer une nouvelle paire sur le nouvel ordinateur.
Tu avais trouvé ?