Skip to content

Instantly share code, notes, and snippets.

@kjaquier
Last active September 2, 2015 16:53
Show Gist options
  • Save kjaquier/c3b452f90c7dd73ee1ec to your computer and use it in GitHub Desktop.
Save kjaquier/c3b452f90c7dd73ee1ec to your computer and use it in GitHub Desktop.
Mode d'emploi des fonctionnalités de bases de git, réalisé lorsque j'apprenais à utiliser git.

Git : aide-mémoire

Notation EBNF

Partie optionnelle : [...]

Partie répétable 0 à N fois : {...}

Partie à choix : (...|...)

Symbole non-terminal : <symbole> (c'est-à-dire "quelque chose" qui fait pas partie de la syntaxe)

Base

Créer un dépôt depuis le dossier courant :

git init
git add <fichier(s)>
git commit

Ajouter un commentaire à une action :

git <commande> [-m "Message"]

Cloner un projet depuis une url dans le dossier courant (crée un dossier) :

git clone <url>

Commit

Le commit crée un snapshot local (!) de l'état d'un ou plusieurs fichiers à un moment donné.

Commit d'un nouveau fichier (sans le add, le fichier n'est pas connu de git) :

git add <fichier> {<fichier>}
git commit

Commit de tous les fichiers modifiés :

git commit -a

Commit de certains fichiers :

git commit {<fichier>}

Corriger une erreur avant/après un commit :

Modifier le message du dernier commit (impossible une fois que le commit a été transmis à d'autres personnes) :

git commit --amend

Annuler un commit :

git reset [--hard] <identifiant du commit> [-- {<fichier>}]

L'identifiant peut être :

  • HEAD : dernier commit
  • HEAD^ : avant-dernier commit
  • HEAD^^ : etc.
  • HEAD~2 : équiv. à HEAD^^
  • <hash> : commit correspondant au hash donné (on peut écrire que le début du moment qu'un seul hash peut en être déduit)

Seul le commit est annulé, les fichiers eux restent modifiés L'option --hard annule également les modifications sur les fichiers, donc fait perdre tout le travail !

Annuler les modifications d'un fichier avant de commit (= restaurer le fichier au dernier commit) :

git checkout <fichier>

Annuler un fichier ajouté avec git add avant un commit :

git reset HEAD -- <fichier>

Regarder les différences, le statut, etc.

status : pour voir les fichiers modifiés, ceux en attente de commit, etc. :

git status

diff : pour voir les lignes de code modifiées dans chaque fichier :

git diff [<branche 1>..<branche 2> --] {<fichier>}

Options :

  • --name-status : voir l'état (modifié/créé/supprimé/...) des fichiers affectés.

Log

Voir le log des derniers commits du projet :

git log

Navigation avec PgUp, PgDwn et Q pour quitter.

Options :

  • -p : pour avoir le détail des lignes modifiées
  • --stat : pour avoir un résumé plus concis des modifications
  • --grep="chaine" : voir git grep
  • -S"chaine" : pour chercher une chaîne ajoutée ou retirée
  • --before|after=<date> : pour chercher dans un intervalle de temps
    • <date> : peut être par exemple : "2012-07-01", "2 weeks ago", ...
  • --author <nom> : liste les commits d'un utilisateur ( peut être le nom ou juste une partie ou l'e-mail)
  • --walk-reflogs : ajoute les commits perdus ou pas facilement accessibles pour une raison quelconque
  • --name-status : voir l'état (modifié/créé/supprimé/...) des fichiers affectés par chaque commit.

Variantes :

Entre deux commits de la branche courante :

git log <ident. commit>..<ident. commit>

Dans une branche et pas dans l'autre :

git log <nom branche exclue>..<nom branche>

Dans certains fichiers (récursif sur les dossiers) :

git log -- <chemin fichier 1> <chemin fichier 2> <etc.>

On peut combiner toutes ces options et variantes. Les résultats seront ceux qui correspondent à au moins un des critères (OU). On peut forcer à faire correspondre à tous les critères (ET) avec l'option --all-match

Mises à jour du serveur et du client

Télécharger les modifications des autres personnes pour la branche courante :

git pull

...qui revient à télécharger les commits (git fetch) puis à les appliquer (git merge).

Deux cas possibles :

  • Aucune modification locale depuis le dernier pull = mise à jour simple sans conflit (fast-forward)
  • Il y a des commits concurrents Dans ce cas :
    • S'il y a des modifications à des endroits distincts d'un même fichier, git les fusionne tout seul
    • Sinon, s'il y a des modifications en conflit, les lignes sont indiquées par des symboles (<<<<<<<<<) délimitant les changements et ceux des autres.

Envoyer ses commits :

git push

Les modifications sur le serveur sont obligatoirement de type fast-forward ! Personne ne doit avoir fait de push depuis le dernier pull ! Un push est irreversible ! Conseils :

  • Consulter le log local (git log -p) avant de faire un push.
  • Faire un pull pour être à jour avant de faire un push (proposé en cas d'échec du push)
  • Commits réguliers, push de temps en temps (~ une fois par jour max)

Annuler un commit publié (= effectuer un commit des modifications inverses) :

git revert <identifiant du commit>

Gérer les branches

Une branche est une copie du projet permettant de faire des modifications sans affecter la branche principale (master), donc le projet original.

L'idée est de créer une branche lorsqu'on apporte une modif au projet, à moins que :

  • Modification rapide
  • Modification simple
  • Un seul commit suffit
  • On sait déjà exactement les modifications à apporter

C'est toujours mieux de créer une branche pour rien que de mettre le bordel dans le master.

Voir les branches (la branche avec une * est la branche sur laquelle on travaille) :

git branch [-r]
  • -r pour lister les branches connues du serveur (remote tracking branches)

Créer une branche :

git branch <nom de la branche>

Changer de branche (ne crée pas de nouveau dossier, mais remplace les fichiers par leur version dans la nouvelle branche sélectionnée) :

git checkout <nom de la branche>

Fusionner deux branches (branche dans branche ) :

git checkout <destination>
git merge <source>

Supprimer une branche (possible seulement après l'avoir fusionnée, sinon -D pour forcer) :

git branch -d <nom de la branche>

Mettre de côté les modifications non commitées de la branche courante (pour éviter d'avoir à les commiter avant de changer de branche) :

git stash

Restaurer les modifications mises de côté dans la branche courante :

git stash apply

Gérer les branches du serveur :

Tracker une branche du serveur :

git branch --track <branche locale> origin/<branche serveur>

Créer une branche directement sur le serveur :

git push origin origin:refs/heads/<nom de la branche>

Pusher une branche :

git push [-u] origin <nom de la branche locale>[:<nom de la branche distante>]
  • -u permet de dire à git de se souvenir de la branche sélectionnée pour les prochains push (permet de juste faire git push après)

Supprimer une branche sur le serveur (ne la supprime pas chez les trackers) :

git push origin :heads/<nom de la branche>

Supprimer une branche trackée :

git branch -r -d origin/<nom de la branche>

Tags

Nom donné à un commit particulier (ex : "v2.0", etc).

Ajouter un tag à un commit :

git tag <nom tag> <identifiant du commit>

Supprimer un tag :

git tag -d <nom tag>

Supprimer un tag sur le serveur :

git push --delete origin <nom tag>

Envoyer les tags lors d'un push :

git push --tags

Divers

Grep sur les fichiers sources à partir d'une chaîne ou d'une expression régulière :

git grep [-n] [-i] "chaine recherchee"
  • -n pour avoir les numéros de ligne
  • -i pour ignorer la casse

Faire ignorer des fichiers à git :

  • Créer un fichier .gitignore à la racine
  • Entrer les noms des fichiers à ignorer (un par ligne)
  • Exemples : unfichier.xml, dossier/fichier.o, *.tmp

Ajout interactif (pour ne commiter qu'une partie des modifs d'un fichier) :

git add -p

Récupérer un fichier d'une autre branche :

git checkout-- <chemin vers fichier>

Insérer un commit dans le passé :

  • On a ça : A---B---C---D---E---F master

  • On veut faire ça : A---B---K---C---D---E---F master

  • Créer une branche et appliquer les changements :

      git checkout -b temp B
      (appliquer changements...)
      git add [changements]
      git commit
    
  • Donc maintenant on a ça :

      A---B---K               temp
           \
            C---D---E---F     master
    
  • Faire un rebase de la branche depuis master va appliquer "les trucs qui dépassent" de master à la fin de temp :

      git rebase temp master
    
  • Maintenant on a ça : A---B---K---C---D---E---F temp. Plus qu'à merger temp dans master.

  • Attention au moment de synchroniser avec le serveur. Le merge automatique risque de rajouter les commits passés après.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment