GIT *** Git est le dernier née des outils de gestion de version. Contrairement à Subversion ou CVS il n'est pas centralisé mais **distribué**: chaque développeur possède son workspace mais aussi son dépôt ... ainsi il n'y a pas de serveur central. Ce mécanisme est déroutant pour une organisation bien structurée comme une entreprise ... mais cela peut être très efficase pour une communauté. Git peut être utilisé localement mais aussi utilisé des protocoles ssh, http ou git comme moyen d'échange. Utilisation basique =================== Installation ------------ Pour windows il existe un executable qui installe l'ensemble des outils. Il faut noter que l'installation classique sous windows n'installe pas de **service** donc windows ne peut être un dépot **distant** qu'on utilise via ssh, git ou http. Il faut installer git sous windows en mode ligne de commande ... cela est plus simple par la suite. On peut comme même donner accès au dépot aux autres developpeurs via l'utilisation d'un partage réseau du dossier git portant le projet. Sous linux un simple apt-get peut suffir, sinon depuis les sources :: apt-get install libcurl4-gnutls-dev libexpat1-dev gettext zlib1g-dev libssl-dev apt-get install make tar zxvf git-1.9.0.tar.gz cd git-1.9.0 make prefix=/usr/local all sudo make prefix=/usr/local install Première utilisation -------------------- Il va falloir tout d'abord paramétrer git, via la commande :: git config Une configuration minimal :: git config --global user.name "manager" git config --global user.email "manager@myproject.org" git config --list core.symlinks=false core.autocrlf=true color.diff=auto color.status=auto color.branch=auto color.interactive=true pack.packsizelimit=2g help.format=html http.sslcainfo=/bin/curl-ca-bundle.crt sendemail.smtpserver=/bin/msmtp.exe diff.astextplain.textconv=astextplain rebase.autosquash=true user.name=manager user.email=manager@myproject.org il est possible de configurer un proxy :: git config --global http.proxy http://user:pass@proxyhost:proxyport On va maintenant initier un nouveau dépot :: mkdir myproject cd myproject git init > Initialized empty Git repository in C:/Users/fraoustin/Downloads/myproject/.git/ Nous allons maintenant: * pouvoir ajouter notre premier programme de notre projet * tester notre programme * indiquer à git que nous ajoutons ce premier fichier à l'index de notre workspace * valider (=commiter) les modifications de notre workspace sur le dépot .. note:: Il faut bien noter que nous modifions tout d'abord le workspace et qu'après nous modifions le dépot :: echo print('initialisation') > test.py python test.py > initialisation git add test.py git commit -m "premier commit" > [master (root-commit) 72bc0f2] premier commit > 1 file changed, 1 insertion(+) > create mode 100644 test.py Nous pouvons maintenant: * visualiser l'état * modifier notre programme * tester le programme * visualiser l'état :: git status > On branch master > nothing to commit, working directory clean echo print('modification 1') > test.py python test.py > modification 1 git status > On branch master > Changes not staged for commit: > (use "git add ..." to update what will be committed) > (use "git checkout -- ..." to discard changes in working directory) > > modified: test.py > > no changes added to commit (use "git add" and/or "git commit -a") git commit -m "deuxième commit" > On branch master > Changes not staged for commit: > modified: test.py > > no changes added to commit git log > commit 72bc0f250bb20e94c25db701e5d06419f0b0a86e > Author: manager > Date: Fri May 2 16:11:20 2014 +0200 > > premier commit > On voit que notre deuxième commit n'a rien modifié ... pourquoi? car nous n'avons pas indiqué à git que nous validions les modifications de notre Workspace :: git add test.py git commit -m "deuxième commit" > [master 1f04106] deuxième commit > 1 file changed, 1 insertion(+), 1 deletion(-) git log > commit 1f04106d63b9e9c5419717e58749d31aa2823bd6 > Author: manager > Date: Fri May 2 16:18:35 2014 +0200 > > deuxième commit > > commit 72bc0f250bb20e94c25db701e5d06419f0b0a86e > Author: manager > Date: Fri May 2 16:11:20 2014 +0200 > > premier commit Testons le retour en arrière, pour cela * modifions le programme * testons le programme * annulons la modification * testons le programme :: echo print('modification 2') > test.py python test.py > modification 2 git checkout -- test.py python test.py > modification 1 Utilisons la notion de tag pour permettre de réaliser des checkouts plus facile * modifions le programme * testons le programme * ajoutons la modification et commitons * tagons comme V1 cette version * modifions le programme * testons le programme * ajoutons la modification et commitons * visualisons les tags * visualisons les logs * visualisons le contenu du tag V1 * revenons à la version V1 * testons le programme * revenons au dernier commit :: echo print('modification 2') > test.py python test.py > modification 2 git commit -a -m "troisieme commit" > [master 76d48a8] troisieme commit > 1 file changed, 1 insertion(+), 1 deletion(-) git tag -a V1 -m "ma premiere version officielle" echo print('modification 3') > test.py python test.py > modification 3 git commit -a -m "quatrieme commit" > [master 81ab001] quatrieme commit > 1 file changed, 1 insertion(+), 1 deletion(-) git log > commit 81ab001ef9d76b58742ea7b236825467ac931310 > Author: manager > Date: Fri May 2 16:33:54 2014 +0200 > > quatrieme commit > > commit 76d48a8027dfef0d027c809194f2481f9df5f632 > Author: manager > Date: Fri May 2 16:33:07 2014 +0200 > > troisieme commit > > commit 1f04106d63b9e9c5419717e58749d31aa2823bd6 > Author: manager > Date: Fri May 2 16:18:35 2014 +0200 > > deuxième commit > > commit 72bc0f250bb20e94c25db701e5d06419f0b0a86e > Author: manager > Date: Fri May 2 16:11:20 2014 +0200 > > premier commit > git tag > V1 git show V1 > tag V1 > Tagger: manager > Date: Fri May 2 16:33:30 2014 +0200 > > ma premiere version officielle > > commit 76d48a8027dfef0d027c809194f2481f9df5f632 > Author: manager > Date: Fri May 2 16:33:07 2014 +0200 > > troisieme commit > > diff --git a/test.py b/test.py > index 1a3a66e..a43e971 100644 > --- a/test.py > +++ b/test.py > @@ -1 +1 @@ > -print('modification 1') > +print('modification 2') git checkout V1 > Note: checking out 'V1'. > > You are in 'detached HEAD' state. You can look around, make experimental > changes and commit them, and you can discard any commits you make in this > state without impacting any branches by performing another checkout. > > If you want to create a new branch to retain commits you create, you may > do so (now or later) by using -b with the checkout command again. Example: > > git checkout -b new_branch_name > > HEAD is now at 76d48a8... troisieme commit python test.py > modification 2 git checkout master > Previous HEAD position was 76d48a8... troisieme commit > Switched to branch 'master' git checkout python test.py > modification 3 .. warning:: Il faut noter que le checkout V1 génère une branche qui faut par la suite supprimer Travail à plusieurs ------------------- Supposons que vous partagez le dossier **myproject** il est possible pour un autre développeur de travailler sur ce project en créant lui même son dépôt .. note:: dans cette solution de partage la sécurité est lié au droits de lecture / d'écriture sur le dossier en lui même. La première à chose sur le dépot du project manager :: git config --bool core.bare true .. note:: le paramètre bare dans git permet d'indiquer qu'un projet rentre en mode partagé On peut aussi lors de l'initialisation du projet, indiquer le mode "partagé" de cette façon :: git init --bare /my/directory/projet Nous allons donc prendre la place d'un developpeur * configurer git * récupérer myproject dans myprojectdistant * tester le programme * visualiser le dernier commit * modifier le programme * tester le programme * ajouter et commiter la modification * visualier le dernier commit sur le poste developpeur :: git config --global user.name "developper" git config --global user.mail "developper@myproject.org" git clone myproject myprojectdistant > Cloning into 'myprojectdistant'... > done. cd myprojectdistant python test.py > modification 3 echo print('modification 1 by dev') > test.py python test.py > modification 1 by dev git add test.py git commit -m "premier commit dev" > [master b4d80e6] premier commit dev > 1 file changed, 1 insertion(+), 1 deletion(-) git log -p -2 > commit b4d80e6c7e913f62846b9280cec2a4b5a960c851 > Author: developper > Date: Fri May 2 18:00:30 2014 +0200 > > premier commit dev > > diff --git a/test.py b/test.py > index fecee96..793e1b2 100644 > --- a/test.py > +++ b/test.py > @@ -1 +1 @@ > -print('modification 3') > +print('modification 1 by dev') > > commit 81ab001ef9d76b58742ea7b236825467ac931310 > Author: manager > Date: Fri May 2 16:33:54 2014 +0200 > > quatrieme commit > > diff --git a/test.py b/test.py > index a43e971..fecee96 100644 > --- a/test.py > +++ b/test.py > @@ -1 +1 @@ > -print('modification 2') > +print('modification 3') Si on regarde du côté manager on voit bien qu'on ne voit pas la modification du developpeur :: git log -p -2 > commit 81ab001ef9d76b58742ea7b236825467ac931310 > Author: manager > Date: Fri May 2 16:33:54 2014 +0200 > > quatrieme commit > > diff --git a/test.py b/test.py > index a43e971..fecee96 100644 > --- a/test.py > +++ b/test.py > @@ -1 +1 @@ > -print('modification 2') > +print('modification 3') > > commit 76d48a8027dfef0d027c809194f2481f9df5f632 > Author: manager > Date: Fri May 2 16:33:07 2014 +0200 > > troisieme commit > > diff --git a/test.py b/test.py > index 1a3a66e..a43e971 100644 > --- a/test.py > +++ b/test.py > @@ -1 +1 @@ > -print('modification 1') > +print('modification 2') On peut sur le poste de développeur visualiser les infos d'origine :: git remote -v > origin C:/Users/fraoustin/Downloads/myproject (fetch) > origin C:/Users/fraoustin/Downloads/myproject (push) git remote show origin > * remote origin > Fetch URL: C:/Users/fraoustin/Downloads/myproject > Push URL: C:/Users/fraoustin/Downloads/myproject > HEAD branch: master > Remote branch: > master tracked > Local branch configured for 'git pull': > master merges with remote master > Local ref configured for 'git push': > master pushes to master (fast-forwardable) On peut synchroniser maintenant les modifications du developpeur (dépot myprojectdistant) sur le dépot du manager (myproject) :: git push origin > Counting objects: 5, done. > Writing objects: 100% (3/3), 274 bytes | 0 bytes/s, done. > Total 3 (delta 0), reused 0 (delta 0) > To C:/Users/fraoustin/Downloads/myproject > 81ab001..b4d80e6 master -> master maintenant sur le dépot du manager on voit bien l'intervention du developpeur :: git log -p -2 > commit b4d80e6c7e913f62846b9280cec2a4b5a960c851 > Author: developper > Date: Fri May 2 18:00:30 2014 +0200 > > premier commit dev > > diff --git a/test.py b/test.py > index fecee96..793e1b2 100644 > --- a/test.py > +++ b/test.py > @@ -1 +1 @@ > -print('modification 3') > +print('modification 1 by dev') > > commit 81ab001ef9d76b58742ea7b236825467ac931310 > Author: manager > Date: Fri May 2 16:33:54 2014 +0200 > > quatrieme commit > > diff --git a/test.py b/test.py > index a43e971..fecee96 100644 > --- a/test.py > +++ b/test.py > @@ -1 +1 @@ > -print('modification 2') > +print('modification 3') Nous pouvons maintenant l'inverse, via la console manager: * modification de la variable care.bare * modification du programme * test * ajout et commit de la modification * visualisation des logs * modification de la variable care.bare :: git config --bool core.bare false echo print('modification finale') > test.py python test.py > modification finale git commit -a -m "last commit" > [master b2b2893] last commit > 1 file changed, 1 insertion(+), 1 deletion(-) git log -p -2 > commit b2b2893a8d7f4b152e77cc7101535fd78bae2755 > Author: manager > Date: Fri May 2 18:29:07 2014 +0200 > > last commit > > diff --git a/test.py b/test.py > index 793e1b2..9ac3b53 100644 > --- a/test.py > +++ b/test.py > @@ -1 +1 @@ > -print('modification 1 by dev') > +print('modification finale') > > commit b4d80e6c7e913f62846b9280cec2a4b5a960c851 > Author: developper > Date: Fri May 2 18:00:30 2014 +0200 > > premier commit dev > > diff --git a/test.py b/test.py > index fecee96..793e1b2 100644 > --- a/test.py > +++ b/test.py > @@ -1 +1 @@ > -print('modification 3') > +print('modification 1 by dev') git config --bool core.bare true Maintenant sur la console developpeur * récupération des modifications sur une branche à part * fusion de la nouvelle bracnhe avec la branche master (git pull) * test du programme :: git fetch origin git pull > Updating b4d80e6..b2b2893 > Fast-forward > test.py | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) python test.py > modification finale .. note:: Afin d'éviter d'être en permanence en train de changer la config de core.bare il est judicieux de laisser sur le serveur "centrale" la variable core.bare à false et créer pour le manager un nouveau dépôt distant Les commandes utiles: * git add ajout d'une modification au workspace * git status visualise le status actuel du projet * git tag -a Version -m "message" permet de tager une version * git tag -s Version -m "message" permet de signer une version * git log visualise l'historique des commits du dépot (un git log -p 2 permet de visualiser les deux derniers commits) * git commit (-a) commit les modifications du workspace (et ajoute ces dernières) * git checkout remplace le workspace par la version du dépot * git branch NameBranch création d'un branche * git merge NameBranch fusionne la branche master avec la branche NameBranch * git clone permet de récupérer un project d'un autre dépot * git rm fichier efface un fichier * git pull récupère les modifications d'un dépot distant et on fusionne * git remote -v visualise les serveurs distants * git remote show origin visualise le dépôt distant d'origine Utilisation avancée =================== Comment mettre en place git dans une situation professionnelle? Pour cela il faut mettre en place une architecture distribuée et sécurisée. Nous allons donc placer sur un serveur debian **ssh** notre repository distant. Puis des développeurs viendront cloner et mettre à jour le repository en utilisant des notions de branches Sur le serveur debian **ssh** nous allons installer git .. code-block:: bash su - root apt-get install libcurl4-gnutls-dev libexpat1-dev gettext zlib1g-dev libssl-dev apt-get install make wget https://www.kernel.org/pub/software/scm/git/git-2.3.5.tar.gz mv git-2.3.5.tar.gz /opt cd /opt tar zxvf git-2.3.5.tar.gz rm git-2.3.5.tar.gz cd git-2.3.5 make prefix=/usr/local all make prefix=/usr/local install ln -s /opt/git-2.3.5 /opt/git ln -s /opt/git/git /usr/bin/git Nous créons le compte **git**, avec pour password **passgit** .. code-block:: bash su - root useradd git .. note:: l'utilisateur git devra se connecter sur la machine en ssh, il peut être utile de vérifier dans la configuration de ssh /etc/ssh/sshd_config le group autorisé à se connecter (AllowGroups) Essayons le compte **git**, et créons le dossier **projects** .. code-block:: bash su - git mkdir projects exit ssh git@localhost exit Nous allons maintenant créer le dépot pour notre projet ** project1.git** .. code-block:: bash su - git cd projects mkdir project1.git cd project1.git git init --bare > Dépôt Git vide initialisé dans /home/git/projects/project1.git/ Et voilà, nous allons maintenant avec un utilisateur classique: * paramétrer son git * créer un dossier workspace * récupérer le dépot de notre projet .. code-block:: bash su - fraoustin git config --global user.name "fraoustin" git config --global user.email "fraoustin@gmail.com" mkdir workspace cd workspace git clone git@localhost:/home/git/projects/project1.git cd project1 git fetch origin .. note:: la commande fetch permet de synchroniser la branche origin avec le repository local Nous allons modifier notre fichier de paramétrage git afin de rendre certaines commandes plus visuelles. Pour cela on édite ~\.gitconfig .. code-block:: bash [alias] graph = log --pretty=online --abbrev-commit --graph changes = diff --name-status On peut maintenant utiliser les commandes git graphbet git changes On va maintenant * modifier project1 * remonter les modifications dans l'index local * commiter les modifications dans le repository local * pousser les modifications sur le repository distant .. code-block:: bash su - fraoustin cd workspace/project1 echo "print('modification 1 by dev')" > test.py python test.py > modification 1 by dev git add test.py git commit -m "modification 1 by dev" git log > commit 1612153518c6f05aaab2644a5db352630b289988 > Author: fraoustin > Date: Sun Apr 5 17:58:03 2015 +0200 > > modification 1 by dev git push > Décompte des objets: 3, fait. > Écriture des objets: 100% (3/3), 245 bytes | 0 bytes/s, fait. > Total 3 (delta 0), reused 0 (delta 0) > To git@localhost:/home/git/projects/project1.git > * [new branch] master -> master un schéma qui illustre le fonctionnement de git .. figure:: data/git_cmd.png Maintenant un autre utilisateur **userlx** va aussi récuperer le projet. Les actions que va réaliser userlx sont: * paramétrer son git * création d'un dossier workspace * récupération dans un repository local * test du programme test.py * visualisation de l'historique de modification du projet .. code-block:: bash su - userlx git config --global user.name "userlx" git config --global user.email "userlx@gmail.com" mkdir workspace cd workspace git clone git@localhost:/home/git/projects/project1.git cd project1 python test.py > modification 1 by dev git log > commit 1612153518c6f05aaab2644a5db352630b289988 > Author: fraoustin > Date: Sun Apr 5 17:58:03 2015 +0200 > > modification 1 by dev L'utilisateur **userlx** va maintenant * modifier project1 * visualiser les modifications réalisées * remonter les modifications dans l'index local * commiter les modifications dans le repository local * pousser les modifications sur le repository distant .. code-block:: bash su - userlx cd workspace/project1 echo "print('modification 1 by userlx')" >> test.py python test.py > modification 1 by dev > modification 1 by userlx git diff > diff --git a/test.py b/test.py > index 48cf62e..a4b9c4a 100644 > --- a/test.py > +++ b/test.py > @@ -1 +1,2 @@ > print('modification 1 by dev') >+print('modification 1 by userlx') git add test.py git commit -m "modification 1 by userlx" git log > commit 240db1d16dd075cc850aee5640967d392e7a5bf5 > Author: userlx > Date: Sun Apr 5 18:37:12 2015 +0200 > > modification 1 by userlx > > commit 1612153518c6f05aaab2644a5db352630b289988 > Author: fraoustin > Date: Sun Apr 5 17:58:03 2015 +0200 > > modification 1 by dev git push Maintenant notre utilisateur va * récuperer les modifications du repository distants dans son repository local * lancer le programme * visualiser les changements .. code-block:: bash su - fraoustin cd workspace/project1 git pull > Mise à jour 1612153..240db1d > Fast-forward > test.py | 1 + > 1 file changed, 1 insertion(+) python test.py > modification 1 by dev > modification 1 by userlx git log > commit 240db1d16dd075cc850aee5640967d392e7a5bf5 > Author: userlx > Date: Sun Apr 5 18:37:12 2015 +0200 > > modification 1 by userlx > > commit 1612153518c6f05aaab2644a5db352630b289988 > Author: fraoustin > Date: Sun Apr 5 17:58:03 2015 +0200 > > modification 1 by dev Maintenant notre utilisateur va * modifier le programme * le lancer * récuperer la dernière version de son repository locale afin de supprimer sa modification * lancer le programme (pour vérifier que le programme ne contient plus la modification) .. code-block:: bash su - fraoustin cd workspace/project1 echo "print('modification 2 by dev')" >> test.py python test.py > modification 1 by dev > modification 1 by userlx > modification 2 by dev git checkout -- test.py python test.py > modification 1 by dev > modification 1 by userlx .. note:: au lieu de supprimer sa dernière modification d'un fichier si on veut revenir à la version du repository distant pour l'ensemble du projet on lance .. code-block:: bash git fetch origin git reset --hard origin/master .. warning:: afin de rendre la lecture des logs plus simple j'utilise la ligne suivante .. code-block:: bash git log --graph --pretty=oneline --abbrev-commit --decorate --all pour pretty une valeur **medium** est idéal pour moi le **all** permet de voir toutes les branches et j'active les couleurs dans les réponses de git .. code-block:: bash git config color.ui true Nous allons maintenant traiter la problématique des branches. Notre utilisateur va * créer une nouvelle branche **branch1** * insérer une modification * tester la modifiction * commiter sa modification * pousser sa nouvelle branche **branch1** sur le serveur .. code-block:: bash su - fraoustin cd workspace/project1 git checkout -b branch1 > Basculement sur la nouvelle branche 'branch1' echo "print('modification 1 for branch1 by dev')" >> test.py python test.py > modification 1 by dev > modification 1 by userlx > modificaiton 1 for branch1 by dev git add test.py git commit -m "ajout pour branch1" git push origin branch1 > Décompte des objets: 3, fait. > Delta compression using up to 2 threads. > Compression des objets: 100% (2/2), fait. > Écriture des objets: 100% (3/3), 295 bytes | 0 bytes/s, fait. > Total 3 (delta 0), reused 0 (delta 0) > To git@localhost:/home/git/projects/project1.git > * [new branch] branch1 -> branch1 Nous pouvons voir ce qui se passe au niveau des branches, l'utilisateur va se placer sur chacune des branches pour voir le résultat du programme et les logs enregistrés par git .. code-block:: bash su - fraoustin cd workspace/project1 git checkout branch1 python test.py > modification 1 by dev > modification 1 by userlx > modificaiton 1 for branch1 by dev git log --graph --pretty=oneline --abbrev-commit > * 6911dc0 ajout pour branch1 > * 240db1d modification 1 by userlx > * 1612153 modification 1 by dev git checkout master python test.py > modification 1 by dev > modification 1 by userlx git log --graph --pretty=oneline --abbrev-commit > * 240db1d modification 1 by userlx > * 1612153 modification 1 by dev Maintenant on demande à **userlx** de travailler sur la branche **branch1** afin de modifier le programme. Pour cela il va * visualiser les branches disponibles * rafraichir son repository local * basculer sur la branche **branch1** * modifier le programme * commiter ces modifications * pousser ces modifications sur le repository distant .. code-block:: bash su - userlx cd workspace/project1 git remote show origin > URL de rapatriement : git@localhost:/home/git/projects/project1.git > URL push : git@localhost:/home/git/projects/project1.git > Branche HEAD : master > Branches distantes : > branch1 nouveau (le prochain rapatriement (fetch) stockera dans remotes/origin) > master suivi > Branche locale configurée pour 'git pull' : > master fusionne avec la distante master > Référence locale configurée pour 'git push' : > master pousse vers master (à jour) git pull > remote: Décompte des objets: 3, fait. > remote: Compression des objets: 100% (2/2), fait. > remote: Total 3 (delta 0), reused 0 (delta 0) > Dépaquetage des objets: 100% (3/3), fait. > Depuis localhost:/home/git/projects/project1 > * [nouvelle branche] branch1 -> origin/branch1 > Already up-to-date. git checkout branch1 > La branche branch1 est paramétrée pour suivre la branche distante branch1 depuis origin. > Basculement sur la nouvelle branche 'branch1' python test.py > modification 1 by dev > modification 1 by userlx > modification 1 for branch1 by dev echo "print('modification 2 for branch1 by userlx')" >> test.py python test.py > modification 1 by dev > modification 1 by userlx > modification 1 for branch1 by dev > modificaiton 2 for branch1 by userlx git add test.py git commit -m "ajout pour branch1 by userlx" git push origin branch1 Maintenant notre utilisateur va * supprimer sa branch1 locale * suivre la branche1 distante (ce mécanisme est bizarre ... mais un git remote show origin nous indique qu'on ne fait pas de pull sur la branch1) * récuperer les modifications de userlx sur la branch1 * vérifier les logs de la branch1 * fusionner la branch1 sur la branche master .. code-block:: bash su - fraoustin cd workspace/project1 git remote show origin > * distante origin > URL de rapatriement : git@localhost:/home/git/projects/project1.git > URL push : git@localhost:/home/git/projects/project1.git > Branche HEAD : master > Branches distantes : > branch1 suivi > master suivi > Branche locale configurée pour 'git pull' : > master fusionne avec la distante master > Références locales configurées pour 'git push' : > branch1 pousse vers branch1 (à jour) > master pousse vers master (à jour) git branch -D branch1 git checkout --track origin/branch1 git remote show origin > * distante origin > URL de rapatriement : git@localhost:/home/git/projects/project1.git > URL push : git@localhost:/home/git/projects/project1.git > Branche HEAD : master > Branches distantes : > branch1 suivi > master suivi > Branche locale configurée pour 'git pull' : > branch1 fusionne avec la distante branch1 > master fusionne avec la distante master > Références locales configurées pour 'git push': > branch1 pousse vers branch1 (à jour) > master pousse vers master (à jour) git pull git checkout branch1 python test.py > modification 1 by dev > modification 1 by userlx > modification 1 for branch1 by dev > modificaiton 2 for branch1 by userlx git log --graph --pretty=oneline --abbrev-commit > * f4bf3b4 ajout pour branch1 by userlx > * 6911dc0 ajout pour branch1 > * 240db1d modification 1 by userlx > * 1612153 modification 1 by dev git checkout master python test.py > modification 1 by dev > modification 1 by userlx git log --graph --pretty=oneline --abbrev-commit > * 240db1d modification 1 by userlx > * 1612153 modification 1 by dev git merge branch1 > Mise à jour 240db1d..f4bf3b4 > Fast-forward > test.py | 2 ++ > 1 file changed, 2 insertions(+) python test.py > modification 1 by dev > modification 1 by userlx > modification 1 for branch1 by dev > modificaiton 2 for branch1 by userlx git add test.py git commit -m "version finale" git push Il est possible de créer des branches locale et de les supprimer .. code-block:: bash git checkout -b branch_local git branch -d branch_local Il est possible aussi de demander à git de suivre une nouvelle branche .. code-block:: bash git checkout --track origin/branch_distante Un autre exemple est la création d'une nouvelle branche qui permet d'obtenir ce genre de log .. code-block:: bash git log --oneline --abbrev-commit --all --graph > * 18e1e63 Merge branch 'branch2' > |\ > | * 55180c1 branch2 > * | 78f9d4e version finale finale > |/ > * f4bf3b4 ajout pour branch1 by userlx > * 6911dc0 ajout pour branch1 > * 240db1d modification 1 by userlx > * 1612153 modification 1 by dev un schéma qui illustre la gestion des branches .. figure:: data/git_branch.png