Mini-tutoriel

Dana & PA

Licence

Pour ce qui concerne tous les contenus que nous avons produits dans cette présentation :  licence Creative Commons Attribution - Pas d’Utilisation Commerciale 4.0 International.

...une développeuse, qui devait travailler avec Git

Il était une fois...

Quelques tutos plus tard :

$ git init

$ git config

$ git clone

Mais ... 

$ git init

$ git config

$ git add

$ git clone

$ git commit

Quelques tutos plus tard :

Mais ... 

$ git init

$ git commit

$ git config

$ git add

$ git clone

$ git status

$ git checkout

$ git branch

Quelques tutos plus tard :

Mais ... 

$ git init

$ git commit

$ git config

$ git add

$ git clone

$ git status

$ git pull

$ git checkout

$ git merge

$ git branch

$ git push

$ git ...

Quelques tutos plus tard :

Mais ... 

Elle a essayé aussi de regarder les interfaces graphiques

... et a eu du mal à choisir la "meilleure"...

Bref, on a l'impression de toujours mal faire,

c'est un peu décourageant tout ça...

git push origin master

Elle a eu des petits soucis, comme

Euh... donc... faut faire un pull avant ??

Auto-merging lib/hello.html
CONFLICT (content): Merge conflict in lib/hello.html
Automatic merge failed; fix conflicts and then commit the result.

Donc ... "fix conflicts"...

 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/USERNAME/REPOSITORY.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.
git pull origin

Tuto to the rescue !

Pourquoi la gestion des versions ?

Pour avoir une référence à la version précédente du code, pour essayer des nouvelles choses sans risque

Pour collaborer avec les autres

Git : logiciel de gestion de versions décentralisé

est un logiciel qui permet de stocker un ensemble de fichiers en conservant la chronologie de toutes les modifications qui ont été effectuées dessus

(Wikipédia)

Logiciel de gestion de versions (anglais : VCS = Version Control System)

VCS centralisé vs. décentralisé

VCS centralisé vs. décentralisé

VCS décentralisé :

- chacun a une copie complète du repository

- fonctionnalités en local : commit, branch, ...

Avantages

- rapide : opérations en local

- meilleure organisation personnelle : commit local

Notions de base

1. Commencer à utiliser Git

B. Créer son repository

C. Utiliser git :-)

"j'ai installé git"

git clone

git init

"j'ai un repository :-)"

Il existe un repository quelque part, et je le copie chez moi

Je crée un nouveau repository git sur ma machine

Notions de base

Les repositories

Ce sont eux qui gardent l'historique des changements

Chacun a son repository, il faut les synchroniser !

En pratique : un repository "central" (GitHub, Codendi, ...)

.git

.gitignore

MonCodeVersioné.java

...

mon_repository

Notions de base

2. Gérer les versions de code avec git

A. On modifie des fichiers

B. On "sauvegarde" l'état avec "commit"

Commit : un snapshot de l'état du repository

commit initial

SHA ID - l'identifiant du commit

add some functionality

a comme parent

Message - une description du changement

User - le créateur du commit

Parent - le commit précédent

Les étapes d'un commit

  • choisir quelles modifications "commiter"
    • staging ou ajout à l'index
  • créer un commit avec un message

Pourquoi le staging ?

ça permet de mieux organiser les snapshots, grouper les changements qui vont ensemble.

=> 2 commits

On peut indexer un fichier entier, ou indexer ligne par ligne

Exemple : 

on ajoute une fonctionnalité dans la méthode B

il y un bug dans la méthode A et on le corrige

Notions de base

2. Gérer les versions de code avec git

je code

commit

"je peux utiliser git :-)"

En résumé

Tout ça reste en local !!

stage

&

Notions de base

A partir d'un repository distant

Remote repository  

Local repository  

git clone

code

stage

commit

Notions de base

3. Partager son code avec les autres : push

Push copie (pousse) les commits

On doit toujours récupérer et intégrer la dernière version du code du repository distant avant le push

repository local               repository distant

But wait !!

Que se passe-t-il si le repository distant a changé ??

PULL

intégrer le code

PUSH

Notions de base

Pull

fetch

= fetch

Remote repository  

Local repository  

Notions de base

fetch

Pull

= fetch

Remote repository  

Local repository  

Notions de base

 + merge

Pull

= fetch

Remote repository  

Local repository  

Notions de base

push

Après le pull : push

Remote repository  

Local repository  

Merge

M1 {
   
}
M2 {
   
}
M1 {
   // modif U1
}
M2 {
   
}
M1 {
   // modif U1
}
M2 {
   // modif U2
}
M1 {
   
}
M2 {
   // modif U2
}

Conflits de merge

M1 {
   // code A
}
M2 {

}
M1 {
   // modif U1
}
M2 {
   
}
M1 {
   // modif U1
   // modif U2
}
M2 {

}
M1 {
   // modif U2
}
M2 {

}

????

Notions de base

En résumé

code

pull

push

en local

échange avec le serveur distant

commit

stage

&

Notions de base++

Mieux organiser le travail

Souvent, dans un projet :

- ajouter de nouvelles features

- correction des bugs

- créer un environnement de pré-prod

- créer un environnement de test

=> on souhaite compartimenter

Branch

Branch = une ligne de développement

En pratique : une branche = "pointeur" sur un commit

On est toujours "dans" une branche

Par défaut : la branche "master"

    => nos commits se font "dans la branche courante"

Pourquoi créer une nouvelle branche ?

  • feature

  • essayer quelque chose

  • les releases

    => si on supprime les pointeurs, on perd accès aux commits

Branch

master
featureA
git branch featureA
git checkout featureA

...new code...

master

On est dans 

featureA

Exemple : création d'une branche

Branch

Exemple : création d'une branche

master
git branch featureA
git checkout featureA

...new code...

git commit
featureA

On est dans 

featureA

Branch

Aller "dans" une branche :

git checkout maBranche

2 in 1 - créer une branche et l'utiliser :

git checkout -b nouvelleBranche

Créer :

git branch maBranche

On a au moins master (local) et origin/master (distant)

  • origin est le nom par défaut pour le repository distant    

Création des branches : en local

Branch : local et distant

  • partager la branche : git push origin maSuperBranche
  • on n'est pas obligés de partager toutes les branches ;-)

  • pratique courante : branche "developpement" locale

    • ​changements à intégrer dans une branche partagée (master)

Branch

Exemple

master
git checkout master
featureA

on découvre un bug (master) :-(

On est dans 

featureA

master

Branch

Exemple

master
git checkout -b bugFix

...on corrige le bug !!

featureA
bugFix

bugFix

git checkout master

on découvre un bug (master) :-(

On est dans 

Branch

Exemple

master

...on corrige le bug !!

git commit
featureA
bugFix
git checkout -b bugFix

bugFix

git checkout master

on découvre un bug (master) :-(

On est dans 

Branch : intégration

Merge

master
featureA

Le bug est corrigé !

=> intégrer le code dans master

git checkout master
bugFix

master

bugFix

On est dans 

Merge

master
featureA
git merge bugFix
git checkout master

Branch : intégration

bugFix

On on a intégré dans master les modifications de bugFix !!

fast-forward merge​ (bugFix était basé sur le dernier commit de master)

On est dans 

master

Le bug est corrigé !

=> intégrer le code dans master

Merge

On n'a plus besoin de la branche bugFix

git branch -d bugFix

Branch : intégration

master
featureA
bugFix
master

On est dans 

master

More merging !

master

Intégrer la feature...

Attention : la branche ne se base pas sur le dernier commit du master !!

git merge featureA
master

C'est un 3-way merge

Nouveau "commit de merge" !

Historique complet

Branch : intégration

featureA

On est dans 

master

Une autre façon pour intégrer le code

Le commit de featureA devrait appartenir au master

git checkout featureA

Rebase change le parent d'une branche.

Branch : intégration

master
featureA

On est dans 

master

featureA

git checkout featureA
git rebase master

intègre dans featureA les changements de master

*

Le commit a changé !!

Branch : intégration

master
featureA

On est dans 

featureA

Le commit de featureA devrait appartenir au master

Rebase change le parent d'une branche.

Une autre façon pour intégrer le code

M1 {   
}
M2 {   
}
M1 {
   // featureA
}
M2 {  
}
M1 {
}
M2 {
   // bug fixed
}

Intégration des branches : exemple rebase

git rebase master
M1 {   
}
M2 {   
}
M1 {
}
M2 {
   // bug fixed
}
git rebase master
M1 {
   // featureA
}
M2 {
   // bug fixed
}
M1 {
   // featureA
}
M2 {  
}

Intégration des branches : exemple rebase

Maintenant on peut faire un merge fast-forward  !

M1 {   
}
M2 {   
}
M1 {
}
M2 {
   // bug fixed
}
M1 {
   // featureA
}
M2 {
   // bug fixed
}

Intégration des branches : exemple rebase

Attention !!

On ne rebase jamais le master ou autre branche partagée !

Que les branches privées peuvent être rebasées, parce qu'on modifie le commit !

Outils pour Git

git bash

git gui

gitk

La ligne de commande Git.

Interface graphique pour les commits, branches, merges...

Interface graphique pour le repository.

On peut tout faire avec git bash !

If you are brave enough...

Staging : voir les différences, choisir les fichiers à commiter...

git gui &

git amend

gitk --all &

Autres outils pour Git

SourceTree

Approuvé par nos collègues ;-)

Encore sur les commandes git

git checkout

  • git checkout mybranch
    • changement de branche      

 

  • git checkout mycommit  --  myfile
    • annuler les changements

git rebase --interactive

  • git rebase --interactive master~6
    • Magie !
r d026b47 demo related code to remove latter
pick bd51f15 fix a bug in ScoreStore: return the correct maximum value
pick 1a21aa7 fix a bug in ScoreAggregator: change the maximum score definition
pick cb1359b clean up
f cb1359b clean up
pick 0ee6fb4 fix the stores: remove the limitation to 10 results

# 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
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit

git stash

  • git stash
    • Ça marche chez moi©
    • Pulling into a dirty tree
    • Mauvaise branche
  • git stash pop
  • git stash --keep-index
    • Test avant commit

À base de popopop

git reset

  • git reset --hard
    • Mauvaise idée en cours
  • git reset --soft HEAD^1
    • Mauvaise idée dans le dernier commit
  • git reset --mixed
    • Vider l’index
  • Article : Reset Demystified

git cherry-pick

  • git cherry-pick
    • Déplacement de commit

Le temps des cerises

git revert

  • git revert
    • git push malheureux

git help

Super-man

  • Man pages
  • Livre Pro Git

Outils

.gitignore

couvrez ce fichier, que je ne saurais voir

# Maven
target

 

# Eclipse
.classpath
.project
.settings
.pydevproject

 

# LogBack
logback-debug.xml

# IntelliJ
.idea
*.iml

 

# log files
*.log

alias

  • Git
    • git config --global alias.c checkout
  • .profile :
    • alias gc="git checkout"
    • alias gs="git stash"
    • alias gsp="git stash pop"
    • alias grim="git rebase --interactive master"

hooks

  • Python, Ruby, Perl, shell script…
  • Côté client (pre-commit, pre-push…)
  • Côté serveur (pre-receive, update, post-receive)

git svn

autocomplétion

  • tab tab tab tab tab tab

Workflows

Workflows centralisés

Feature Branch Workflow 

Feature Branch Workflow 

  • git  push  --set-upstream origin  my-feature
  • Historique groupé par feature
    • Reverts facilités
  • Collaboratif :
    • Partage de features avant merge
    • Pull request

Gitflow Workflow 

Environment Branch Workflow 

Workflows décentralisés

  • git remote add upstream https://viseo.com/maintainer/repo
  • Open source
  • Collaboration++
  • Facilite contribution anonyme
  • Github

Workflows décentralisés

Integration Manager WF

Dictator and Lieutenants WF

Bonnes pratiques

Commit poussé

  • Unitaire (petit et complet)
  • Testé
  • Commenté
  • Early and often

Commit local

  • Souvent

Bonnes pratiques

Message de commit :

  • description courte sur la première ligne (max 50 char)
  • expliquer la conséquence (« add the login page »)
  • deuxième ligne vide
  • 72 char max par ligne
  • * ou – pour items

Bonnes pratiques

Branche

  • Les utiliser !
  • Bien les nommer
  • Définir un workflow
  • Une branche poussée doit compiler
  • Ne pas changer l’historique d’une branche distante

Bonnes pratiques

Références

That's all folks!

GitTuto

By Dana Popovici

GitTuto

Petit tuto Git

  • 320