1. Environment

Vous pouvez installer depuis le site officiel. Nous utilisons ici la version 2.9.2 en ligne de commande. Mais vous pouvez bien sûr utiliser un client graphique (comme https://www.sourcetreeapp.com/).

sourcetree
Figure 1. Client graphique (https://www.sourcetreeapp.com)
git term
Figure 2. Lignes de commande

Je vous recommande tout de même de connaître les commandes en ligne, c’est souvent utile! Pour vous familiariser avec les commandes en ligne, ne pas hésiter à utiliser le site http://try.github.com.

2. General principles

git branching
Figure 3. Usage classique de git (http://nvie.com/posts/a-successful-git-branching-model/)

Ce modèle est controversé et ne fait pas l’unanimité. Nous verrons dans la suite qu’il y a plus simple.

3. Before starting

Initialize some useful variables:

$ git config --global user.name "JM Bruel"
$ git config --global user.email jbruel@gmail.com
$ git config --global alias.co checkout

Those information are stored in the file: ~/.gitcongif.

Here is an extract of mine:

[user]
        name = Jean-Michel Bruel
        email = jbruel@gmail.com
[alias]
        co = checkout
        st = status
$ 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)

4. Classic scenario (and ideal)

4.1. Step 1: local repository

Let’s start versioning:

$ git init

This generates the .git folder (in the current one).

$ 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/

4.2. Step 2: adding files

Adding the current forlder (and its content) to the repository:

$ git add .

You can select what is added (git add *.c for example).

Create a .gitignore file to avoid adding useless files (such as log ones).

4.3. Step 2 (ctd.): checking

You can verify the current state:

$ 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
...

4.4. Step 3: Commit

To register the changes:

$ 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

The commit is only local!

4.5. Step 3 (ctd.) : Gestion "locale"

Example of scenario:

$ 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

4.6. Step 4: Find a distant repository

GitHub, GitLab etc.

github

4.7. Step 4 (ctd.): define the distant repository

$ 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 Possible to have several distant repository (this one is named origin).
2 The option -u origin master is for the next git push

4.8. Step 5: branch, edit, commit, merge

$ git checkout
Your branch is ahead of 'origin/master' by 1 commit.

4.9. Step 5 (ctd.): branching

is very good to create branches:

$ git checkout -b testModifTiti
Switched to a new branch 'testModifTiti'
$ git branch
  master
* testModifTiti (1)
1 current branch with *.

4.10. Step 5 (ctd.): edit

$ 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")

4.11. Step 5 (ctd.): commit

$ git commit -am "modif de titi"
[testModifTiti 4515b5d] modif de titi
 1 files changed, 7 insertions(+), 0 deletions(-)
  • Only local!

4.12. Step 5 (ctd.): use of branches

$ 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

4.13. Step 5 (ctd.): merge

$ git co master
Switched to branch 'master'

$ git merge testModifTiti
Merge made by recursive.
 titi.txt |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

4.14. Step 6: push

$ 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

4.15. Step 7: pull request (acceptation)

$ git checkout -b develop origin/develop
$ ...                       (1)
$ git checkout master
$ git merge --no-ff develop (2)
$ git push origin master    (3)
1 We check what is going to be integrated
2 Local merge (to check pproblems))
3 Push on master

5. Existing repository

$ git clone git@github.com:jmbruel/first_app.git

6. Illustration of branches

(taken from git-scm).

gf1
Figure 4. Situation initiale
$ git checkout -b iss53
gf2
Figure 5. Création d’une branche

only creates a pointer ⇒ no memory copy.

$ edit ...
$ git commit -m " blabla iss53"
gf3
Figure 6. On commence à diverger de master
$ git checkout master
$ git checkout -b hotfix
$ edit ...
$ git commit -m " blabla hotfix"
gf4
Figure 7. Maintenant on a 2 branches parallèles (en plus de master)
$ git checkout master
$ git merge hotfix
gf5
Figure 8. Merge de deux branches (en fast-forward)

use of fast-forward here

Working on iss53 :

$ git branch -d hotfix (1)
$ git checkout iss53
$ edit ...
$ git commit -m " blabla iss53"
1 Destruction de la branche devenue redondante avec master.
gf6
Figure 9. On retravaille sur iss53
$ git checkout master
$ git merge iss53
gf7
Figure 10. Explications du fonctionnement du merge sans fast-forward
  • Explications : recherche la racine commune (ici c3 pour intégrer les branches (les commits feuilles) une par une et vérifier les conflits par itérations à partir de cette racine.

gf8
Figure 11. Situation finale

7. Good habits

7.1. Defined procedure

git branching

7.2. Do not version everything!

  • no exe files

  • no changing zip files

  • no generated images

  • no binary in general!

7.3. Tricks

7.4. Oups! I forgot something

$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend

7.5. Oups! I’ve put too much

$ git add *.*
$ git reset *.class
Safe

7.6. CTRL+Z

$ working on some file README.adoc ...
$ git checkout -- REAME.adoc
Unsafe!

7.7. Where am I?

$ git status
gitbash1
gitbash2
gitbash3
gitbash4

8. Branching

(taken from the excellent book Pro Git)

Only 2 branches: master & 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

fork develop to treat a bug or a feature.

  • merge in develop

  • destroy the useless branch

  • Create a branch (e.g., fix-451)

  • Work on it

  • Merger in develop

  • Re-run tests

  • Fix conflicts if any

  • When everything works ⇒ pull-request

  • master is ready

9. Different merge

9.1. Explicit merge

what is a merge

9.2. Implicit merge via rebase or fast-forward

what is a rebase

9.3. Implicit merge via fast-forward

what is a fast forward

9.4. Squash on merge

squash on merge

10. Conflicts management

10.1. By hand

$ 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

10.2. With some help

11. Git advanced: Git-Flow

12. Wrap-up

(taken from http://osteele.com) :

git resume
Figure 13. Résumé des commandes git (http://osteele.com)