# git

### Créer un repo git

Sur le serveur (DS916), aller dans le dossier Repo:

```bash
dsm916> cd /volume1/Repositories/

dsm916> git init –-bare wp2012.git
```

```bash
bruno@DS916:/volume1/Repositories $ mkdir wp_yuzu-child.git
bruno@DS916:/volume1/Repositories $ cd wp_yuzu-child.git/

bruno@DS916:/volume1/Repositories/wp_yuzu-child.git $ git --bare init
Initialized empty Git repository in /volume1/Repositories/wp_yuzu-child.git/
```

Sur le client (Mac), se mettre dans le dossier source:

```bash
bruno@macbook-pro:~/ git init

bruno@macbook-pro:~/ git remote -v

#bruno@macbook-pro:~/ git remote add origin ssh:dsm916e/volume1/Repositories/wp2012.git
bruno@macbook-pro:~/ git remote add origin bruno@dsm916e:/volume1/Repositories/wp2012.git

bruno@macbook-pro:~/ git add *

bruno@macbook-pro:~/ git commit -m "Created my repo"

bruno@macbook-pro:~/ git push –-all origin
```



ssh:dsm916/volume1/Repositories/shell_scripts.git



### Démarrage:

Les fichiers peuvent avoir 3 états:

1. <u>Validé</u> signifie que les données sont stockées en sécurité dans votre base de données locale. 
2. <u>Modifié</u> signifie que vous avez modifié le fichier mais qu'il n'a pas encore été validé en base. 
3. <u>Indexé</u> signifie que vous avez marqué un fichier modifié dans sa version actuelle pour qu'il fasse partie du prochain instantané du projet.

Ce qui induit les 3 sections d'un projey git:

1. Le <u>répertoire Git</u> est l'endroit où Git stocke les méta-données et la base de données des objets de votre projet. C'est la partie la plus importante de Git, et c'est ce qui est copié lorsque vous clonez un dépôt depuis un autre ordinateur.
2. Le <u>répertoire de travail</u> (working copy) est une extraction unique d'une version du projet. Ces fichiers sont extraits depuis la base de données compressée dans le répertoire Git et placés sur le disque pour pouvoir être utilisés ou modifiés.
3. La <u>zone d'index</u> est un simple fichier, généralement situé dans le répertoire Git, qui stocke les informations concernant ce qui fera partie du prochain instantané.



#### Fichier de config:

Pour l'utilisateur: `~/.gitconfig`

#### Configurer git:

```bash
$ git config --global user.name "Bruno 21"

# --global		Pour l'utilisateur (~/.gitconfig)
# paramètres: user.email, core.editor, merge.tool

$ git config --list
credential.helper=osxkeychain
user.name=Bruno 21
user.email=bruno@clicclac.info
filter.lfs.clean=git-lfs clean -- %f
filter.lfs.smudge=git-lfs smudge -- %f
filter.lfs.process=git-lfs filter-process
filter.lfs.required=true
```

#### Aide git:

```bash
$ git help <verbe>
$ git <verbe> --help
$ man git-<verbe>

$ git help config
```



### Démarrer un dépôt Git:

#### [Initialisation d'un dépôt Git dans un répertoire existant](https://git-scm.com/book/fr/v1/Les-bases-de-Git-D%C3%A9marrer-un-d%C3%A9p%C3%B4t-Git#Initialisation-d'un-d%C3%A9p%C3%B4t-Git-dans-un-r%C3%A9pertoire-existant)

Se placer dans le répertoire:

```bash
$ git init
```

Ajouter les fichiers à suivre:

```bash
$ git add *.php
```

Valider:

```bash
$ git commit –m 'version initiale du projet'
```



#### [Cloner un dépôt existant:](https://git-scm.com/book/fr/v1/Les-bases-de-Git-D%C3%A9marrer-un-d%C3%A9p%C3%B4t-Git#Cloner-un-d%C3%A9p%C3%B4t-existant)

```bash
$ git clone git://github.com/depot/projet.git
```

Crée un répertoire <u>grit</u> contenant les données du dépôt ainsi qu'un répertoire .git

```bash
$ git clone git://github.com/depot/projet.git mondossier
```

Crée un clone du depot dans le dossier mondossier



Cloner un repo dans SmartGit / GitKraken:

```bash
$ ssh://bruno@clicclac.synology.me:42666/volume1/Repositories/shell_scripts.git
```

Pas de bruno@dsm916e/



Si erreur de certificat:

```bash
bruno@Mint-book:~/Documents$ git clone https://192.168.1.7/volume1/Repositories/
Clonage dans 'Repositories'...
fatal: unable to access 'https://192.168.1.7/volume1/Repositories/': SSL: certificate subject name (clicclac.synology.me) does not match target host name '192.168.1.7'

GIT_SSL_NO_VERIFY=true git clone ssh://bruno@192.168.1.7:42666/volume1/Repositories/shell_scripts.git
```



#### Tirer un seul fichier d'un repo git:

```bash
$ mkdir rpi_py
$ git init
Dépôt Git vide initialisé dans /home/pi/git/rpi_py/.git/
$ git remote add origin bruno@dsm916e:/volume1/Repositories/rpi_py.git
$ git fetch
bruno@clicclac.synology.me's password:
remote: Enumerating objects: 38, done.
remote: Counting objects: 100% (38/38), done.
remote: Compressing objects: 100% (38/38), done.
remote: Total 38 (delta 5), reused 0 (delta 0)
Dépaquetage des objets: 100% (38/38), fait.
Depuis dsm916e:/volume1/Repositories/rpi_py
 * [nouvelle branche] master     -> origin/master
$ git checkout origin/master -- Camera/camera_2.py

pi@litePi:~/git/rpi_py $ cd Camera/
total 12
drwxr-xr-x 2 pi pi 4096 févr.  4 16:45 .
drwxr-xr-x 4 pi pi 4096 févr.  4 16:45 ..
-rw-r--r-- 1 pi pi  238 févr.  4 16:45 camera_2.py
```

Autre solution (juste le fichier, pas l'historique):

```bash
$ git archive --format=tar --remote=ssh://bruno@dsm916e/volume1/Repositories/rpi_py.git heads/master -- Camera/camera_2.py | tar xf -

# affiche le fichier sur la sortie stdout (tar -xO)
$ git archive --format=tar --remote=ssh://bruno@dsm916e/volume1/Repositories/rpi_py.git heads/master -- Camera/camera_2.py | tar -xO
bruno@clicclac.synology.me's password:
import time
import picamera

with picamera.PiCamera() as camera:
    camera.resolution = (1024, 768)
    camera.start_preview()
    # Camera warm-up time
    time.sleep(2)
    camera.capture('/home/pi/Desktop/foo.jpg', resize=(320, 240))
```



```bash

# -n		: No checkout of HEAD is performed after the clone is complete.
# --depth 1 : juste la dernière révision
$ git clone -n ssh://bruno@dsm916e/volume1/Repositories/rpi_py.git --depth 1
Clonage dans 'rpi_py'...
...
$ cd rpi_py/
$ git checkout HEAD Camera/camera_2.py
```

Voir aussi https://gist.github.com/ssp/1663093





### Enregistrer des modifications dans le dépôt:

#### [Vérifier l'état des fichiers](https://git-scm.com/book/fr/v1/Les-bases-de-Git-Enregistrer-des-modifications-dans-le-d%C3%A9p%C3%B4t#V%C3%A9rifier-l'%C3%A9tat-des-fichiers)

```bash
$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean
```

1 commit en attente de push.



#### [Placer de nouveaux fichiers sous suivi de version](https://git-scm.com/book/fr/v1/Les-bases-de-Git-Enregistrer-des-modifications-dans-le-d%C3%A9p%C3%B4t#Placer-de-nouveaux-fichiers-sous-suivi-de-version)

```bash
$ git add LISEZMOI
```



#### [Ignorer des fichiers](https://git-scm.com/book/fr/v1/Les-bases-de-Git-Enregistrer-des-modifications-dans-le-d%C3%A9p%C3%B4t#Ignorer-des-fichiers)

Les fichiers ajoutés à <u>.gitignore</u> ne seront pas sous suivi de version.

```bash
$ cat .gitignore
.DS_STore
```



#### [Inspecter les modifications indexées et non indexées](https://git-scm.com/book/fr/v1/Les-bases-de-Git-Enregistrer-des-modifications-dans-le-d%C3%A9p%C3%B4t#Inspecter-les-modifications-index%C3%A9es-et-non-index%C3%A9es)

Pour visualiser ce qui a été modifié mais pas encore indexé, tapez:

```bash
$ git diff
```



#### [Valider vos modifications](https://git-scm.com/book/fr/v1/Les-bases-de-Git-Enregistrer-des-modifications-dans-le-d%C3%A9p%C3%B4t#Valider-vos-modifications)

```bash
$ git commit
```

Ouvre l'éditeur de texte pour renseigner le message de validation.

```bash
$ git commit -m "Correction d'un bug"
```

Le message est dans la commande.

```bash
$ git commit -a -m  "Correction d'un bug"
```

Ordonne à Git de placer automatiquement tout fichier déjà en suivi de version dans la zone d'index avant de réaliser la validation, évitant ainsi d'avoir à taper les commandes `git add` 



#### [Effacer des fichiers](https://git-scm.com/book/fr/v1/Les-bases-de-Git-Enregistrer-des-modifications-dans-le-d%C3%A9p%C3%B4t#Effacer-des-fichiers)

```bash
$ git rm LISEZMOI
```



#### [Déplacer des fichiers](https://git-scm.com/book/fr/v1/Les-bases-de-Git-Enregistrer-des-modifications-dans-le-d%C3%A9p%C3%B4t#D%C3%A9placer-des-fichiers)

```bash
$ git mv nom_origine nom_cible
```



### Visualiser l'historique des validations:

```bash
$ git log

# -p		montre les différences entre chaque validation
# -2		les deux entrées les plus récentes

$ git log --pretty=format:"%h - %an, %ar : %s"

```



### Annuler des actions:

#### [Modifier le dernier *commit*](https://git-scm.com/book/fr/v1/Les-bases-de-Git-Annuler-des-actions#Modifier-le-dernier-commit)

```bash
$ git commit -m 'validation initiale'
$ git add fichier_oublie
$ git commit --amend
```



#### [Désindexer un fichier déjà indexé](https://git-scm.com/book/fr/v1/Les-bases-de-Git-Annuler-des-actions#D%C3%A9sindexer-un-fichier-d%C3%A9j%C3%A0-index%C3%A9)

```bash
$ git reset HEAD benchmarks.rb
$ git status
```



#### [Réinitialiser un fichier modifié](https://git-scm.com/book/fr/v1/Les-bases-de-Git-Annuler-des-actions#R%C3%A9initialiser-un-fichier-modifi%C3%A9)

Ramener le fichier à son état du dernier instantané (ou lors du clonage, ou dans l'état dans lequel vous l'avez obtenu dans votre copie de travail) 

```bash
$ git checkout -- benchmarks.rb
$ git status
```



#### Undo

https://stackoverflow.com/questions/927358/how-do-i-undo-the-most-recent-local-commits-in-git





### Dépot distants:

#### [Afficher les dépôts distants](https://git-scm.com/book/fr/v1/Les-bases-de-Git-Travailler-avec-des-d%C3%A9p%C3%B4ts-distants#Afficher-les-d%C3%A9p%C3%B4ts-distants)

```bash
$ git remote -v
KYMSU	https://Bruno21@github.com/Bruno21/kymsu.git (fetch)
KYMSU	https://Bruno21@github.com/Bruno21/kymsu.git (push)
kymsu_dsm	bruno@dsm916e:/volume1/Repositories/kymsu_dsm.git (fetch)
kymsu_dsm	bruno@dsm916e:/volume1/Repositories/kymsu_dsm.git (push)
```

#### [Récupérer et tirer depuis des dépôts distants](https://git-scm.com/book/fr/v1/Les-bases-de-Git-Travailler-avec-des-d%C3%A9p%C3%B4ts-distants#R%C3%A9cup%C3%A9rer-et-tirer-depuis-des-d%C3%A9p%C3%B4ts-distants)

```bash
$ git fetch [nom-distant]
```

#### [Pousser son travail sur un dépôt distant](https://git-scm.com/book/fr/v1/Les-bases-de-Git-Travailler-avec-des-d%C3%A9p%C3%B4ts-distants#Pousser-son-travail-sur-un-d%C3%A9p%C3%B4t-distant)

```bash
$ git push origin master
```

#### [Inspecter un dépôt distant](https://git-scm.com/book/fr/v1/Les-bases-de-Git-Travailler-avec-des-d%C3%A9p%C3%B4ts-distants#Inspecter-un-d%C3%A9p%C3%B4t-distant)

```bash
$ git remote show origin

$ git remote show KYMSU
* distante KYMSU
  URL de rapatriement : https://Bruno21@github.com/Bruno21/kymsu.git
  URL push : https://Bruno21@github.com/Bruno21/kymsu.git
  Branche HEAD : master
  Branche distante :
    master suivi
  Branche locale configurée pour 'git pull' :
    master fusionne avec la distante master
  Référence locale configurée pour 'git push' :
    master pousse vers master (à jour)
```

##### Ajouter un dépot distant:

```bash
GIT_SSL_NO_VERIFY=true git remote add origin ssh://bruno@192.168.1.7:42666/volume1/Repositories/shell_scripts.git
```



### Etiquettes:

[https://git-scm.com/book/fr/v2/Les-bases-de-Git-Étiquetage](https://git-scm.com/book/fr/v2/Les-bases-de-Git-Étiquetage)

#### Lister les étiquettes

```bash
$ git tag

$ git tag  -l 'v1.4.2*'
v1.4.2
v1.4.2-rc0
v1.4.2-rc1
v1.4.2-rc2
```



Il existe 2 types d'étiquettes: légère ou annotée.

#### Créer des étiquettes annotées

```bash
$ git tag -a v1.4 -m 'my version 1.4'

# -a étiquette
# -m message d'étiquetage
```

#### Créer des étiquettes légères

```bash
# ne pas utiliser les options -a, -m et -s

$ git tag v1.4
```

#### Voir les données de l'étiquette

```bash
$ git show v1.0
tag v1.0
Tagger: Bruno 21 <bruno@clicclac.info>
Date:   Sun Dec 8 08:47:05 2019 +0100

version 1.0

commit 1f8e7c7c4d2b7337eb28816d92fa31ed26c6d656 (HEAD -> master, tag: v1.0, KYMSU/master)
Author: Bruno 21 <bruno@clicclac.info>
Date:   Sun Dec 8 08:04:54 2019 +0100
```

#### Tagger une ancienne version

On récupère le commit de la version: eaeda19

```bash
$ git log --pretty=oneline
1f8e7c7c4d2b7337eb28816d92fa31ed26c6d656 (HEAD -> master, tag: v1.0, KYMSU/master) Update README.md
8497b0d0d560ad782643b0b8a4ef096d03692f1f (kymsu_dsm/master) pecl.sh
d076210d4f1883504dbed7a707201944dc52af75 homebrew.sh
ce5fa6e908fb8b3545a83f894e42920e3b913cc9 homebrew.sh
5dab2b9d33632f343f914b0e9f670fc5fff0122b homebrew.sh
e8a6b02a95d7e9a3f5166b1524f420acf15fb4d4 Homebrew - Pinned package support
f354d0b6990be2ec8841b133901b3ff3557089fb homebrew.sh
4399d440ec8747745b8ec817b57024234e75cd8f homebrew.sh
f678d88c78737dcfa734979b5c93465b28d2bc8e Bugfix
d0898cb1e44b898cbceb67c1912c32ab013f3026 Bugfix - amélioration
eaeda193d6c76cca30e7346a6355ad77311d860f LaunchAgent
```

On tag le commit

```bash
 git tag -a v0.9 -m 'pré-version' eaeda19
```

```bash
$ git tag
v0.9
v1.0
```

#### Partager les étiquettes

Par défaut, la commande `git push` ne transfère pas les étiquettes vers les serveurs distants. Il faut explicitement pousser les étiquettes après les avoir créées localement.

`git remote -v` pour obtenir le nom court du dépot distant.

```bash
# Pousser 1 tag précis

$ git push KYMSU v0.9
Énumération des objets: 1, fait.
Décompte des objets: 100% (1/1), fait.
Écriture des objets: 100% (1/1), 163 octets | 81.00 Kio/s, fait.
Total 1 (delta 0), réutilisés 0 (delta 0)
To https://github.com/Bruno21/kymsu.git
 * [new tag]         v0.9 -> v0.9

# Pousser tous les tags

$ git push KYMSU --tags
Énumération des objets: 1, fait.
Décompte des objets: 100% (1/1), fait.
Écriture des objets: 100% (1/1), 158 octets | 158.00 Kio/s, fait.
Total 1 (delta 0), réutilisés 0 (delta 0)
To https://github.com/Bruno21/kymsu.git
 * [new tag]         v1.0 -> v1.0
```

Dans **Tower**: push -> options -> Push All Tags



### Branches:

https://git-scm.com/book/fr/v2/Les-branches-avec-Git-Les-branches-en-bref

#### Gérer les branches

```bash
$ git branch              # Permet de lister les branches
$ git branch -v           # Visualiser les dernières validations sur chaque branche
$ git branch <branche>    # Permet de créer une nouvelle branche <branche>
$ git branch -m <branche> # Renomme la branche courante en <branche>
$ git branch -d <branche> # Permet de supprimer une branche
$ git branch -D <branche> # Supprime la branche même si elle n'a pas été fusionnée
$ git branch --merged     # Quelles branches ont déjà été fusionnées dans votre branche actuelle ?
$ git branch --no-merged  # Branches qui contiennent des travaux qui n'ont pas encore été fusionnés
```

**master** est la branche par défaut.

**HEAD** est un pointeur qui indique la branche courante.

`$ git branch <branche>` crée une nouvelle branche mais ne fait pas basculer la <u>copie de travail</u> vers celle-ci.



#### Passer d'une branche à l'autre

```bash
$ git checkout <branche>
$ git checkout -b <branche> # sauter sur une branche qui n'existe pas en la créant au préalable
```

Le pointeur **HEAD** pointe désormais sur <branche>

La <u>copie de travail</u> a basculée sur la nouvelle branche:

- la nouvelle branche pointera sur les nouveaux commit 
- la branche **master** pointera sur le dernier commit au moment du checkout.



#### Fusionner les branches

Merge permet de ramener une branche sur une autre et ainsi de la fusionner. La fusion de 2 branche se fait toujours à partir de la branche principale.

- La branche "source" sera affectée en récupérant l'historique de la branche ou un commit de fusion
- La branche fusionnée ne sera pas affectée

```bash
$ git merge <branche>
```

https://git-scm.com/book/fr/v1/Les-branches-avec-Git-Brancher-et-fusionner%C2%A0%3A-les-bases



#### Les branches distantes



#### Rebaser

Avec la commande rebase, vous prenez toutes les modifications qui ont été validées sur une branche et vous les rejouez sur une autre.



#### => [Session de travail avec git](git-session.md) <=



http://www.ntu.edu.sg/home/ehchua/programming/howto/Git_HowTo.html