Git et contrôle de version
Apprendre Git
Principles essentielles
Utilisation de base
Config
git config --global user.name "Rong Zhou"
git config --global user.email "ron@ronzz.org"
git config user.<valeur>
git config credential.helper 'cache --timeout 36000' # --global
Rendre
.gitfichiers visible en VSCode:
CTRL+,>>Exclude> x**/.git
Visioner l'histoire de révision
git log --graph --oneline --decorate {branch-name : default HEAD }# --all --color
Pour une branche remote :
git fetch origin
# Voir les commits d'une branche distante origin/feature-x
git log --graph --oneline --decorate --color origin/feature-x
commit, branches, et rebase
git commit
git branch {branch_name}
git switch {branch_name/commit_name/relative_commit_reference} # e.g., {main/fec0/main^^|main~2 # La branche sera crée si elle n'existe pas encore --orphan : sans historique
git merge {branch_name} # Integrates changes from another branch into your current branch. The commit graph preserves the fact that two lines of development existed.
git branch -d {branch_name} # supprime une branche locale déjà fusionnée
git push origin --delete init # supprime davantage ref distante
git rebase {target_parent_branch_name} # -i pour interactive # Re‑applies commits from your current branch on top of another branch for a linear history.
rollback
git branch -f {branch/HEAD to be deplaced} {destination-branch/HEAD} # changer seulement le postionnement des branches et HEAD sans bouger les commits
git reset HEAD~1 # annule dernier commit (LOCAL seulement)
git revert HEAD # faire un nouveau commit qui en effet annule le dernier commit
# remarquez qu'en `reset` on specifie l'état cible où en `revert` on specifie le commit à annuler
Dupliquer un fichier/dossier d'une branche à une autre
git restore --source main resources/
Cherry Pick
git cherry-pick {commit_name}
git commit --amend
Tag
git tag {tag_name} {target_commit : default HEAD}
git describe {commit}
Stash
git stash push -m "Message descriptif" # -k Stasher uniquement les fichiers suivis -u include-untracked
git stash list
git stash show -p stash@{0}
git stash pop stash@{0}
git stash apply stash@{0} # Garde le stash après l'application. Utile pour l'appliquer sur différentes branches
git stash drop stash@{0} # Supprimer un stash spécifique
git stash clear # Supprimer tous (DANGER !)
Collaboration en ligne
Init : clone
git clone <URL>
git clone --single-branch --branch <nom-de-la-branche> <url>
.gitignore : à placer à la racine du dépôt Git
passwords.txt
*.txt
rm -rf .git
git init
git status # -s: montrer moin des détails
git add . # tout les modifications dois sont validé par `add` avant `commit`.*
git add <filename>*
git diff # --staged
git commit -m "message" -a # -a = add .
.inclut tous les fichiers dans les SOUS-DOSSIERs de répertoire actuel du terminal. Exécutezgit add .à la racine du répertoire de dépôt pour valider des changements sur tous les fichiers.
Annuler les modifications :
git rm --cached {files*} # Cesser de traquer des fichiers
git reset --soft HEAD~1 # roll-back dernier commit. --soft: ne changera pas les fichiers dans votre répertoire de travail, et les commits annulés sont conservé dans l'index comme 'staged', prêt pour refaire.
Repo à distance
git remote add origin <URL>
git branch -M main
git pull origin main # = fetch + merge. --rebase = fetch + rebase
git push -u origin main --force-with-lease # force-with-lease prévien l'écrasement accidentel des changements effectuer par les autres développeurs depuis votre dernier `pull`
git push --set-upstream origin bugfix1 # pousser nouvelle branche
Annuler les modifications
git revert HEAD~1
git restore --source=origin/main --worktree file.txt # restaure file.txt depuis origin/main dans le répertoire de travail
Revenir à l'état de distant (écraser des changements locals)
git fetch origin
git reset --hard origin/main
Pour restaurer uniquement certains fichiers à partir de la branche distante :
git restore --source=origin/main --staged --worktree chemin/vers/fichier1 chemin/vers/fichier2
Submodules et Subtrees
- Ajouter dépendance externe et la maintenir : submodule.
- Intégrer code externe pour simplifier le workflow des contributeurs : subtree.
Submodules
Un submodule lie le dépôt parent à un autre dépôt Git distinct. Le dépôt parent conserve une référence à un commit précis du sous‑dépôt, pas son historique complet, utile pour dépendances versionnées et pour garder l’historique séparé.
Ajouter un submodule
git submodule add https://github.com/orga/projet-externe.git path/to/submodule
git commit -m "Add submodule projet-externe"
Cloner un dépôt avec submodules
git clone --recurse-submodules <url>
# ou après clone
git submodule update --init --recursive
Mettre à jour un submodule
# aller dans le submodule, récupérer et checkout la version voulue
cd path/to/submodule
git fetch
git checkout main
git pull
# revenir au parent et enregistrer la nouvelle référence
cd ../..
git add path/to/submodule
git commit -m "Update submodule {projet-externe} to latest main"
Supprimer un submodule proprement
git submodule deinit -f path/to/submodule
git rm -f path/to/submodule
rm -rf .git/modules/path/to/submodule
git commit -m "Remove submodule"
Mise à jour automatisés
Suivre une branche automatiquement
git submodule add -b main https://github.com/orga/projet-externe.git path/to/submodule
- Remarque: même en suivant une branche, le parent enregistre un commit précis ; il faut toujours
git add+git commitdans le parent après mise à jour du submodule.
Mettre à jour directement depuis le parent
git submodule update --remote --merge
Avantages
- Historique séparé, dépendance versionnée, contrôle précis du commit utilisé.
Inconvénients
- Workflow plus complexe pour les contributeurs (init/update), gestion manuelle des mises à jour, pièges lors des merges et des clones sans
--recurse-submodules.
Subtrees
Concept
Un subtree intègre le contenu d’un dépôt externe directement dans un sous‑répertoire du dépôt parent tout en conservant la possibilité d’importer/exporter des changements entre les deux dépôts. Pas de .gitmodules, pas de dépôt séparé dans le dossier.
Ajouter un subtree
git remote add {projet-externe} https://github.com/orga/projet-externe.git
git fetch {projet-externe}
git subtree add --prefix=path/to/subtree {projet-externe} main --squash
--prefix: dossier où placer le code.--squash: regroupe l’historique importé en un seul commit (optionnel).
Mettre à jour depuis le remote
git subtree pull --prefix=path/to/subtree {projet-externe} main --squash
Pousser des changements vers le remote
git subtree push --prefix=path/to/subtree {projet-externe} main
Extraire un subtree en tant que nouveau dépôt
git subtree split --prefix=path/to/subtree -b {split-branch}
# puis push split-branch vers un remote
git push origin {split-branch}:refs/heads/main
Avantages
- Simplicité pour les contributeurs (pas d’init/update), tout est dans un seul dépôt, facile à cloner.
- Pas de dossiers
.gitimbriqués.
Inconvénients
- Historique externe peut être aplati si
--squashutilisé ; synchronisation bidirectionnelle moins naturelle que submodule pour workflows complexes. - Opérations
subtreepeuvent être plus lourdes pour de très gros historiques.
Quand utiliser quoi
- Submodule si vous voulez garder l’historique séparé, pinner une dépendance à un commit précis, ou si le sous‑projet est développé indépendamment (librairie, composant réutilisable).
- Subtree si vous préférez simplicité pour les contributeurs, intégrer le code directement dans le dépôt parent et éviter la gestion explicite des submodules.
Bonnes pratiques
- Documenter dans le README comment cloner et mettre à jour (
--recurse-submodulesougit submodule update --init --recursive). - Pour submodules, committer la mise à jour du pointeur dans le dépôt parent après avoir changé de commit dans le submodule.
- Pour subtrees, tester
pull/pushsur une branche dédiée avant de fusionner. - Éviter de mélanger submodule et subtree pour le même sous‑répertoire.
- Automatiser les mises à jour via CI si vous dépendez de versions externes (PR automatique, tests).
Opérations courant
Problèmes connu
Dossier nommé comme fichiers ❌
reveal.js/reveal.js ❌
git l'interpreter la premier reveal.js comme fichier Javascript et ignorer la actuel javascript.
Inclusion des .git dossier (potentiellement invisible*) en sou-dossiers ❌
*: nombreuses OS n'afficher pas les dossier /\..*/ par défaut
plutôt:
# suivres les changes de ce sous-dossier .git
git submodule add <url_du_dépôt*> assets/js/reveal-js/ # Dépôt distant, comme Github, ou locale, en un autre dossier
ou:
# ne suivres pas les changes
rm -rf assets/js/reveal-js/.git
pdfs, tomls ignoré par defaut ❌
find . -name "*.toml" -o -name "*.pdf" -exec git add -f {} +
Please enter a commit message ❌
# Merge branch 'repair2' of https://gitlab.com/ronzz-public/CDN into repair2
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
# Lines starting with '#' will be ignored, and an empty message aborts # the commit.
~
Naviguez avec les flèches sur votre clavier jusqu'à la fin des lignes de commentaires précédées par #, puis taper o pour insérer une nouvelle ligne. Entrez un message, puis tape esc et :wq pour enregistrer et fermer.
Github
gh auth login
gh auth status
# Create a repository interactively
gh repo create
| Purpose | Permissions |
|---|---|
| git commit | metadata, contents (read&write) |
| git admin | issues, pull requests |
| repo admin | administration, actions, workflows |
Gitlab
L'utilisation de Gitlab VScode extension est conseillé.
Diagnostiques
git fsck --full
Member discussion