Projet

Général

Profil

Recueil GIT

Présentation

Site officiel : http://git-scm.com/

Tutoriaux intéressants : Recueil des commandes :

Les manpages des commandes sont accessibles avec la commande help directement,
par exemple :

git help log

remarque : Il faut utiliser une version récente de git-core (>1.6.3) pour pouvoir travailler avec les dépôts.

Lexique de base

git clone [adressedepot] > clone le dépôt en local

git pull > rattriement de la branche distante sur la branche locale
git push > dépôt de la branche locale sur la branche distante

git branch > liste des branches locales
git branch -a > liste des branches locales et distantes
git checkout [nombranche] > aller sur la branche
git checkout -b [nombranche] > création d'une branche
git push -u origin [nombranche] > 1er push d'une branche qui vient d'être créée
git branch -D [nombranche] > suppression d'une branche locale
git branche origin:[nombranche] > suppression d'une branche distante

git status > affiche les fichiers qui doivent être ajoutés / supprimés / commités de la branche
git add [nomfichier] > ajoute un fichier
git add . > ajout de l'ensemble des fichiers novueaux dans la branche
git rm [nomfichier] > supprime un fichier
git rm -rf [nomrépertore] > supprime l'ensemble d'un répertorie
git mv [nomfichier] > déplace un fichier

git commit -a > validation de l'ensemble des modification de la branche
git commit -a [filename] > validation d'un seul fichier
git log > affiche l'ensemble des commits réalisés sur la branche

git merge [nombranche] > rappatriement des modications de la branche ciblée dans la branche en cours
git reset __merge > annule le dernier merge réalisé sur la branche

Prompt

Pour une meilleur navigation dans les branches, vous pouvez utiliser git-sh-prompt fourni en contribution de git.

Il est très probablement déjà installé par votre distribution et activé par le complètement de votre shell.

Pour vérifier la présence de git-sh-prompt vous pouvez exécuter :

moi@work:~$ command -v __git_ps1 > /dev/null && echo OK || echo NOK
OK

Une fois la présence confirmé, vous pouvez l’utiliser, par exemple pour bash sur une distribution basée sur Debian :

  • Modifiez votre fichier ~/.bashrc
    moi@work:~$ cat >> ~/.bashrc <<'EOF'
    if [ "$color_prompt" = yes ]; then
        PROMPT_COMMAND='__git_ps1 "${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]" "\\\$ "'
    else
        PROMPT_COMMAND='__git_ps1 "${debian_chroot:+($debian_chroot)}\u@\h:\w" "\\\$ "'
    fi
    EOF
    
  • Activez l’affichare de l’état du dépôts
    moi@work:~$ cat >> ~/.bashrc <<'EOF'
    export GIT_PS1_SHOWDIRTYSTATE=true
    export GIT_PS1_SHOWSTASHSTATE=true
    export GIT_PS1_SHOWUNTRACKEDFILES=true
    export GIT_PS1_SHOWUPSTREAM=auto
    export GIT_PS1_SHOWCOLORHINTS=true
    EOF
    
  • Rechargez votre ~/.bashrc
    moi@work:~$ . ~/.bashrc
    

Paramétrage global

Il est nécessaire de déclarer vos noms et emails dans votre configuration git globale

git config --global user.name "Prénom NOM" 
git config --global user.email "prenom.nom@ac-acad.fr" 

Afin que le git push fonctionne, il faut renseigner le fichier ~/.netrc :

machine dev-eole.ac-dijon.fr
login monlogin
password monmotdepasse

et paramétrer les droits du fichier :
chmod 600 ~/.netrc

Premiers pas

  • Démarrer un nouveau projet.

Demandez à l’administrateur Eole la création de votre projet dans le RedMine.

  • Premier Commit du projet.

d'abord récupérer le projet :

git clone http://login@dev-eole.ac-dijon.fr/git/nom_projet

remarquons bien que le projet initialisé est vide

ensuite, aller dans le dossier du nom_projet, ajouter au moins un fichier,
puis

git add fichier1 fichier2 fichier3
git commit -m"permière version" 

maintenant la branche master doit être apparue (puisqu'il y a des fichiers dans le projet), donc

git branch

doit lister la branche master

pour finir , faire un "push" pour envoyer les fichiers sur le dépot de code :

git push -u http://login@dev-eole.ac-dijon.fr/git/nom_projet master

L'option -u (upstream) permet de créer automatiquement le lien entre la branche locale et la branche créée sur le serveur.

Récupérer un projet existant.

git clone https://login@dev-eole.ac-dijon.fr/git/nom_projet.git

Cela va créer un répertoire nom_projet contenant un répertoire .git.
  • Ajouter/retirer des fichiers :
    git add file1 file2 ...
    git remove file1 file2 ...
    
  • Pour savoir quel est l'état des modifications :
    git status
    
  • Enregistrer les modifications localement :
    git commit -a -m"premiere version avec le scm git" 
    
  • Enregistrer les changements sur le serveur :
    git push
    

remarque : Avant d'enregistrer les changements sur le serveur, pensez à éditer vos messages de commit, il est possible de les fusionner (Voir "Messages de commit").

  • Récupérer les modifications du serveur et les fusionner localement :
    git pull
    
Notre serveur GIT a plusieurs branches "branch".
  • Pour afficher les branches disponibles sur le serveur :
    git branch -a
    
  • Pour paramétrer la prise en compte d'une branche :
    git config branch.2.2.remote origin
    git config branch.2.2.merge refs/heads/2.2
    
  • Pour récupérer la branche localement (à ne faire que la première fois) :
    git fetch origin 2.2:2.2
    
  • Pour se placer dans la branche :
    git checkout 2.2
    
  • Récupérer les modifications du serveur :
    git pull
    
  • Pour se placer dans une autre branche, "master" par exemple :
    git checkout master
    

Branch

  • Récupérer une branche
    git checkout nomDeBrancheExistant
    
  • Créer une branche
    Se placer dans la branche que l'on veut copier
    git checkout maBrancheABrancher
    ...
    git checkout -b maNouvelleBranche
    
  • Ceci peut être décomposé en 2 commandes :
    git branch mabranche
    git checkout mabranche
    
  • Diffuser la branche sur le serveur
    git push http://user@194.167.18.22/git/eolebase mabranche
    

    ou, plus simplement :
    git push --all
    
  • Créer une branche à partir d'un numéro de commit
    git checkout -b mabranche <numero_de_commit>
    
  • Supprimer une branche :
    git branch -D [nom-branche]
    
  • Supprimer une branche sur le dépôt origin
    git push origin :branche
    

    Cela correspond en fait à cette commande là : git push REMOTENAME LOCALBRANCHNAME:REMOTEBRANCHNAME sauf que LOCALBRANCHNAME est vide dans notre exemple.
  • Voir les différences entre deux branches
    (par exemple avant de merger) :
    git diff-tree -p [nom-de-branche]
    
  • Pour changer de branche :
    git checkout autrebranche
    
  • Pour revenir à la branche principale :
    git checkout master
    
  • Une autre technique consiste à organiser localement une arborescence différente par branche :
    git/master
       /mabranche
    
  • Savoir dans quelle branche on se trouve :
    git branch
    
  • Voir la branche courante avec le dernier log :
    git show-branch
    
  • Envoyer pour la première fois le contenu de la branche courante sur le serveur :
    git push origin HEAD
    

Arrivé à ce stade il peut être intéressant d'utiliser git-gui (/usr/lib/git-core/git-gui) ou giggle.

Pour voir l'historique des différentes branches dans guit-gui, "menu>dépôt>Voir l'historique de toutes les branches"

  • Autres commandes de base :
    git log
    git log --pretty=oneline --all
    git diff
    

Branches distantes

  • Si vous avez déjà cloné le master d'un projet, pour visualiser les branches disponibles :
    git branch -a
    

    devrait renvoyer quelque chose comme ceci :
    * master
      remotes/origin/2.2
      remotes/origin/HEAD -> origin/master
      remotes/origin/master
      remotes/origin/upstream
    
  • Pour récupérer la branche 2.2 :
    git co 2.2
    

    va récupérer la branche 2.2 auprès du serveur origin.
    Une autre méthode:
    git branch --track 2.2 remotes/origin/2.2
    

Merge

Fusion : action consistant à fusionner une branche avec une autre ("mabranche" avec master par exemple)

Exemple : merge de la branche mabranche dans la branche master

  • Se placer dans la branche master :
    git checkout master
    git merge mabranche
    

remarque : après un merge réussi, il n'y a pas de commit à faire.

Si vous n'êtes pas satisfait du merge, il faut revenir en arrière avec un

git reset --hard

Résoudre un conflit de merge

Si lors d'un merge il y a eu un problème du type :

Auto-merged file.txt
CONFLICT (content): Merge conflict in file.txt
Automatic merge failed; fix conflicts and then commit the result.
et que
git commit
répond qu'il reste des fichiers à merger (unresolved merge), Il n'y a donc pas eu de commit
de même qu'un
git status

Il faut alors éditer le fichier concerné, résoudre le conflit à la main et faire un nouveau un commit :

git add [file.txt]
git commit

Le message fatal: You have not concluded your merge. (MERGE_HEAD exists) vous rappelle qu'il ne faut pas utiliser l'option "-m" ici ;)

  • Pour repérer les fichiers qui n'ont pas été fusionné :
    git ls-files --unmerged
    

Stash

git stash permet de sauvegarder des modifications locales afin de les appliquer plus tard.

  • Sauvegarde des modifications :
    # git stash save "en attente" 
    Saved working directory and index state On master: en attente
    
  • Liste des modifications sauvegardées :
    git stash list
    stash@{0}: On master: en attente
    
  • Revenir à l'état sauvegardé (stash@{1} pour restaurer la 2ème sauvegarde) :
    git stash apply [stash@{0}]
    
  • Nettoyer la liste des sauvegarde :
    git stash clear
    

Message de commit

IMPORTANT : ne pas effectuer de modifications sur des commits déjà envoyés sur le serveur origin (le dépot).

Avant d'envoyer vos données sur le serveur, il est possible de modifier/améliorer les messages de commit.

Modifier le dernier message de commit

git commit --amend

Modifier, sauvegarder et quitter.

Modifier les trois derniers messages

  • On lance un rebase
    git rebase -i HEAD~3
    
  • Un éditeur de texte s'ouvre avec quelque chose qui ressemble à ça:
    pick 6ffa65b update des bases de donnees editable=0 et pas 2
    pick 9697740 update des bases vers 2.2.3 : nettoyage et ajout d'un __init__.py (ref #11)
    pick e56a7a4 Configuration des bases de donnees pour le passage en version 2.2.3 (fixes #11 : fixé)
    
    # Rebase cd9333c..e56a7a4 onto cd9333c
    #
    # Commands:
    #  p, pick = use commit
    #  r, reword = use commit, but edit the commit message
    #  e, edit = use commit, but stop for amending
    #  s, squash = use commit, but meld into previous commit
    #
    # If you remove a line here THAT COMMIT WILL BE LOST.
    # However, if you remove everything, the rebase will be aborted.
    #
    
  • Changer pick en edit sur les lignes correspondantes aux commit à modifier, par exemple :
    edit 6ffa65b update des bases de donnees editable=0 et pas 2
    pick 9697740 update des bases vers 2.2.3 : nettoyage et ajout d'un __init__.py (ref #11)
    pick e56a7a4 Configuration des bases de donnees pour le passage en version 2.2.3 (fixes #11 : fixé)
    
  • Sauver et quitter.
  • Lancer la commande :
    git commit --amend
    
  • Modifier les messages de commit, par ex :
    update des bases de donnees editable=0 et pas 2 (ref #11)
    
  • Sauvegarder et quitter
  • Lancer la commande :
    git rebase --continue
    
  • Vérifier les messages de commit
    git log
    

Fusionner des commits

Il est possible de fusionner des commit afin d'éviter des commits multiples pour des modifications mineures.
  • Lancer un git rebase
    git rebase -i HEAD~3
    

    pick 16098ec Ajout d'icône gepi et cdt (ref #51)
    pick f244e89 Deplacement d'icone
    pick 7c8670c Deplacement des icones sources
    
    # Rebase 5f5bfee..7c8670c onto 5f5bfee
    #
    # Commands:
    #  p, pick = use commit
    #  r, reword = use commit, but edit the commit message
    #  e, edit = use commit, but stop for amending
    #  s, squash = use commit, but meld into previous commit
    #
    # If you remove a line here THAT COMMIT WILL BE LOST.
    # However, if you remove everything, the rebase will be aborted.
    #
    
  • Changer pick en squash fusionne votre commit avec la ligne au-dessus
    pick 16098ec Ajout d'icône gepi et cdt (ref #51)
    squash f244e89 Deplacement d'icone
    squash 7c8670c Deplacement des icones sources
    
  • Sauver et quitter, Un éditeur s'ouvre:
    # This is a combination of 3 commits.
    # The first commit's message is:
    Ajout d'icône gepi et cdt (ref #51)
    
    # This is the 2nd commit message:
    
    Deplacement d'icone
    
    # This is the 3rd commit message:
    
    Deplacement des icones sources
    
    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    # Not currently on any branch.
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #       modified:   eole/tmpls/update_creole_posh.sql
    #       renamed:    plugins/plugin_desktop/icones/old/Corbeille.png -> plugins/plugin_desktop/icones/Corbeille.png
    #       renamed:    plugins/plugin_desktop/icones/old/Courrier.png -> plugins/plugin_desktop/icones/Courrier.png
    #       renamed:    plugins/plugin_desktop/icones/old/agenda.png -> plugins/plugin_desktop/icones/agenda.png
    #       new file:   plugins/plugin_desktop/icones/cdt.png
    #       modified:   plugins/plugin_desktop/icones/dir.png
    #       modified:   plugins/plugin_desktop/icones/gepi.png
    #       renamed:    plugins/plugin_desktop/icones/old/mail.jpg -> plugins/plugin_desktop/icones/mail.jpg
    #       modified:   plugins/plugin_desktop/icones/mail.png
    #       new file:   sources-desktop/icones/cdt.xcf
    #       renamed:    plugins/plugin_desktop/icones/grand/moodle.gif -> sources-desktop/icones/moodle.gif
    #
    # Untracked files:
    #   (use "git add <file>..." to include in what will be committed)
    #
    #       databases/bdd/scribe-posh.sql.sav
    
  • Éditer les messages (un message suffit)
    # The first commit's message is:
    Ajout d'icône pour les applications scribe (ref #51)
    # This is the 2nd commit message:
    
    # This is the 3rd commit message:
    
    # Please enter the commit message for your changes. Lines starting
    
  • Sauver et quitter
  • Vérifier que cela ressemble bien à ce que vous voulez
    git log
    

Trucs et astuces

  • Résoudre un signalement avec l'ajout de "fixes #<numéro du signalement>"
    git commit -m"La nouvelle feature fixes #<numéro du signalement>" 
    git push ....
    
  • Faire référence à un signalement
    git commit -m"bla bla bal du bug #<numéro du signalement>" 
    
  • Activer la coloration syntaxique
    git config --global color.ui true
    
  • Pour controler les fichiers à ne JAMAIS prendre en compte (commit), utiliser le fichier ~/.gitignore. Exemple d'un fichier ~/.gitignore :
    # ignorer le fichier lui même
    .gitignore
    # les fichiers de sauvegarde VIM
    *~
    # ignorer les fichiers html générés
    *.html
    # sauf mon_fichier.html que je veux prendre en compte
    !mon_fichier.html
    # ignorer les dossiers @.svn@
    .svn
    # ignore documentation buid html files
    .build
    

De nombreux exemples de gitignore en fonction des applications et des frameworks : https://github.com/github/gitignore

  • Le fichier ~/.gitconfig peut permettre d'éviter de taper trop au clavier :
    [alias]
          st = status
          di = diff
          co = checkout
          ci = commit
          br = branch
          sta = stash
    
  • Pour éviter de taper l'URL et son mot de passe à chaque push et pull, il faut :
    • configurer l'URL du projet
      git config remote.origin.url http://194.167.18.22/git/projet/
      git config remote.origin.mirror false
      
    • renseigner le fichier ~/.netrc :
      machine dev-eole.ac-dijon.fr
      login monlogin
      password monmotdepasse
      
    • paramétrer les droits du fichier ~/.netrc :
      chmod 600 ~/.netrc
      

      Ensuite git push et git pull ne posent plus de questions.
  • Pour faire le ménage :
    git repack
    git prune
    
  • Pour repérer des commit dans des branches qui n'ont pas été fusionnés (merge) dans la branche principale :
  • Pour voir les commit dans la branche ma_branche qui n'ont pas été fusionnés (merge) dans master :
    git cherry -v master ma_branche
    

De subversion vers git

Il n'existe pas de commande update. Lorsqu'un fichier a été modifié localement par erreur et qu'on veut récupérer l'original, les habitudes étaient :

rm mon_fichier
svn update

A la place, il faut faire

git checkout mon_fichier

Pour revenir à un checkout frais dans le projet entier, utiliser reset. On peut annuler un commit en faisant :

git reset --hard HEAD

De bazaar vers git

Il est possible de suivre un projet bzr depuis git grâce à un plugin.

Certains logiciels sont ainsi suivi au sein du projet EOLE.

Créer un patch et l'intégrer

Dans un projet (Ex.: conf-horus) on a créé une branche "ma_branche" dans laquelle on a fait des modifications (par rapport à "master").

On veut récupérer un fichier recensant les différences entre la branche master et la branche ma_branche (un fichier diff) :

git diff master [nom-de-branche]  > file.patch

  • Une fois le patch récupéré, pour l'inclure dans la branche master :
git apply --stat file.patch
git apply --check file.patch
permet de tester le patch, et :
git apply file.patch
permet de l'appliquer

Tags

git fait une différence entre les branches et les tags, cela se voit bien avec git-gui (vue de l'historique des branches).

Une branche est modifiable, un tag ne l'est pas.

  • Création du tag :
    git tag mon-premier-tag
    
  • Liste des tags :
    git tag
    
  • Commit d'un tag :
    git push --tags http://login@dev-eole.ac-dijon.fr/git/sandbox
    
    • ou bien :
      git push http://login@dev-eole.ac-dijon.fr/git/sandbox <nom_tag>
      
    • ou encore :
      git push http://login@dev-eole.ac-dijon.fr/git/sandbox <nom_branche> <nom_tag>
      
  • Recupérer un tag :
    git checkout tags/<nom_tag>
    
  • Pour voir quel commit exactement a été taggé :
    git show <nom_tag>
    

bash_gitprompt_en.zip - Le prompt pour un GIT en anglais (961 octets) Arnaud FORNEROT, 27/03/2014 10:42

bash_gitprompt_fr.zip - Le prompt pour un GIT en français (978 octets) Arnaud FORNEROT, 27/03/2014 11:04