Git est un outil avant tout fait par des développeurs (Linus Torvald, 2005) pour des développeurs.
Git permet :
Git est un logiciel de gestion de version de fichiers décentralisé.
L’historique d’un répertoire se représente sous la forme d’un graphe.
Chaque nœud est appelé commit et contient :
git init
[Répertoire]
.git
dans Répertoire
ou le
répertoire courant s’il n’est pas spécifié.
$ cd /quelque/part/
$ git init MonRepertoireDeBase
Initialized empty Git repository in /quelque/part/MonRepertoireDeBase/.git/
$ ls -a MonRepertoireDeBase
.git
git config
[--global] user.name <myname>
myname
comme nom d’auteur des commits
git config
[--global] user.email <myemail>
myemail
comme email de l’auteur des
commits
git config
[--global|--local] -l
$ git config user.name "Adrien Krähenbühl"
$ git config -l
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
user.name=Adrien Krähenbühl
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[user]
name = Adrien Krähenbühl
Le répertoire de travail (working directory) est le répertoire sur le disque dur. Les fichiers y sont créés/modifiés/supprimés.
La zone de transit (staging area) ou index, est un espace temporaire qui stocke les modifications qui seront commitées.
Le dépôt (répertoire .git
)
stocke tous les commits.
Les commandes git qui suivent vont permettre de manipuler les fichiers pour les faire passer d’une zone à une autre.
git status
affiche les infos sur l’état courant des fichiers.
$ git status
On branch main
Changes to be committed:
new file: NouvelleClasse.java
modified: README.md
Changes not staged for commit:
modified: Diagramme.puml
Untracked files:
Test.java
Changes to be committed
liste les
fichiers dans la zone de transit.Changes not staged for commit
liste
les fichiers du répertoire de travail qui ont été modifiés depuis le
dernier commit.Untracked files
liste les fichiers qui
ne sont pas versionnés.git add
$ git status
On branch main
Changes not staged for commit:
modified: MaClasse.java
$ git add MaClasse.java
$ git status
On branch main
Changes to be committed:
modified: MaClasse.java
git commit
[-m "message"]
message
indiquant en quoi consistent les modifications.
$ git status
On branch main
Changes to be committed:
modified: MaClasse.java
$ git commit -m "Modification du fichier Maclasse.java"
$ git status
On branch main
nothing to commit, working tree clean
git log
[--oneline] [--graph] [--branches]
Liste les commits avec leurs métadonnées :
--oneline
: chaque commit condensé en une seule
ligne--graph
: visualisation du graphe--branches
: visualisation de toutes les branches$ git log
commit 638c310fa5a42839595e9d8499fdb98773feff5e (HEAD -> main)
Author: Adrien Krähenbühl <krahenbuhl@unistra.fr>
Date: Tua Jan 11 10:02:59 2022 +0100
Modification du fichier Maclasse.java
$ git log --oneline
638c310 (HEAD -> main) Modification du fichier Maclasse.java
git restore
<file>
<file>
qui ne sont pas
dans la zone de transit$ cat MaClasse.java
interface MaClasse {}
$ git status
On branch main
Changes not staged for commit:
modified: MaClasse.java
no changes added to commit
1. Depuis le dernier commit, MaClasse.java
a été
modifié.
$ git restore MaClasse.java
$ cat MaClasse.java
class MaClasse {}
$ git status
On branch main
nothing to commit, working tree clean
2. Après git restore
, les modifications sont
annulées.
git restore
--staged <file>
$ cat MaClasse.java
interface MaClasse {}
$ git status
On branch main
Changes to be committed:
modified: MaClasse.java
1. Depuis le dernier commit, MaClasse.java
a été
modifié et indexé.
$ git restore --staged MaClasse.java
$ cat MaClasse.java
interface MaClasse {}
$ git status
On branch main
Changes not staged for commit:
modified: MaClasse.java
no changes added to commit
2. Modifications désindexées.
git mv
<file> <destination>
déplace <file>
vers
<destination>
$ git mv MaClasse.java MaClasse2.java
$ git statusOn branch main
Changes to be committed:
renamed: MaClasse.java -> MaClasse2.java
git rm
<file>
supprime <file>
$ git rm MaClasse.java
$ git status
On branch main
Changes to be committed:
deleted: MaClasse.java
git checkout
<commit-id>
<commit-id>
(calculé par la fonction de hachage
SHA-1)
$ git log --oneline --graph
* 56dd655 (HEAD -> main) Suppression de MaClasse.java
* eaa13b4 Ajout de README.md
* 6d865ec Ajout de Diagramme.puml
* 638c310 Ajout du fichier Maclasse.java
$ ls
Diagramme.puml README.md
2 - “Retour” au commit 6d865ec
$ git checkout 6d865ec
HEAD is now at 6d865ec Ajout de Diagramme.puml
$ git log --oneline --graph
* 6d865ec (HEAD) Ajout de Diagramme.puml
* 638c310 Ajout du fichier Maclasse.java
$ ls
Diagramme.puml MaClasse.java
Git utilise un pointeur nommé HEAD
pour
indiquer où il se trouve dans le graphe des commits.
git commit
crée un nouveau commit et déplace le
pointeur HEAD
sur ce nouveau commitgit checkout
déplace uniquement le pointeur
HEAD
sur un commit donné.
1 - Départ
2 -
git commit -m "..."
3 -
git checkout 6d865ec
Une branche est un pointeur nommé sur un commit.
git branch
[-d] <name>
<name>
au niveau du commit
pointé par HEAD
.-d
(delete) supprime la branche.git switch
<name>
HEAD
vers la branche
<name>
.switch
est aux branches ce que checkout
est aux commits 1.
Départ.
2.
git branch myBranch
3.
git switch myBranch
4.
git checkout 6d865ec
5.
git branch otherBranch
6.
git switch otherBranch
7.
git switch myBranch
8.
git branch -d otherBranch
1. Départ.
2. Céation d’un nouveau
fichier
OtherClasse.java
.
3.
git add OtherClasse.java
.
4.
git commit -m "Ajout de la classe OtherClasse.java"
4.
git commit -m "Ajout de la classe OtherClasse.java"
5. Modification du fichier
OtherClasse.java
.
6.
git add OtherClasse.java
.
7.
git commit -m "Modification du fichier OtherClasse.java"
7.
git commit -m "Modification du fichier OtherClasse.java"
Les branches permettent de travailler en parallèle à partir d’une base de code commune.
On peut créer des branches pour :
release
, beta
, etc. de
son applicationUn dépôt a toujours une branche principale
main
(anciennement master
) qui contient par
convention du code fonctionnel.
Convention essentielle entre développeurs :
Ne jamais commiter directement sur la branche
principale.
git merge
<branche>
<branche>
avec le la
branche pointée par HEAD
.
1.
Reprenons…
2.
git switch myBranch
2.
git switch myBranch
3.
git merge otherBranch
???
3.
git merge otherBranch
4.
git branch -d otherBranch
4.
git branch -d otherBranch
git merge
crée un commit de
fusion.Créer un “commit de fusion” est le comportement par défaut de Git, mais il existe d’autres stratégies de fusion.
La fusion peut échouer s’il y a un ou plusieurs fichiers en conflit.
$ git merge otherBranch
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.
Message d’erreur indiquant un conflit sur le fichier
README.md
Un fichier sera en conflit :
depuis que les branches ont divergé.
1.
Départ.
Fichier README.md
Les partenaires de l'ITI :
- IRMA
- ICube
- ObAS
- INRIA
- Plateformes
2.
git branch otherBranch
README.md
sur…
Les partenaires de l'ITI :
- IRMA
- ICube
- ObAS
- INRIA
- Plateformes
… myBranch
Les partenaires de l'ITI :
- IRMA
- ICube
- ObAS
- INRIA
- Plateformes
… otherbranch
3.
git switch otherBranch
README.md
sur…
Les partenaires de l'ITI :
- IRMA
- ICube
- ObAS
- INRIA
- Plateformes
… myBranch
Les partenaires de l'ITI :
- IRMA
- ICube
- ObAS
- INRIA
- Plateformes
… otherbranch
4.
Modification de
README.md
README.md
sur…
Les partenaires de l'ITI :
- IRMA
- ICube
- ObAS
- INRIA
- Plateformes
… myBranch
ITI partners:
- IRMA
- ICube
- ObAS
- INRIA
- Plateformes
… otherbranch
5.
git add README.md
README.md
sur…
Les partenaires de l'ITI :
- IRMA
- ICube
- ObAS
- INRIA
- Plateformes
… myBranch
ITI partners:
- IRMA
- ICube
- ObAS
- INRIA
- Plateformes
… otherbranch
6.
git commit -m "Traduction du titre en anglais"
README.md
sur…
Les partenaires de l'ITI :
- IRMA
- ICube
- ObAS
- INRIA
- Plateformes
… myBranch
ITI partners:
- IRMA
- ICube
- ObAS
- INRIA
- Plateformes
… otherbranch
7.
git switch myBranch
README.md
sur…
Les partenaires de l'ITI :
- IRMA
- ICube
- ObAS
- INRIA
- Plateformes
… myBranch
ITI partners:
- IRMA
- ICube
- ObAS
- INRIA
- Plateformes
… otherbranch
8.
Modification de
README.md
README.md
sur…
The ITI's partners:
- IRMA
- ICube
- ObAS
- INRIA
- Plateformes
… myBranch
ITI partners:
- IRMA
- ICube
- ObAS
- INRIA
- Plateformes
… otherbranch
9.
git add README.md
README.md
sur…
The ITI's partners:
- IRMA
- ICube
- ObAS
- INRIA
- Plateformes
… myBranch
ITI partners:
- IRMA
- ICube
- ObAS
- INRIA
- Plateformes
… otherbranch
10.
git commit -m "Traduction anglais britannique"
README.md
sur…
The ITI's partners:
- IRMA
- ICube
- ObAS
- INRIA
- Plateformes
… myBranch
ITI partners:
- IRMA
- ICube
- ObAS
- INRIA
- Plateformes
… otherbranch
11.
git merge otherBranch
?
README.md
sur…
The ITI's partners:
- IRMA
- ICube
- ObAS
- INRIA
- Plateformes
… myBranch
ITI partners:
- IRMA
- ICube
- ObAS
- INRIA
- Plateformes
… otherbranch
Git propose dans le répertoire de travail une version temporaire du fichier en conflit contenant les deux versions :
<<<<<<< HEAD
The ITI's partners:
=======
ITI partners:
>>>>>>> otherBranch
...
à changer en
The ITI's partners:
...
ou
ITI partners:
...
C’est à vous de régler le conflit.
Pour terminer la fusion, vous devez :
git add
+
git commit
Vous pouvez annuler la fusion à tout moment avec git merge
--abort
.
Les fichiers .gitignore
permettent de
déclarer des fichiers à ignorer lors de la création des
commits.
.idea/
build/
*.log
MaClasse.java
Exemple de ficher .gitignore
Un fichier .gitignore
:
$ ls
README.md
$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
README.md
$ echo "*.md" >> .gitignore
$ ls
README.md .gitignore
$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
$ git add README.md
The following paths are ignored by one of your .gitignore files:
README.md
hint: Use -f if you really want to add them.
Après l’ajout du fichier .gitignore
, le fichier
README.md
:
git clone
<dépot> [<répertoire>]
<dépôt>
dans le
répertoire courant ou dans <répertoire>
s’il est
indiqué.<dépôt>
peut être l’URL d’un dépôt Git accessible
via le réseau.Un dépôt distant Base
versionné avec Git qui
correspondrait à ceci :
$ ls -a Base/
.git README.md
peut être cloné dans un autre répertoire Clone
:
$ git clone git@git.unistra.fr:Base.git Clone
Cloning into 'Clone'...
done.
qui sera une copie exacte de Base
:
$ ls -a Clone/
.git README.md
Un dépôt distant (ou remote) est un dépôt suivi par le dépôt local.
git remote
[-v]
git remote
add <nom> <dépôt>
<nom>
vers le dépôt distant
<dépôt>
.
$ git remote -v
origin git@git.unistra.fr:Base.git (fetch)
origin git@git.unistra.fr:Base.git (push)
Un dépôt distant peut se trouver sur le même ordinateur, le mot “distant” s’oppose simplement au mot “local” du dépôt courant.
1. Soit un dépôt distant
2. git clone git@git.unistra.fr:Base.git Clone
2. git clone git@git.unistra.fr:Base.git Clone
2. git clone git@git.unistra.fr:Base.git Clone
3. git commit -m "Travail en local"
3. git commit -m "Travail en local"
git push
<remote> <branch>
HEAD
vers la <branch>
du dépôt
<remote>
.
$ git push origin main
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 270 bytes | 270.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@git.unistra.fr:Base.git
9e13dfb..e92d6f0 main -> main
Pousser des modifications locales vers un dépôt distant implique :
$ git pull origin main
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), 254 bytes | 254.00 KiB/s, done.
From git@git.unistra.fr:Base.git
* branch main -> FETCH_HEAD
ae9a8b2..a399689 main -> origin/main
Updating ae9a8b2..a399689
Fast-forward
README.md | 1 +
1 file changed, 1 insertion(+)
git fetch
[[<remote>] <branch>]
<branche>
du dépôt
<remote>
vers le dépôt local. Attention, il
n’y a pas de fusion locale.
git merge
git pull
= git fetch
+
git merge
1. Reprenons…
2a. Le dépôt distant évolue.
2a. Le dépôt distant évolue.
3a. git fetch origin main
3a. git fetch origin main
4a. git merge origin main
4a. git merge origin main
2b. Le dépôt distant évolue.
3b. git pull origin main
3b. git pull origin main
puller
avant de de
pusher
pour éviter les conflits et les reésoudre
localement.
Comment ça fonctionne physiquement ?
Git sauvegarde l’ensemble des commits dans un répertoire
.git
à la racine de cette arborescence.Pour pouvoir manipuler une arborescence, Git se base sur 3 éléments :
.git