docs au propre

This commit is contained in:
eleonore12345 2024-07-25 12:46:26 +02:00
parent 3a04aa0089
commit 90744539dc
2 changed files with 116 additions and 89 deletions

View File

@ -2,7 +2,7 @@ How to minimize the memory and data flow consumption of Git cloning?
# Background
Jean-Cloud is a small association providing hosting services on second-hand hardware. It is currently launching the Shlagernetes project, a software that enables services to be distributed and managed across several second-hand servers. Git is used in certain cases to install a service on a server or update it.
[Jean-Cloud](https://www.jean-cloud.net) is a small association providing hosting services on second-hand hardware. It is currently launching the Shlagernetes project, a software that enables services to be distributed and managed across several second-hand servers. Git is used in certain cases to install a service on a server or update it.
# Objective
@ -26,10 +26,10 @@ The final chosen combination is :
`git clone --depth=1 --recurse-submodules --remote-submodules`
- depth=1 allows you to clone only the last commit along with the necessary objects. By default, it is single-branch.
- recurse-submodules ensures that the contents of submodules are cloned
- remote-submodules ensures submodule content is cloned from the original remote submodule
- shallow-submodules ensures that only the latest submodule commit is imported (for this to work locally, specify ://file/ before the submodule path)
- `depth=1` allows you to clone only the last commit along with the necessary objects. By default, it is single-branch.
- `recurse-submodules` ensures that the contents of submodules are cloned
- `remote-submodules` ensures submodule content is cloned from the original remote submodule
- `shallow-submodules` ensures that only the latest submodule commit is imported (for this to work locally, specify ://file/ before the submodule path)
## To update :
@ -44,20 +44,20 @@ git gc --aggressive --prune=now
```
- git fetch --tags --depth=1 --prune --prune-tags origin
tags is used to fetch tags, and must be specified even if a tag is fetched by reference
depth=1 allows only the last commit to be considered
prune deletes references that are no longer accessible from the local remote folder
prune-tags not only deletes references in the local remote repository that are no longer accessible, but also deletes local tags that do not exist on the remote.
`tags` is used to fetch tags, and must be specified even if a tag is fetched by reference
`depth=1` allows only the last commit to be considered
`prune` deletes references that are no longer accessible from the local remote folder
`prune-tags` not only deletes references in the local remote repository that are no longer accessible, but also deletes local tags that do not exist on the remote.
- `git reset --hard --recurse-submodules origin/main`
- `git submodule update --init --recursive --force --depth=1 --remote`
init updates the .gitmodules file
recursive applies the command to submodules of submodules etc.
force ignores local changes to submodules and automatically checks out the new version
depth=1 allows you to consider only the last submodule commit
remote updates from the original remote submodule
`init` updates the .gitmodules file
`recursive` applies the command to submodules of submodules etc.
`force` ignores local changes to submodules and automatically checks out the new version
`depth=1` allows you to consider only the last submodule commit
`remote` updates from the original remote submodule
CAREFUL: order does matter here. Using this instruction first would make it ineffective because of the `--recurse-submodules` of the `git reset`. This option is yet kept to deal with the case of deletion of a submodule.
- `git reflog expire --expire=now --all`
@ -90,10 +90,12 @@ Partial clones can also be created by `sparse-checking`. Some files and/or folde
A surface clone can be created using the `depth=<number>` option, which specifies the number of commits to be kept. This option is available for both the clone and fetch commands.
## Large file storage
LFS is a Git extension that lets you manipulate selected files (by name, expression or size) using a local cache. In practice, files are replaced by references in the Git repository and a local folder outside the repository is created to store the files. They are downloaded lazily, i.e. only when checked out. All older versions are stored on an online server.
This is a very interesting mechanism, which we will not use for the same reason as the `--filter` clone: we only want to keep one specific version of the files, which would in any case be downloaded by LFS.
This is a very interesting mechanism, which we will not use for the same reason as the `git clone --filter`: we only want to keep one specific version of the files, which would in any case be downloaded by LFS.
## Delete history
The `git filter-branch` command is not recommended by the Git documentation. It has several security and performance flaws. It can be used to rewrite branch history using filters.
The Java repo-cleaner library works, but the Git documentation considers the Python filter-repo library to be faster and more secure. We do not wish to install either Python or Java, hence we will not dig any deeper into these two possibilities here.
@ -101,12 +103,14 @@ The Java repo-cleaner library works, but the Git documentation considers the Pyt
We want to delete the entire history without filtering, so the git command `git fetch --depth=1` followed by a git checkout, reset or merge works for us.
## checkout ? merge ? reset ?
Once we have fetched the changes to our local remote/ folder, what is the best way to apply them to our index and working directory?
Let us compare 4 possibilities: `git merge -X`, `git merge -s`, `git reset --hard`, `git checkout -f -B`. The final results are identical, except for `git merge -X`.
In the case of git merge, we do not wish to resolve conflicts manually. Remote must always take precedence over local differences.
In the case of `git merge`, we do not wish to resolve conflicts manually. Remote must always take precedence over local differences.
### `git merge -X theirs`
This command applies an ort strategy which, in the event of a conflict, gives precedence to theirs.
However, since we are working in `--depth=1`, the two branches have no common ancestor, and the `--allow-unrelated-histories` option must be supplied. The absence of a common ancestor prevents Git from recognizing similarities within the same file. Any modification to a tracked file on ours, even on a new line, will thus cause a conflict and be overwritten. This command does, however, save newly created and committed files on ours.
Newly created uncommitted files are kept unless `git clean` is run.
@ -114,8 +118,9 @@ Advantage: committed files created on ours are saved.
Disadvantage: in the event of deletion of a file on theirs that already existed on ours: it will not be deleted on ours.
### `git merge -s ours`
[caution: the notions of theirs and ours are reversed here, as `git merge -s theirs` does not exist].
This command applies a ours strategy that gives prevalence to ours, whether there is a conflict or not. It will ignore all changes and file creations committed to theirs. It will also ignore uncommitted modifications. Uncommitted file creations are retained unless git clean is run. This is the same result as with the `git reset --hard` command.
This command applies a ours strategy that gives prevalence to ours, whether there is a conflict or not. It will ignore all changes and file creations committed to theirs. It will also ignore uncommitted modifications. Uncommitted file creations are retained unless `git clean` is run. This is the same result as with the `git reset --hard` command.
As the `git merge -s theirs` option does not exist, we need to do a little manipulation:
```
#we want to merge origin/main on main, giving prevalence to origin/main

View File

@ -2,114 +2,128 @@
# Contexte
Jean-Cloud est une petite association d'hébergement associatif sur du matériel de récupération. Elle lance en ce moment le projet Shlagernetes : un logiciel qui permet de répartir et gérer des services sur plusieurs serveurs de récupération. Git est utilisé dans certains cas pour installer un service sur un serveur ou le mettre à jour.
[Jean-Cloud](https://www.jean-cloud.net) est une petite association d'hébergement associatif sur du matériel de récupération. Elle lance en ce moment le projet Shlagernetes : un logiciel qui permet de répartir et gérer des services sur plusieurs serveurs de récupération. Git est utilisé dans certains cas pour installer un service sur un serveur ou le mettre à jour.
# Objectif
Lobjectif est d'obtenir la dernière version (ou une version précise) dun dépôt git, en utilisant le moins de ressources possible. Par ressources, nous entendons le flux de données qui part du remote pour arriver au dossier local, ainsi que la place mémoire occupée par le dépôt sur le serveur local.
Lobjectif est d'obtenir la dernière version (ou une version précise) dun dépôt git, en utilisant le moins de ressources possible. Par ressources, nous entendons le flux de données qui part du remote pour arriver au dossier local, ainsi que la place mémoire occupée par le dépôt sur le serveur local.
Le dépôt Git créé n'enverra aucune donnée au remote. Il aura accès aux tags mais pas à l'historique. Il pourra éventuellement conserver certains fichiers locaux non-tracés en plus de ses clonages Git. Il incluera les éventuels submodules. Il peut vouloir télécharger le dernier commit de main (par défaut) ou bien un commit d'une certaine référence, c'est-à-dire branche ou tag.
Le dépôt Git créé n'enverra aucune donnée au remote. Il aura accès aux tags mais pas à l'historique. Il pourra éventuellement conserver certains fichiers locaux non-tracés en plus de ses clonages Git. Il incluera les éventuels submodules. Il peut vouloir télécharger le dernier commit de main (par défaut) ou bien un commit d'une certaine référence, c'est-à-dire branche ou tag.
# Procédé
Des tests sur différentes commandes ont été réalisés sur un dépôt factice. Le dossier de tests est transportable et peut être téléchargé ici. Attention, pour fonctionner en local, il nécessite d'autoriser le protocole pour les fichiers locaux : git config --global protocol.file.allow always.
Des tests sur différentes commandes ont été réalisés sur un dépôt factice. Le dossier de tests est transportable et peut être téléchargé ici. Attention, pour fonctionner en local, il nécessite d'autoriser le protocole pour les fichiers locaux : `git config --global protocol.file.allow always`.
Ce n'est pas la configuration par défaut car elle peut représenter une faille de sécurité.
Les tests consistent à analyser l'espace mémoire pris par le dépôt en local grâce à la commande bash "du", ainsi qu'à analyser le texte produit par Git lors du clonage.
Ce n'est pas la configuration par défaut car elle peut représenter une faille de sécurité.
Les tests consistent à analyser l'espace mémoire pris par le dépôt en local grâce à la commande bash "du", ainsi qu'à analyser le texte produit par Git lors du clonage.
# Résultats finaux
La combinaison finale retenue est :
## Pour cloner :
git clone --depth=1 --recurse-submodules --remote-submodules
depth=1 permet d'uniquement cloner le dernier commit et les objets nécessaires. Par défaut, elle est single-branch.
recurse-submodules s'assure que le contenu des submodules est cloné
remote-submodules s'assure que le contenu des submodules est cloné à partir du remote submodule originel
shallow-submodules s'assure que seul le dernier commit des submodules est importé (pour que cela fonctionne en local, il faut préciser ://file/ avant le chemin des submodules)
La combinaison finale retenue est :
## Pour cloner :
`git clone --depth=1 --recurse-submodules --remote-submodules`
- `depth=1` permet d'uniquement cloner le dernier commit et les objets nécessaires. Par défaut, elle est single-branch.
- `recurse-submodules` s'assure que le contenu des submodules est cloné
- `remote-submodules` s'assure que le contenu des submodules est cloné à partir du remote submodule originel
- `shallow-submodules` s'assure que seul le dernier commit des submodules est importé (pour que cela fonctionne en local, il faut préciser ://file/ avant le chemin des submodules)
## Pour mettre à jour :
```
git fetch --tags --depth=1 --prune --prune-tags origin $ref
git reset --hard --recurse-submodules FETCH_HEAD
git submodule update --init --recursive --force --depth=1 --remote
git reflog expire --expire=now --all
git gc --aggressive --prune=now
[git clean -qfdx]
```
git fetch --tags --depth=1 --prune --prune-tags origin
- `git fetch --tags --depth=1 --prune --prune-tags origin`
tags permet de fetch les tags, elle doit être précisée y compris si un tag est fetched par référence
depth=1 permet de considérer uniquement le dernier commit
prune permet de supprimer du dossier remote en local les références qui ne sont plus accessibles
prune-tags permet non seulement de supprimer du dossier remote en local les références qui ne sont plus accessibles, mais aussi de supprimer les tags locaux qui n'existent pas sur le remote
git reset --hard --recurse-submodules origin/main
`tags` permet de fetch les tags, elle doit être précisée y compris si un tag est fetched par référence
`depth=1` permet de considérer uniquement le dernier commit
`prune` permet de supprimer du dossier remote en local les références qui ne sont plus accessibles
`prune-tags` permet non seulement de supprimer du dossier remote en local les références qui ne sont plus accessibles, mais aussi de supprimer les tags locaux qui n'existent pas sur le remote
git submodule update --init --recursive --force --depth=1 --remote
- `git reset --hard --recurse-submodules origin/main`
init met à jour le fichier .gitmodules
recursive applique la commande aux submodules de submodules etc.
force permet d'ignorer les changements locaux aux submodules et d'automatiquement check out la nouvelle version
depth=1 permet de considérer uniquement le dernier commit du submodule
remote permet de mettre à jour depuis le remote submodule originel
ATTENTION : l'ordre compte. Exécuter cette instruction en premier la rendrait inefficace en raison de l'option --recurse-submodules du git reset. Celle-ci est néanmoins à conserver pour gérer le cas de délétion du submodule.
- `git submodule update --init --recursive --force --depth=1 --remote`
git reflog expire --expire=now --all
`init` met à jour le fichier .gitmodules
`recursive` applique la commande aux submodules de submodules etc.
`force` permet d'ignorer les changements locaux aux submodules et d'automatiquement check out la nouvelle version
`depth=1` permet de considérer uniquement le dernier commit du submodule
`remote` permet de mettre à jour depuis le remote submodule originel
ATTENTION : l'ordre compte. Exécuter cette instruction en premier la rendrait inefficace en raison de l'option `--recurse-submodules` du `git reset`. Celle-ci est néanmoins à conserver pour gérer le cas de délétion du submodule.
cette commande permet de marquer tous les reflogs isolés comme expirés immédiatement au lieu de 90 jours plus tard. Cela permet un plus grand nettoyage par git gc. git rev-list permet de vérifier quels objets sont reliés et ne seront pas marqués comme expirés.
- `git reflog expire --expire=now --all`
git gc --aggressive --prune=now
cette commande permet de marquer tous les reflogs isolés comme expirés immédiatement au lieu de 90 jours plus tard. Cela permet un plus grand nettoyage par git gc. git rev-list permet de vérifier quels objets sont reliés et ne seront pas marqués comme expirés.
cette commande supprime les références non reliées et réorganise le dépôt pour l'optimiser.
aggressive invoque repack et prend plus de temps. repack défait et refait les packs, qui sont des unités de compression.
[git clean -qfdx] si cette commande est absente, les fichiers créés non-committés sont conservés.
- `git gc --aggressive --prune=now`
cette commande supprime les références non reliées et réorganise le dépôt pour l'optimiser.
aggressive invoque repack et prend plus de temps. repack défait et refait les packs, qui sont des unités de compression.
- `[git clean -qfdx]`
si cette commande est absente, les fichiers créés non-committés sont conservés. C'est le cas dans git_update.sh.
Cette combinaison ne permet de garder aucun changement effectué sur notre dépôt, hormis les créations de fichiers non-committés si git clean est omis.
# Détails
Voici un résumé de différentes pistes explorées afin de réduire l'empreinte du dépôt Git.
## Clone partiel (partial) vs superficiel (shallow)
Un clone superficiel consiste à ne pas cloner tout l'historique du dépôt.
Un clone partiel consiste à ne pas cloner tous les fichiers et/ou dossiers du dépôt, selon un filtre. Les filtres peuvent concerner les Binary Large Objects (blobs) ou bien les trees. Si le filtre concerne l'ancienneté, un clone partiel peut alors aussi être un clone superficiel. Les clones partiels peuvent être créés grâce à la commande git clone --filter.
Lors de check-out ou switch, des objets initialement ignorés par le clone --filter peuvent être importés.
Dans notre cas, nous ne souhaitons garder quun commit précis, qui sera dans tous les cas laissé passer par git clone --filter et ce n'est donc pas pertinent.
Les clones partiels peuvent aussi être créés par le sparse-checking. Certains fichiers et/ou dossiers n'apparaissent alors pas du tout dans le dossier local et ne sont pas concernés par les opérations git porcelain (de surface). Néanmoins, les objets associés à ces fichiers et dossiers sont toujours stockés dans le .git
Un clone partiel consiste à ne pas cloner tous les fichiers et/ou dossiers du dépôt, selon un filtre. Les filtres peuvent concerner les Binary Large Objects (blobs) ou bien les trees. Si le filtre concerne l'ancienneté, un clone partiel peut alors aussi être un clone superficiel. Les clones partiels peuvent être créés grâce à la commande `git clone --filter`.
Lors de check-out ou switch, des objets initialement ignorés par le `--filter` peuvent être importés.
Dans notre cas, nous ne souhaitons garder quun commit précis, qui sera dans tous les cas laissé passer par `git clone --filter` et ce n'est donc pas pertinent.
Les clones partiels peuvent aussi être créés par le `sparse-checking`. Certains fichiers et/ou dossiers n'apparaissent alors pas du tout dans le dossier local et ne sont pas concernés par les opérations git porcelain (de surface). Néanmoins, les objets associés à ces fichiers et dossiers sont toujours stockés dans le .git
Un clone superficiel peut être créé grâce à l'option depth=<nombre> qui indique le nombre de commits à conserver. Cette option est disponible pour la commande clone mais aussi fetch.
Un clone superficiel peut être créé grâce à l'option `depth=<nombre>` qui indique le nombre de commits à conserver. Cette option est disponible pour la commande `clone` ainsi que `fetch`.
## Le large file storage
LFS est une extension Git qui permet de manipuler les fichiers choisis (par nom, expression ou taille) à l'aide d'un cache local. En pratique, les fichiers sont remplacés par des références dans le dépôt Git et un dossier local hors du dépôt est créé pour stocker les fichiers. Ils y sont téléchargés de manière lazy, c'est-à-dire uniquement lorsqu'ils sont checked out. Toutes les anciennes versions sont stockées sur un serveur en ligne.
C'est un mécanisme très intéressant, que nous ne retenons pas pour la même raison que le clone --filter : nous ne souhaitons garder que la toute dernière version des fichiers, qui serait dans tous les cas téléchargée par LFS.
C'est un mécanisme très intéressant, que nous ne retenons pas pour la même raison que le `git clone --filter` : nous ne souhaitons garder que la toute dernière version des fichiers, qui serait dans tous les cas téléchargée par LFS.
## Suppression de l'historique
L'usage de la commande git filter-branch est déconseillé par la documentation Git. Elle présente plusieurs failles de sécurité et de performance. Elle permet de réécrire l'historique des branches grâce à des filtres.
L'usage de la commande `git filter-branch` est déconseillé par la documentation Git. Elle présente plusieurs failles de sécurité et de performance. Elle permet de réécrire l'historique des branches grâce à des filtres.
La librairie Java repo-cleaner fonctionne, néanmoins la documentation Git estime que la librairie Python filter-repo est plus rapide et plus sûre. Nous ne souhaitons pas devoir installer Python ou Java donc ne creusons pas plus ces deux possibilités.
Nous souhaitons supprimer tout l'historique sans filtrer, donc la commande git fetch --depth=1 suivie d'un git checkout, reset ou merge nous convient.
Nous souhaitons supprimer tout l'historique sans filtrer, donc la commande `git fetch --depth=1` suivie d'un git checkout, reset ou merge nous convient.
## checkout ? merge ? reset ?
Une fois que nous avons fetched les modifications dans notre dossier local remote/, quelle est la meilleure façon de les appliquer à notre index et working directory ?
Nous allons comparer 4 possibilités : git merge -X, git merge -s, git reset --hard, git checkout -f -B. Les résultats finaux sont identiques à l'exception de git merge -X.
Dans le cas de git merge, nous ne souhaitons pas résoudre de conflits manuellement. Le remote doit toujours prévaloir sur les différences locales.
### git merge -X theirs
Une fois que nous avons fetched les modifications dans notre dossier local remote/, quelle est la meilleure façon de les appliquer à notre index et working directory ?
Nous allons comparer 4 possibilités : `git merge -X`, `git merge -s`, `git reset --hard`, `git checkout -f -B`. Les résultats finaux sont identiques à l'exception de `git merge -X`.
Dans le cas de `git merge`, nous ne souhaitons pas résoudre de conflits manuellement. Le remote doit toujours prévaloir sur les différences locales.
### `git merge -X theirs`
Cette commande applique une stratégie ort qui en cas de conflit, donne la prévalence à theirs.
Néanmoins, puisque nous travaillons en --depth=1, les deux branches n'ont pas d'ancêtre commun, et nous devons d'ailleurs fournir l'option --allow-unrelated-histories. L'absence d'ancêtre commun empêche Git de reconnaître les similitudes à l'intérieur d'un même fichier. N'importe quelle modification d'un fichier tracé sur ours, même sur une nouvelle ligne, causera ainsi un conflit et sera écrasée. Cette commande permet tout de même de sauvegarder les fichiers nouvellement créés et committés sur ours.
Les fichiers non-committés nouvellement créés sont conservés à moins que git clean soit run.
Néanmoins, puisque nous travaillons en `--depth=1`, les deux branches n'ont pas d'ancêtre commun, et nous devons d'ailleurs fournir l'option `--allow-unrelated-histories`. L'absence d'ancêtre commun empêche Git de reconnaître les similitudes à l'intérieur d'un même fichier. N'importe quelle modification d'un fichier tracé sur ours, même sur une nouvelle ligne, causera ainsi un conflit et sera écrasée. Cette commande permet tout de même de sauvegarder les fichiers nouvellement créés et committés sur ours.
Les fichiers non-committés nouvellement créés sont conservés à moins que `git clean` soit run.
Avantage : fichier commités créés sur ours conservés
Inconvénient : en cas de délétion d'un fichier sur theirs qui existait déjà sur ours : il ne sera pas supprimé sur ours.
### git merge -s ours
[attention les notions de theirs et ours sont inversées ici car git merge -s theirs n'existe pas]
Cette commande applique une stratégie ours qui donne la prévalence à ours, qu'il y ait conflit ou pas. Elle va ignorer tous les changements et créations de fichiers committés sur theirs. Elle va également ignorer les modifications non committées. Les créations de fichier non-committées sont conservées à moins que git clean soit run. C'est le même résultat qu'avec la commande git reset --hard.
Comme l'option git merge -s theirs n'existe pas, nous devons faire une petite manipulation :
### `git merge -s ours`
[attention les notions de theirs et ours sont inversées ici car `git merge -s theirs` n'existe pas]
Cette commande applique une stratégie ours qui donne la prévalence à ours, qu'il y ait conflit ou pas. Elle va ignorer tous les changements et créations de fichiers committés sur theirs. Elle va également ignorer les modifications non committées. Les créations de fichier non-committées sont conservées à moins que `git clean` soit run. C'est le même résultat qu'avec la commande `git reset --hard`.
Comme l'option `git merge -s theirs` n'existe pas, nous devons faire une petite manipulation :
```
#on veut merge origin/main sur main, en donnant la prévalence à origin/main
#création d'une nouvelle branche temporaire temp qui est checked out, sourcée sur origin/main
git switch -c temp origin/main
@ -121,41 +135,48 @@ git checkout main
git merge --allow-unrelated-histories temp
#suppression de temp
git branch -D temp
Avantage :
```
Avantage :
Inconvénient : création d'une branche temporaire.
### git checkout force -B main origin/main
Cette commande est équivalente à git merge -s ours et à git reset --hard, à la différence près que nous finissons en detached HEAD state, ce qui n'est pas un problème dans notre cas puisque nous ne souhaitons pas push de modification depuis notre dépôt.
Avantage :
### `git checkout force -B main origin/main`
Cette commande est équivalente à `git merge -s ours` et à `git reset --hard`, à la différence près que nous finissons en detached HEAD state, ce qui n'est pas un problème dans notre cas puisque nous ne souhaitons pas push de modification depuis notre dépôt.
Avantage :
Inconvénient : detached HEAD state.
### git reset --hard
git reset --hard est équivalente à git merge -s ours et git checkout --force -B.
Avantage :
Inconvénient :
### `git reset --hard`
Les tests nous montrent que les options les plus économes en mémoire sont git checkout -force -B, git merge -s ours, git --reset hard, qui font la même chose. Néanmoins git reset --hard n'implique pas la création d'une branche temporaire et ne finit pas en detached HEAD state, c'est donc celle que nous retenons.
`git reset --hard` est équivalente à `git merge -s ours` et `git checkout --force -B`.
Avantage :
Inconvénient :
Les tests nous montrent que les options les plus économes en mémoire sont `git checkout -force -B`, `git merge -s ours`, `git --reset hard`, qui font la même chose. Néanmoins `git reset --hard` n'implique pas la création d'une branche temporaire et ne finit pas en detached HEAD state, c'est donc celle que nous retenons.
### Gestion des submodules
Les submodules sont clonés au début via les options de git clone --recurse-submodules --remote-submodules.
Puis ils sont mis à jour par git submodule update --init --recursive --force --depth=1 remote.
Git reset --hard doit avoi rloption --recurse-submodules pour pouvoir supprimer des submodules du working directory.
Les submodules sont clonés au début via les options de `git clone --recurse-submodules --remote-submodules`.
Puis ils sont mis à jour par `git submodule update --init --recursive --force --depth=1 remote`.
`git reset --hard` doit avoir loption `--recurse-submodules` pour pouvoir supprimer des submodules du working directory.
Les mêmes règles s'appliquent aux submodules qu'au reste du dépôt. Il est possible de préciser dans le fichier .gitmodules des règles d'import des submodules, comme un certain tag ou une certaine branche par exemple.
En retirant --remote-submodules du git clone et --remote du git submodule update, alors les submodules seront identiques au dépôt que nous clonons et plus au dépôt originel du submodule.
En retirant `--remote-submodules` du `git clone` et `--remote` du `git submodule update`, alors les submodules seront identiques au dépôt que nous clonons et plus au dépôt originel du submodule.
##Tests
## Tests
### Description du script
Le script est composé de vingt-neuf tests (listés dans les résultats ci-dessous), qui s'appuient sur trois fonctions : generate_random_file, get_storage_used et get_bandwidth.
generate_random_file s'appuie sur la commande bash dd et /dev/random.
get_storage_used utilise la commande bash du.
get_bandwidth récupère la sortie des commandes Git et extrait le trafic affiché. Celui-ci ne prend pas en compte le trafic des submodules.
generate_random_file s'appuie sur la commande bash dd et /dev/random.
get_storage_used utilise la commande bash du.
get_bandwidth récupère la sortie des commandes Git et extrait le trafic affiché. Celui-ci ne prend pas en compte le trafic des submodules.
Les cinq premiers tests concernent le clonage.
Les cinq premiers tests concernent le clonage.
Les tests suivants concernent la mise à jour du dépôt selon différentes commandes, avec pour chaque commande trois cas : après addition d'un fichier, après délétion d'un fichier, après addition puis délétion d'un fichier.
### Extrait du README
```
NAME
performance_tests.sh
SYNOPSIS
@ -164,6 +185,7 @@ OPTIONS
-a excutes all the tests.
-n number executes test number
-h prints the help.
```
### Résultats