Git
Git
par Jiel
Introduction et théorie
git est un logiciel de gestion de versions. Très apprécié par les dévelopeurs, il permet de travailler en équipe sur des fichiers et de faire des modifications concurrentes avec conservation d'un historique. Certains services d'hébergement se basent sur git, notamment GitHub, GitLab et Bitbucket. L'astuce de git est que tout est tracé au moyen d'index.
Le principe de Git est le suivant : un utilisateur créé un répertoire local dans lequel il met son code. Quand il satisfait du résultat, il pousse son code dans un système centralisé (le dépôt git), généralement situé sur un serveur local ou distant. Un second utilisateur qui veut modifier le code existant, ou juste l'utiliser, récupère le contenu du système centralisé dans un répertoire local sur son ordinateur. Il modifie ensuite le code, qu'il peut créer dans une branche (pour ne pas écraser le code du premier utilisateur) et quand il est satisfait du résultat, il le pousse dans le système centralisé. Et ainsi de suite.
Une modification s'appelle un commit (grosso modo une soumission). L'usage est d'en faire aussi souvent que possible. En pratique, chaque dépôt git contient une liste de commits. Ces commits sont liés les uns avec les autres par leurs métadonnées - chaque commit contient une référence vers ses "parents".
Cette documentation explique les commandes les plus courantes que sont amenées à faire un utilisateur de git au cours de la journée.
Commandes basiques
Pour lister les options de git, faîtes :
git
Pour créer un nouveau dépôt git, créez un répertoire de travail et faîtes :
mkdir ~/nouveau_repertoire cd ~/nouveau_repertoire git init
Mettez à jour vos variables globales pour git :
git config --global user.name "Lea Linux" git config --global user.email "lea@lea-linux.org"
Voir lesdites variables git config -l
Pour plus de commodité, on pourra aussi définir ces variables dans la zone [user] du fichier .git/config
Pour créer une copie d'un dépôt situé sur un serveur distant :
git clone username@host:/path/to/repository
Ou si on a déjà un dépôt existant dans le répertoire local et qu'on veut le mettre à jour :
git pull
Pour regarder le statut de votre dépôt, c'est à dire visionner les modifications :
git status
Pour ajouter un fichier modifié lea.txt listé par git status :
git add /chemin/vers/mon/fichier/lea.txt
Pour ajouter tous les fichiers modifiés :
git add -all
Ou
git add .
Pour ajouter les fichiers de manière interactive (peu utilisé) :
git add -i /chemin/vers/mon/fichier/lea1.txt /chemin/vers/mon/fichier/lea2.txt
Pour supprimer un fichier lea.txt
git rm /chemin/vers/mon/fichier/lea.txt
Les fichiers ajoutés sont maintenant affichés en vert, alors qu'auparavant ils étaient en rouge :
git status
Pour soumettre ces changements avec un petit commentaire :
git commit -m "Correction des fautes d'orthographes dans les commentaires"
Pour écrire un commentaire plus détaillé :
git commit
Pour pousser les modifications dans le dépôts, on fera :
git push
Cependant, nous allons voir ci-dessous que dans la vraie vie, on souhaite travailler avec des branches, pour avoir un travail plus propre.
Travailler proprement : les branches
Généralement, nous n'allons pas modifier le clone du dépôt directement mais créer une branche à partir du tronc (la branche maître). Dans un système de contrôle de versions comme git, une branche exprime comment un bout de code doit évoluer. Une branche permet aussi que plusieurs personnes puissent faire des modifications différentes en même temps. Il y a de nombreuses raisons de créer une branche : pour une phase de développement donné (prototype, bêta), pour isoler le travaiil d'un contributeur, pour travailler sur une fonctionnalité unique, pour corriger un bug etc. Une branche commence toujours à partir d'un point spécifique du code de base.
Voir les branches locales (la branche maître est précédée d'un astérisque)
git branch --list
Voir les branches distantes :
git branch --remotes
Voir les branches locales et distantes :
git branch --all
La liste des branches distantes ne se met pas à jour automatiquement, pour la mettre à jour :
git fetch
Changer de branche pour la branche super_truc :
git checkout super_truc
Donc pour revenir au tronc / la branche maître :
git checkout master
La même chose avec une option de traçage :
git checkout --track super_truc
Pour créer une nouvelle branche "super_truc" à partir de la branche maître :
git checkout -b super_truc master
Pour supprimer une branche :
git branch -d super_truc
Quand on est sûr de nos modifications et qu'elles ont été revues par quelqu'un autre, on incorpore les commits de la branche super_truc dans la branche courante :
git merge super_truc
Une autre option est le rebasage. Il s'agit de mettre une branche à jour avec les commits qui ont été faits dans sa branche mère : on se base sur les commits. Un usage classique du rebasage est de conserver une série de commits de votre code à jour avec une autre branche, généralement la branche maître ou une branche importante d'un autre dépôt. Vous allez donc continuer à développer parallèlement à l'autre branche, simplement le rebasage va déplacer l'embranchement entre les deux branches au plus proche. Rebaser n'est pas fusionner (merge) : après le rebasage, les différentes branches et les ramifications existent toujours, simplement on a une nouvelle séquence de commits. Ainsi :
git rebase master super_truc
Pour fusionner un commit spécifique avec le précédent, c'est à dire supprimer un seul commit de l'historique d'une branche :
git rebase --interactive fa75c64
Pour pousser la branche dans le dépôt, afin qu'elle soit disponible aussi pour les autres :
git push origin super_truc
Pour pousser les changements dans le dépôt central dans la branche maître
git push origin master
Pour mettre à jour son répertoire local avec une branche spécifique, on fera de même par analogie :
git pull origin super_truc
Les logs
Voir le log de modification :
git log
Voir l'historique condensé de votre projet, c'est à dire la liste des commits récents, chacun sur une ligne :
git log --oneline
Voir les détails d'un commit en particulier (qui a le numéro fa75c64) :
git log fa75c64 --max-depth=1 git show fa75c64
Vous pouvez ajouter des paramètres pour voir seulement des choses spécifiques, comme par exemple ne voir que les commits de Jiel
git log --author=jiel
Ou juste les fichiers modifiés :
git log --name-status
Voir un arbre avec toutes les branches et leurs noms (et les étiquettes associées) :
git log --graph --oneline --decorate --all
Voir l'historique étendu, c'est à dire les logs de références, les informations mises à jour dans le répertoire local :
git reflog
Voir la différence entre deux commits de numéros 56dfgd4fg454 et 787mjka9a7a8 :
git diff 56dfgd4fg454 787mjka9a7a8
Quand ça coince
Parfois, on doit effacer des modifications et on aussi des conflits d'édition.
Supprimer tous les changements non sauvegardés :
git clean -fd
Revenir à un commit précédznt, c'est à dire supprimer tous les changements et les précédents commits, mais ne pas supprimer les nouveaux fichiers dans le répertoire de travail :
git reset --hard fa75c64
Supprimer le travail précédent, mais garder l'historique intact (le répertoire de travail peut s'en trouver dans un état un peu laid) :
git reset fa75c64
Restaurer un fichier modifié, mais qui n'a pas été "commité" :
git checkout -- /chemin/vers/mon/fichier/lea.txt
Après avoir résolu un conflit, continuer avec le processus de rebasage :
git rebase --continue
Pour voir si le conflit touche le fichier lea.txt :
git mergetool /chemin/vers/mon/fichier/lea.txt
Pour suppprimer tous les changements et commits locaux, aller chercher les dernières modifications sur le server et faire pointer dessus notre branche maître locale :
git fetch origin git reset --hard origin/master
Les étiquettes
Une étiquette est utilisée pour pointer sur un commit spécifique, un peu comme un signet. Voir toutes les étiquettes :
git tag
Pour ajouter une étiquette "babar" sur un objet qui a été soumis avec le commit numéro fa75c64 :
git tag babar fa75c64
Un cas fréquent d'utilisation des étiquettes concerne la numérotation de version de développement d'un logiciel. Ainsi pour indiquer que le commit correspond à la version 1.3.0 de notre application :
git tag 1.3.0 fa75c64
Voir un commit qui a été étiqueté avec "babar" :
git show babar
Quelques astuces
Dans le cas où on l'on doit s'arrêter en cours de route (une autre modification doit être faîtes plus urgemment) mais que l'on ne veut pas perdre tous les fichiers modifiés, alors on mettra de côté avec :
git stash save
Le temps de faire quelques autres commits, et on pourra faire :
git stash pop
pour revenir à la modification précédemment mise en suspend.
Le fichier .gitignore donne des indications sur les choses à ignorer pour git. Cela peut être des noms de fichiers (énoncés en entier ou avec des expressions régulières). On peut en mettre un dans chaque répertoire de votre dépôt.
Pour les utilisateurs de Subversion qui voudraient passer à git, ou l'inverse, ou faire communiquer git et Subversion, il y a une commande :
git svn
Pour réécrire les commits d'une branche en jouant avec les différents objets qui constituent un dépôt, les téméraires utiliseront :
git filter-branch
Pour avoir une sortie en couleur pour git ;
git config color.ui true
Pour lancer un ou plusieurs scripts à l'occasion d'un événement particulier, par exemple quand un commit ou un patch se produit dans votre dépôt, vous pouver créer ce que l'on appelle un hook. Les hooks appartiennent à un dépôt spécifique (qu'il soit local ou distant) et ne sont pas clonés lors d'une opération de clonage. Chaque hook est un script situé dans le répertoire .git/hooks. L'usage veut que le hook soit utilisé avec parcimonie, en cas de dernier recours. En effet, d'une part le hook peut ralentir les opérations de git, peut surprendre un autre utilisateur (d'autant plus qu'il n'existe que dans un dépôt) et surtout, c'est un peu en dehors du principe de git qui se veut simple.
Liens utiles
@ Retour à la rubrique Administration système
Copyright
© 2017 Jiel Beaumadier
Vous avez l'autorisation de copier, distribuer et/ou modifier ce document suivant les termes de la GNU Free Documentation License, Version 1.2 ou n'importe quelle version ultérieure publiée par la Free Software Foundation; sans section invariante, sans page de garde, sans entête et sans page finale. |