Commandes git¶
La moitié du test devrait porter sur les commandes git, donc voici celles que je juge importantes à connaitre.
Config¶
Il y a 3 niveaux: --system, --global et --local (le local gagne sur le global, qui gagne sur le system).
Avant de commit quoi que ce soit, il faut que user.name et user.email aient qqch de valide.
git config --global user.name "mon nom"
git config --global user.email "moi@mail.com"
git config --global init.defaultBranch main
# juste pour le repo courant
git config --local user.name "autre nom"
# tout voir
git config --global --list
Créer ou cloner un repo¶
git init # nouveau repo dans le dossier courant
git init --initial-branch=main # pareil mais en forçant le nom de la branche
git clone <url> # cloner dans un nouveau dossier
git clone <url> . # cloner dans le dossier courant (il doit être vide)
Les 3 zones¶
Avant les commandes, il faut comprendre où vivent les fichiers. Un fichier passe par 3 zones:
working directory staging (index) HEAD (dernier commit)
----------------- --------------- ---------------------
mes fichiers, tels --> ce qui partira dans --> le dernier commit de
que je les édite add le prochain commit commit la branche courante
| Zone | C'est quoi |
|---|---|
| working directory (work) | les fichiers sur le disque |
| staging | la "liste d'attente" de ce qui sera dans le prochain commit |
| HEAD | pointeur vers le dernier commit de la branche où je suis |
git addcopie work -> staginggit commitstaging -> HEAD (en gros) (ce qui sera push sur le remote)
Les bases¶
git status # ce qui a changé
git add fichier # mettre un fichier dans le staging
git add . # tout mettre dans le staging
git commit -m "message" # valider (voir conventional commits)
Annuler des choses¶
| Je veux | Commande |
|---|---|
| jeter les modifs d'un fichier (perdues pour de bon) | git restore fichier |
| retirer un fichier du staging (modifs gardées) | git restore --staged fichier |
| corriger le dernier commit (pas encore push) | git commit --amend |
| annuler le dernier commit mais garder les modifs | git reset HEAD~1 |
| annuler le dernier commit et jeter les modifs | git reset --hard HEAD~1 |
| annuler un commit déjà push (nouveau commit inverse) | git revert <hash> |
Warning
Ne pas reset ou amend un commit qui est déjà sur le remote, ça réécrit l'historique des autres aussi. Si par pur hasard c'est trop tard, faites git push --force et osef.
Remotes¶
Un remote est un serveur distant (dans notre cas le gitlab). Chaque remote a un nom, normalement origin.
Sans remote, il n'est pas possible de fetch / pull / push.
git remote -v # lister les remotes
git remote add origin <url> # créer un remote (sans rien télécharger)
git remote remove origin # supprimer un remote
git remote rename ancien nouveau
| Commande | Ce qu'elle fait |
|---|---|
git fetch origin main |
télécharge main du remote dans origin/main, sans toucher à mes fichiers |
git pull origin main |
fetch + merge dans la branche courante |
git push |
envoie la branche courante (si l'upstream est défini) |
git push --set-upstream origin ma-branche |
pareil, mais définit l'upstream la 1ère fois |
refusing to merge unrelated histories
Si le repo local et le remote ont chacun leur propre premier commit (ex: on fait git init + un commit, puis git remote add d'un repo qui a déjà un README), git pull origin main refuse avec cette erreur. Il faut ajouter --allow-unrelated-histories.
Branches et merge¶
git branch # lister
git branch ma-branche # créer
git checkout ma-branche # y aller
git checkout -b ma-branche # créer + y aller
git branch -d ma-branche # supprimer (une fois mergée)
# merge: on se place sur la branche qui REÇOIT, puis on merge l'autre
git checkout main
git merge ma-branche # merge ma-branche dans main
En cas de conflit, git marque les fichiers concernés avec <<<<<<<, ======= et >>>>>>>. Il faut éditer à la main pour ne garder que ce qu'on veut, supprimer les marqueurs, puis:
git add fichier
git commit
Après normalement on gère les merge requests sur gitlab.
Tags¶
Un tag fait référernce à un "état" d'un code particulier.
Par exemple v1.0.0 fait référence à X moment dans le code (un commit).
git tag # lister
git tag v1.0.0 # créer sur le commit courant
git show v1.0.0
git push origin v1.0.0 # pousser un tag
git push --tags # pousser tous les tags
git tag -d v1.0.0 # supprimer en local
Les tags ne partent pas tout seuls avec git push. Et pousser un tag peut lancer une pipeline sur gitlab (voir rules et workflow).
Pour le format du nom (v1.0.0, v1.1.0, v2.0.0), voyez conventional commits.
.gitignore¶
Un fichier .gitignore à la racine, une ligne par chose à ignorer:
node_modules
dist
.env
Perso j'aime bien tout ignorer, puis enlever les contenus au fur et à mesure. Mais ça peut être un peu traître:
# ignore tout
*
# désignore le DOSSIER (et le dossier uniquement) "src"
!/src/
# désignore le CONTENU de "src"
!/src/**
# les gitlab ci
!/.gitlab-ci.yml
# autres configs
!/**/*.config.*
# désignore le readme et la license
!/LICENSE
!/README.md
Exemple¶
(Tiré du cours)
Créer un repo local avec un fichier, le commit, créer un lien origin vers exercice-base (sans cloner), récupérer uniquement main du remote, et faire apparaitre le README.md en local.
# dépôt local avec un fichier
git init
echo "IP" > ip.txt
git add ip.txt
git commit -m "chore: ajout d'ip.txt avec infos"
# lien vers le remote, SANS cloner
git remote add origin https://git.s2.rpn.ch/ict-324/exercice-base
# rapatrier que la branche main, puis mettre à jour le local
git fetch origin main
git pull origin main --allow-unrelated-histories