16 votes

Qu'est-ce que signifie profondeur pour git clone ?

Nous avons essayé d'accélérer la construction continue (CI) d'un de nos projets logiciels au travail. Quelqu'un a commis des fichiers binaires énormes (selon les normes de git) au début de la vie du projet. Réécrire l'historique de git juste pour s'en débarrasser semble trop compliqué, donc nous avons pensé qu'une clonage peu profond évitant ces gros commits initiaux serait suffisant.

J'ai fait quelques expériences avec le paramètre --depth pour le clonage et j'ai rencontré un comportement étrange. Voici ce que dit l'aide de git clone à ce sujet:

--depth 
           Crée un clonage peu profond avec un historique tronqué au nombre spécifié de commits. Implique
           --single-branch sauf si --no-single-branch est donné pour récupérer les historiques près des extrémités de toutes
           les branches. Si vous voulez cloner des sous-modules de manière peu profonde, passez aussi --shallow-submodules.

Cela indiquerait que équivaudra au nombre de commits qui seront récupérés lors du clonage, mais ce n'est pas le cas. Voici ce que j'ai obtenu quand j'ai essayé différentes valeurs pour depth:

| depth   | nombre de commits repo linux | nombre de commits repo git |
|---------|-------------------------|-----------------------|
| 1       | 1                       | 1                     |
| 5       | 15                      | 13                    |
| 10      | 80                      | 46                    |
| 100     | 93133                   | 39552                 |
| 1000    | 788718                  | 53880                 |

Pour le clonage, j'ai utilisé cette commande git clone --depth 10 https://github.com/torvalds/linux.git, git clone --depth 100 https://github.com/git/git.git, et pour compter les commits j'ai utilisé ceci git log --oneline | wc -l. (Au travail j'ai observé la même chose avec un serveur GitLab, donc cela ne peut pas être un artefact de la façon dont fonctionne GitHub.)

Est-ce que quelqu'un sait ce qui se passe? Comment la valeur de depth correspond-elle à la quantité réelle de données téléchargées? Est-ce que je comprends mal la documentation, ou y a-t-il un bug?

EDIT: J'ai ajouté les résultats pour un deuxième repo

24voto

torek Points 25463

Comme l'a commenté Jonathon Reinhart, vous observez l'effet des fusions.

Le paramètre --depth fait référence à la profondeur à laquelle Git parcourt à partir de chaque point de départ. Comme le mentionne la documentation que vous avez citée, cela implique également --single-branch, ce qui simplifie la discussion à ce sujet. Le point important ici est que le parcours visite tous les parents de chaque commit, ce qui – pour chaque niveau de profondeur – est plus d'un commit si le commit lui-même est une fusion.

Supposons que nous ayons un graphique de commits qui ressemble à ceci :

$ git log --graph --oneline master
* cf68824 profile: fix PATH with GOPATH
* 7c2376b profile: add Ruby gem support
* 95c8270 profile: set GOPATH
* 26a9cc3 vimrc: fiddle with netrw directory display
* 80b88a5 add ruby gems directory to path
[snip]

Ici, chaque commit a juste un parent. Si nous utilisons --depth 3, nous récupérerons le commit de la pointe cf68824, son parent 7c2376b à la profondeur 2, et enfin 95c8270 à la profondeur 3 - puis nous nous arrêtons, avec trois commits.

Avec le dépôt Git pour Git, cependant :

$ git log --graph --oneline master
*   965798d1f2 Merge branch 'es/format-patch-range-diff-fix-fix'
|\  
| * ac0edf1f46 range-diff: always pass at least minimal diff options
* |   5335669531 Merge branch 'en/rebase-consistency'
|\ \  
| * | 6fcbad87d4 rebase docs: fix incorrect format of the section Behavioral Differences
* | | 7e75a63d74 RelNotes 2.20: drop spurious double quote
* | | 7a49e44465 RelNotes 2.20: clarify sentence
[snip]

Avec --depth 3, nous commençons avec 965798d1f2, puis - pour la profondeur 2 - récupérons les deux parents, ac0edf1f46 et 5335669531. Pour ajouter les commits de profondeur 3, nous récupérons tous les parents de ces deux commits. Le parent (unique) de ac0edf1f46 n'est pas visible ici, alors que les deux parents de 5335669531 le sont (à savoir 6fcbad87d4 et 7e75a63d74). Pour obtenir les IDs de hachage des parents de ac0edf1f46 nous pouvons utiliser :

$ git rev-parse ac0edf1f46^@
d8981c3f885ceaddfec0e545b0f995b96e5ec58f

ce qui nous donne nos six commits : la pointe de master (qui est actuellement un commit de fusion), deux parents de ce commit, un parent de l'un de ces parents, et deux parents de l'autre de ces parents.

En fonction du moment exact où vous avez exécuté le clone de Git, la pointe de master est souvent un commit de fusion, mais a souvent une fusion comme parent immédiat, de sorte que --depth 2 vous donnera souvent 3 commits, et --depth 3 obtiendra donc au moins 5, en fonction de si les deux parents de la pointe de master sont eux-mêmes des fusions.

(Comparez la sortie git rev-parse ci-dessus avec :

$ git rev-parse 965798d1f2^@
5335669531d83d7d6c905bcfca9b5f8e182dc4d4
ac0edf1f46fcf9b9f6f1156e555bdf740cd56c5f

par exemple. Le suffixe ^@ signifie tous les parents du commit, mais pas le commit lui-même.)

3voto

jsexpert Points 704

--depth signifie le nombre de validations à récupérer lorsque vous clonez.

Par défaut, git télécharge tout votre historique de toutes les branches. Cela signifie que votre copie aura tout l'historique, vous pourrez donc "changer" (checkout) vers n'importe quelle validation que vous souhaitez.

Ajouter le --depth limite la taille de votre clone et ne vérifie que les X dernières validations

# Clonage d'une seule branche avec les options suivantes :
# cloner une branche spécifique et limiter l'historique aux X dernières validations
git clone --branch<...> --depth=

Comment la valeur de profondeur correspond-elle à la quantité réelle de données téléchargées? avec le --depth git ne téléchargera que le contenu correspondant aux validations dans la plage donnée, de sorte que la taille du dépôt augmentera lorsque la valeur est plus grande


Cela indiquerait que sera égal au nombre de validations qui seront récupérées pendant

Pas toujours, si l'une de ces validations est une fusion (par exemple non fast forward) vous obtiendrez plus de X validations.


Comment nettoyer votre binaire:

Réécrire l'historique de git juste pour s'en débarrasser semble être trop contraignant

Cet outil peut le faire pour vous:

https://rtyley.github.io/bfg-repo-cleaner

BFG Repo-Cleaner une alternative à git-filter-branch.

Le BFG est une alternative plus simple et plus rapide à git-filter-branch pour nettoyer les mauvaises données de l'historique de votre dépôt Git:

*** Supprimer des fichiers très volumineux***

  • Supprimer les mots de passe, les informations d'identification et autres données privées

Exemples (du site officiel) Dans tous ces exemples, bfg est un alias pour java -jar bfg.jar.

# Supprimer tous les fichiers nommés 'id_rsa' ou 'id_dsa' :
bfg --delete-files id_{dsa,rsa}  my-repo.git

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X