2.9.2
)On initialise certaine variables (une fois pour toute en général) :
$ git config --global user.name "JM Bruel" $ git config --global user.email jbruel@gmail.com $ git config --global alias.co checkout
Ces informations sont stockées dans le fichier Voici un extrait du mien : [user] name = Jean-Michel Bruel email = jbruel@gmail.com [alias] co = checkout st = status Ce qui donne : $ git co Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) $ git checkout Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) |
On démarre la gestion de version :
$ git init
Génération d’un répertoire $ git init Initialized empty Git repository in /tmp/.git/ $ ll total 0 drwxr-xr-x 3 bruel admin 102 21 jul 17:29 ./ drwxr-xr-x 35 bruel admin 1190 21 jul 17:29 ../ drwxr-xr-x 10 bruel admin 340 21 jul 17:29 .git/ |
On ajoute les fichiers courants au dépôt :
$ git add .
|
|
On peut visualiser les actions en vérifiant l'état courant du dépôt :
$ git status # On branch master # Your branch is ahead of 'origin/master' by 1 commit. # # Changes not staged for commit: # (use "git add/rm <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: Generalites.txt # deleted: S3/128056_56.d ...
Pour entériner les changements :
$ git commit -m "First draft" [master (root-commit) 4f40f5d] First draft 0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 titi.txt create mode 100644 toto.txt
|
Exemple de scénario type (suppression exceptionnelle et rattrapage) :
$ rm titi.txt $ git status # On branch master # Changes not staged for commit: # (use "git add/rm <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # deleted: titi.txt # no changes added to commit (use "git add" and/or "git commit -a") $ git checkout -f $ ls titi.txt titi.txt
Il existe de nombreux endroits disponibles pour héberger du code libre. Les plus connus sont GitHub et GitLab.
Après avoir créé un dépôt distant, il n’y a plus qu’à associer ce dépôt distant avec le notre.
$ git remote add origin git@github.com:jmbruel/first_app.git (1) $ git push -u origin master (2) Counting objects: 3, done. Delta compression using up to 2 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 225 bytes, done. Total 3 (delta 0), reused 0 (delta 0) To git@github.com:jmbruel/first_app.git * [new branch] master -> master Branch master set up to track remote branch master from origin.
1 | Il est possible d’avoir plusieurs dépôts distants, celui-ci sera référencé par origin . |
2 | L’option -u origin master permet d’associer une fois pour toute les git push suivants au fait
de "pousser" sur la branche master du dépôt origin (comme l’indique la dernière ligne). |
En cas d’édition et de commit local :
$ git checkout Your branch is ahead of 'origin/master' by 1 commit.
est très bon pour créer des branches :
$ git checkout -b testModifTiti Switched to a new branch 'testModifTiti' $ git branch master * testModifTiti (1)
1 | La branche courante est repérée par un * . |
Après modification :
$ git status # On branch testModifTiti # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: titi.txt # no changes added to commit (use "git add" and/or "git commit -a")
On "sauvegarde" les changements :
$ git commit -am "modif de titi" [testModifTiti 4515b5d] modif de titi 1 files changed, 7 insertions(+), 0 deletions(-)
|
On peut "zapper" d’une branche à l’autre à volonté :
$ ll titi* -rw-rw-r-- 1 bruel staff 331 12 nov 12:39 titi.txt $ git co master Switched to branch 'master' Your branch is ahead of 'origin/master' by 1 commit. $ ll titi* -rw-rw-r-- 1 bruel staff 0 12 nov 12:40 titi.txt
Maintenant que la branche a été développée (testée, etc.) on peut l’intégrer à la branche principale :
$ git co master Switched to branch 'master' $ git merge testModifTiti Merge made by recursive. titi.txt | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
|
Maintenant que notre dépôt est satisfaisant, on peut le synchroniser avec le dépôt distant :
$ git push Counting objects: 11, done. Delta compression using up to 2 threads. Compressing objects: 100% (9/9), done. Writing objects: 100% (9/9), 977 bytes, done. Total 9 (delta 2), reused 0 (delta 0) To git@github.com:jmbruel/first_app.git 6103463..3aae48a master -> master
$ git checkout -b develop origin/develop $ ... (1) $ git checkout master $ git merge --no-ff develop (2) $ git push origin master (3)
1 | Vérifiez ce qui va être intégré |
2 | On merge localement pour gérer les problèmes |
3 | On pousse sur master |
Si vous devez partir d’un dépôt existant :
$ git clone git@github.com:jmbruel/first_app.git
|
Voici une illustration de l’utilisation des branches (tirée de git-scm).
On part d’une situation type :
On crée une branche (appelée iss53
ici pour indiquer qu’elle traite de l'issue numéro 53) :
$ git checkout -b iss53
On modifie et on commit :
$ edit ... $ git commit -m " blabla iss53"
On commence à diverger de master |
On revient à la branche maître pour tester une autre solution :
$ git checkout master $ git checkout -b hotfix $ edit ... $ git commit -m " blabla hotfix"
On intègre cette solution à la branche principale :
$ git checkout master $ git merge hotfix
Il manque le pointeur HEAD sur mes illustrations |
On continue à travailler sur la branche iss53
:
$ git branch -d hotfix (1) $ git checkout iss53 $ edit ... $ git commit -m " blabla iss53"
1 | Destruction de la branche devenue redondante avec master . |
On retravaille sur iss53 |
On intègre cette branche :
$ git checkout master $ git merge iss53
Merge sans fast-forward |
Situation finale |
|
Revenons sur l’exemple type :
Ce qu’il ne faut pas versionner :
En on peut taguer des branches et c’est ce mécanisme qui permet de gérer simplement les releases.
$ git tag -a v1.0 -m "Release 1.0 as required by client" $ git tag v1.0
On peut voir les détails d’un commit tagué :
$ git show v1.0 tag v1.0 Tagger: Jean-Michel Bruel <jbruel@gmail.com> Date: Fri Sep 16 14:27:20 2016 +0200 Release 1.0 as required by client commit 47da474098d95f8ef5c3ca838be8b87d7a7ed729 Author: Jean-Michel Bruel <jbruel@gmail.com> Date: Fri Sep 16 12:38:20 2016 +0200
On peut aussi taguer a posteriori :
$ git tag -a v1.2 9fceb02 (1)
1 | ajoute le tag v1.2 au commit dont le [SHA-1] commence par 9fceb02 |
Par défaut les tags ne sont pas poussés sur le dépôt distant. $ git push origin v1.5 |
$ git commit -m 'initial commit' $ git add forgotten_file $ git commit --amend
$ git add *.* $ git reset *.class
Aucun danger |
$ working on some file README.adoc ... $ git checkout -- REAME.adoc
Danger! |
$ git status
La principale difficulté de vient de la liberté en termes de branches.
Pour faire simple, je vous conseille une gestion qui marche bien pour les petites équipes, tiré de l’excellent livre Pro Git :
master
et develop
.$ git branch * develop (1) master (2)
1 | develop est la branche de travail qui contient la dernière version des codages en cours. |
2 | master est toujours stable et sert au déploiement |
develop
pour traiter un bug ou une feature.develop
Ce qui donne le flot suivant dès que vous devez faire une amélioration (corriger un bug ou ajouter une fonctionnalités) :
fix-451
)develop
master
Les exemples suivants sont tirés de :
merge
merge
via rebase
or fast-forward
merge
via fast-forward
merge
La principale activité du programmeur qui utilise en équipe vient de la gestion des conflits.
$ git checkout master $ git merge other_branch Auto-merging toto.txt CONFLICT (content): Merge conflict in toto.txt Automatic merge failed; fix conflicts and then commit the result. $ more toto.txt <<<<<<< HEAD (1) Salut monde ======= (2) hello world! >>>>>>> other_branch (3) $ vi toto.txt (4) $ git commit (5)
1 | Voilà où commence la différence entre la branche courante (HEAD )
et la branche qu’on essaye de merger (other_branch ) |
2 | Séparation |
3 | Voilà où se termine cette différence |
4 | on édite le fichier à la main pour choisir la bonne version |
5 | on commit pour valider la modif |
Il est déconseillé d’en profiter pour faire une nouvelle modif dans le fichier… |
git diff
git difftool
Voici un schéma pour résumer la philosophie (tiré de http://osteele.com) :