UP | HOME

Git

Table of Contents

1. Utilisation de Git

auteur: rick <rick@gnous.eu> Fichier sous licence CC-BY-SA 4.0 (https://creativecommons.org/licenses/by-sa/4.0/).

1.1. Configuration

1.1.1. Configuration basique

On utilise la commande git config suivi de l’option à modifier (user.name, user.email …).

Exemple de commande : git config --global user.name moi

1.1.2. Configuration avancé

Plusieurs niveaux de configurations:

  • global : tous les dépôts présents sur le pc (caduque si local)
  • local : uniquement le dépôt où on se trouve

Le fichier se trouve dans .git/config (local) et ~/.gitconfig (global).

  • git config --global --list : configuration globale. on peut remplacer --global par --local pour voir la configuration locale

Liste non exhaustive des valeurs à configurer:

  • user.name : nom utilisateur
  • user.email : mail utilisateur
  • core.editor : éditeur utilisé pour les commit
  • merge.tool : outil pour merge
  • commit.template : template pour les commits
  • man git-config
  1. Les alias
    git config alias.commande 'commande'
    # exemple
    git config alias.last 'log -1 HEAD'
    git last # exécute l’alias
    

    Il est possible de rajouter des options lors de l’appel à l’alias, ils vont se rajouter après la commande de l’alias.

1.2. TODO Connexion avec clé SSH

Il faut en premier générer une clé ssh publique avec `ssh-keygen` puis mettre son contenu sur son profile git. Il faut laisser le nom par défaut sinon il faut préciser la clé dans les paramètres du git clone.

1.3. Création de dépôts

Pour créer un dépôt simple, il suffit de faire git init nom_dossier ou git init dans le dossier.

Pour faire un dépôt type serveur, il faut faire git init --shared --bare nom_dossier.

1.3.1. Enlever des fichiers ou des dossiers

Pour éviter que git ne synchronise tous les fichiers qui lui passe sous la main, on peut faire un fichier .gitignore à la racine du dossier, qui contient les noms de fichiers à exclure

doc/*
*.class

1.3.2. Ajouter une origine au dépôt

Si le dépôt en ligne est vide, il faut le link sur le dépôt local. git remote add nom https:// permet de le faire. En règle générale, le nom sera origin. Il est possible d’avoir des informations avec git remote -v ou git remote show nom.

Lors du premier push, il faut lier la branche locale avec le dépôt distant et sa branche. Cela se fait avec git push -u origin master.

Pour pousser des tags sur la branche distante, on peut utiliser 2 commandes :

  • git push nom tag : pousse juste le tag sur le remote donné
  • git push --tags : pousse tous les tags

1.4. Commandes

1.4.1. Usage classique

Git ne prend en compte que les fichiers, pas les dossiers vides.

Pour ajouter un fichier au git, il suffit de faire git add fichier. On peut en ajouter plusieurs d’un coup. Pour savoir quels fichiers n’ont pas été ajouté au git, il faut faire git status. Un fois le fichier ajouté, on va faire un commit afin de connaître les modifications apporté avec git commit, il est possible d’ajouté directement le titre du commit : git commit -m "titre commit". On met ensuite en ligne avec git push. Pour mettre à jour un dossier git, on tape git pull.

  1. MAJ du dépôt local
    • git fetch remote : va mettre à jour le dépôt local avec les informations du dépôt distant (le nom du remote est obligatoire pour le premier fetch). Il faut cependant se déplacer ensuite manuellement pour aller sur le dernier commit.
    • git pull : met à jour et se déplace sur le dernier commit.
  2. Commits
    • `git revert sha1` : fait un commit contenant l’inverse du sha1
    • `git add file && git commit –amend` : ajoute un fichier au dernier commit
    • `git commit –amend` : modifie le message du commit précédent
  3. Voir les modifications
    git log
    affiche l’historique du dépôt
    --graph
    affiche sous forme de graphe
    -p N
    affiche les N derniers commits
    git show sha1
    affiche les informations du commit et ses modifications
  4. Informations sur les fichiers

    Pour pouvoir voir plus en détail un fichier et ses modifications, il est possible de faire un git blame fichier. La première colonne indique le commit modifiant le fichier (^ = commit ayant créer le fichier), la deuxième l’autheur, puis la date de création et pour finir la ligne du fichier. Avec -L on peut préciser les lignes à montrer :

    -L 10,20
    les lignes 10 et 20
    -L 10,+
    tout à partir de la ligne 10
    -L 10,+4
    4 lignes après la ligne 10
  5. Mettre de côté les modifications

    Pour mettre de côté des modifications, il est possible d’utiliser la commande git stash save "message" afin de les sauvegarder pour plus tard. Pas besoin de faire des commits pour mettre les fichiers de côtés. Ces modifications seront sauvegardés avec un index. Pour les restaurer dans l’espace de travail, il faut faire git stash pop index. Pour récupérer la liste des index, il faut faire git stash list. Pour voir les informations du stash : git stash show index.

    git stash save = git stash. git stash pop = pop le dernier stash.

    Exemple d’utilisation en cas de conflit:

    git pull
    # erreur !
    git stash
    git pull
    git stash pop
    # régler les derniers conflits
    
  6. Rebase

    Change le parent d’un commit.

    Se fait automatiquement avec git pull --rebase.

    1. L’utiliser de manière interactive
      git rebase -i sha1
      # modifier le fichier selon ses gouts
      # le fichier est trié par ordre chronologique (+ancient au +récent)
      # ce fichier est un script qui sera exécuté. Pour modifier un commit, 
      # il faut remplacer le pick par r par ex (+d’infos dans le fichier).
      
      Option Description
      p Ne rien faire
      r Réécrire le commit
      drop Supprime le commit, possible de supprimer la ligne au lieu de mettre d. Possibilité de conflit à gérer
      squash Fusionne le commit avec son commit parent
      edit Laisse la main pour faire ce qu’on souhaite (ajout de fichiers…)

      Pour découper un commit, on utilise edit sur le commit et il suffit de rajouter les fichiers avec add et les commit avant de continuer le rebase.

      Pour changer l’ordre des commits, il faut changer la ligne où ils se trouvent.

      pick commitA -> pick commitA
      pick commitB -> pick commitC
      pick commitC -> pick commitB
      pick commitD -> pick commitD
      
  7. Se déplacer de commit en commit
    • git checkout sha1 : déplace HEAD sur le sha1
    • git checkout HEAD~2 : déplace HEAD 2 commit en arrière.

    HEAD^ = parent du commit actuel

  8. Déplacer la tête de la branche

    git reset sha1 : déplace la branche sur le commit (marche aussi avec HEAD~X)

    On peut annuler un reset avec ORIG-HEAD comme commit.

    1. Arguments
      • --hard : supprime toutes les modifications qu’il y ai pu avoir (= git checkout sur tous les fichiers)
      • --mixed (option par défaut) : les modifications faites sont sauvegardées mais les fichiers indexés ne le sont plus
      • --soft : idem que --mixed mais les fichiers indexés le restent
  9. Historique position

    git reflog : affiche l’historique des différentes positions de HEAD. Il est possible de rajouter -N qui affichera les N dernières positions (git reflog -4 par ex).

    Il est aussi possible de rajouter --reflog à la commande git log.

1.4.2. Commandes pour les branches

Les branches permettent de développer des fonctionnalités de l’application en parallèle de la branche principale et de les fusionner plus tard si la fonctionnalité est concluante.

Pour créer une branche, on tape git branch nom puis git checkout nom pour basculer dessus. Pour fusionner une branche annexe avec la principale, on bascule sur la principale (git checkout master) et on tape git merge nom.

git branch -a : montre toutes les branches, y compris les branches distantes

  1. Copier un commit dans une branche

    git cherry-pick sha1 : duplique le commit passé en pramètre

  2. Rebase d’une branche

    Aligne tous les commits de la branche dans l’autre branche (master ici).

    # depuis la branche à rebase
    git rebase master
    # régler les conflits et si conflits:
    # git add files
    # git rebase --continue
    git checkout master
    git merge branche
    
  3. Suppression

    En local: git branch -d nom. Il faut ensuite pousser cette suppression avec git push origin --delete nom.

1.5. Submodules

Fichier se trouvant dans le dépôt nommé .gitmodules contient toutes les informations sur les modules (chemin, version…).

1.5.1. Commandes

  • git submodule add url chemin : ajoute le submodule se trouvant dans l’url dans le chemin du dépôt donné
  • pour cloner un repo avec submodules :

    git clone
    git submodule init
    git submodule update
    # ou
    git clone --recurse-submodules
    
  • pour pull un repo avec submodules :

    git pull
    git submodule update --remote # --merge ou --rebase pour finir la commande (pas obligatoire)
    
  • git push --recurse-submodules=check : vérifie si les modifications apportées sur le sous module ont bien été push sur son dépôt avant de push le dépôt prinicpal.

On peut aller dans le dossier du sous module et faire un git checkout pour changer la version utilisée par le dépôt principal.

  • git submodule foreach commande : applique la commande à tous les sous modules

1.6. Annexe

1.6.1. Hooks

Scripts exécutés lors de certaines actions. Ils se trouvent dans .git/hooks. Ils doivent avoir le même nom que l’action (pre-commit, commit-msg…) et être exécutable. Ils ne sont pas dupliqués avec un clone. Des exemples sont trouvables avec l’extension .sample.

On peut lier un dossier externe contenant les hooks à notre projet :

  • core.hooksPath path dans la configuration pour mettre le chemin vers le dossier hooks se trouvant dans un autre dépôt git par ex.
  • Lors du clone / init, ajouter l’option --template=dir où le répertoire contient un dossier hooks.
  1. Local

    Si la valeur de retour n’est pas 0, on arrête tout.

    Liste non exhaustive des hooks existant pour un dépôt local:

    • pre-commit : juste après git commit. Pas d’arguments
    • prepare-commit-msg : juste après pre-commit, 3 arguments : nom fichier tmp contenant le message, type de commit (-m, -t, merge ou squash), sha1 (pour -c -C ou –amend)
    • commit-msg : juste après l’entré du message du commit, 1 argument : nom fichier tmp contenant le message
    • post-commit : juste après la création du commit (aucune anulation possible si retourne !0). Pas d’arguments
    • post-checkout : juste après commande checkout. 3 arguments : ref HEAD pred, ref nouv HEAD, checkout de branche (1) ou fichier (0). Aucun changement si ret !0
    • pre-rebase : juste après commande rebase mais avant la rebase. 2 arguments: branch upstream, branche rebasée (vide si la branche est la même)

    On peut les ignorer en ajoutant -n à la commande commit.

  2. Serveur

    Les scripts ont la même règle que les hooks locaux.

    Liste non exhaustive des hooks existant pour un dépôt distant:

    • pre-receive : en recevant un push et avant d’intégrer le code reçu. Pas d’argument
    • update : après le pre-receive. 3 arguments : nom branche maj, sha1 du commit actuel de la branche, sha1 du nouveau commit de la branche
    • post-receive : après push réussi. Pas d’arguments et n’arrête rien. Permet de faire des notifications pour le CI/CD par ex.

1.6.2. Voir les références

  • cat .git/HEAD : fichier contenant la référence actuelle de HEAD
  • git cat-file -p HEAD : affiche plus d’infos sur la référence HEAD
  • ORIG-HEAD : commit où se trouvait avant HEAD (créé uniquement avec certaines commandes)
  • git diff --cached --submodule : les chemins vers les sous modules et leur url

1.6.3. Faire une recherche dichotomique pour trouver un bug

Si on sait qu’entre le commit X et Y, il y a un bug et qu’il y a plusieurs commits entre les deux, on peut appliquer la dichotomie pour trouver le bug en question (en prenant le commit à la moitié, en vérifiant s’il contient le bug, etc.).

On peut utiliser git bisect pour ça.

git bisect start
git bisect good sha1 # le commit sans le bug
git bisect bad sha1 # le commit avec le bug

# good et bad sans sha1 = HEAD.
# un git checkout est fait automatiquement en se mettant au milieu
# si le bug est toujours présent, on refait git bisect bad 
# ou git bisect good s’il n’y est plus
# lorsque le bug est trouvé de manière sur, il affiche des infos sur le commit

git bisect reset # sort du mode bisect et retourne sur le commit précédent cette commande

Pour automatiser la recherche, il est possible de lui passer un script qui sera exécuté à chaque checkout:

git bisect start
git bisect good sha1 # le commit sans le bug
git bisect bad sha1 # le commit avec le bug
git bisect run script # le script retourne 0 = good, autre = bad
# attendre
git bisect reset

1.6.4. Autres

  • git commit --amend : modifie le dernier commit, supprime le tag sur ce commit (toujours possible d’aller dessus mais pas afficher dans log).
  • git log nom : commits de la branche passée en paramètres
  • git merge --abort : annule un merge en cours.

Tableau des commandes :

Commande Description
clone Obtenir une copie d’un dépôt existant
add Place un contenu sous le système de suivi de versions. Indexer un fichier
init Initialise un nouveau dépôt
rm Supprime un contenu
commit Valide les modifications
push Propage les modifications sur un dépôt distant
pull Récupère les objets du dépôt distant et tente de faire un merge avec les objets locaux (git pull =git fetch + git merge)
diff Calcule la différence entre deux versions
log Affiche les journaux des modifications
fetch Met à jour les objets locaux avec ceux d’un dépôt distant (pas de merge)
branch Liste, créé ou supprime une branche
config Configure Git
status Affiche l’état des fichiers locaux

Author: rick

Email: rick@gnous.eu

Created: 2024-05-16 jeu. 20:32

Validate