Tutoriel

Dana & Rafael

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

- plusieurs backups

 

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" (GitLab, GitHub, ...)

.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 devrait être 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 origin/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

GitKraken

...

Extensions pour les environments de développement :

VS code

Sublime text

IntelliJ

 

Encore sur les commandes git

git checkout

  • git checkout mybranch
    • changement de branche  
  • git checkout myFile --ours (ou --theirs)
    • résolution de conflits

 

git rebase [--interactive]

  • git rebase --interactive HEAD~6
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 rebase origin/develop

git stash

  • git stash
    • Ça marche chez moi©
    • Pulling into a dirty tree
    • Mauvaise branche
  • git stash pop (ou apply)
  • git stash --keep-index

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

git cherry-pick

  • git cherry-pick <shacommit>
    • Déplacement de commit

Le temps des cerises

git revert

  • git revert <shacommit>
    • git push malheureux

git status

git log

git reflog

git help

Super-man

  • Man pages

In real life

Les conflits

Merge

  • résoudre le conflit dans un éditeur
  • stage & commit le fichier

Rebase

  • résoudre le conflit dans un éditeur
  • stage & commit le fichier
  • git rebase --continue
    • ou --skip

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)

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

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

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
  • en anglais
  • utiliser l'impératif

Bonnes pratiques

Branche

  • Les utiliser !
  • Définir un workflow avec l'équipe :
    • feature/US123-nom, bugfix/US356-autre-nom
    • strategies de merge
  • Une branche poussée doit compiler
  • Ne pas changer l’historique d’une branche partagée

Bonnes pratiques

Références

Exercices

Exercice 0

Vous allez utiliser git bash (& HTML)

Exercice 1

Contexte

  • Vous allez travailler en paralel
  • Objective final: Avoir une page avec le texte "Bien joué!"

Tes taches

  • Regarder le travail de ton collègue
  • Ajouter le mot "Bien"
  • Faire un merge request sur gitlab (sans merger!) 

Branchs

  • début : start-here
  • partagé : feature/exercice1
  • collègue : 237a7a23
  • ta branche: feature/exercice1-bien-ton-prenom

Exercice 1

Finaliser

  • Merger la feature/exercice1 dans develop

Exercice 2

Objectives

  • Transformer les 6 commits en 2
    • garder tel qu'il est le dernier commit, squash les 5 autres
  • Rebase sur la branch develop.
  • Merge request sur gitlab sur la branch partagé (sans merger!)

Branches

  • partagé : develop
  • début : feature/exercice2
  • ta branche: feature/exercice2-ton-prenom

Exercice 3

Objectives

  • Prendre un bout de code qui est dans une autre branch
    • ajouter le deuxième commit de la branche feature/exercice3 sur la votre
  • Merge request sur gitlab sur la branch partagé (sans merger!)

Branches

  • partagé : develop
  • début : develop
  • ta branche: feature/exercise3-ton-prenom

Exercice 4

Objectives

  • Faire un commit de revert

Branches

  • partagé : feature/exercice4
  • début : feature/exercice4
  • ta branche: feature/exercice4-ton-prenom
    • revert le commit "REVERT THIS USELESS COMMIT"
    • merge request vers la branche partagée

Exercice 5

Objectives

  • Faire un reset!
    • a partir de develop, ajoutez un <div> et faites un commit
    • faites un reset --soft pour défaire le dernier commit
    • stash les changements
    • créer une branche feature/exercice5-ton-prenom
    • faire le commit sur cette branche au lieu de develop

Branches

  • partagé : develop
  • début : develop

Exercice 6

Objectives

  • Faire un merge en local
    • pendant que vous avez fait les exercices 1-3, nous avons "travaillé" sur d'autres features / bugfixes dans la branche feature/exercice6
    • il faut arriver à un fichier hello.html qui a les div avec les id en ordre croissant! 

Branches

  • partagé : develop
  • début : develop
  • branche à merger: feature/exercice6

GitTuto2020

By Dana Popovici

GitTuto2020

Petit tuto Git

  • 211