[{"data":1,"prerenderedAt":2070},["ShallowReactive",2],{"/fr-fr/blog/a-beginners-guide-to-the-git-reftable-format":3,"navigation-fr-fr":1286,"banner-fr-fr":1721,"footer-fr-fr":1729,"blog-post-authors-fr-fr-Patrick Steinhardt":1968,"blog-related-posts-fr-fr-a-beginners-guide-to-the-git-reftable-format":1983,"blog-promotions-fr-fr":2007,"next-steps-fr-fr":2061},{"id":4,"title":5,"authors":6,"body":8,"category":1263,"date":1264,"description":1265,"extension":1266,"externalUrl":1267,"faq":1267,"featured":169,"heroImage":1268,"meta":1269,"navigation":169,"path":1270,"seo":1271,"slug":1276,"stem":1277,"tags":1278,"template":1283,"updatedDate":1284,"__hash__":1285},"blogPosts/fr-fr/blog/a-beginners-guide-to-the-git-reftable-format.md","Format reftable de Git : guide pour les débutants",[7],"Patrick Steinhardt",{"type":9,"value":10,"toc":1250},"minimark",[11,22,38,41,46,56,59,81,84,92,99,102,273,277,284,454,460,533,536,539,564,570,620,623,637,640,714,720,724,727,744,751,767,770,778,781,787,790,799,802,805,810,817,831,834,856,862,866,869,872,880,883,894,900,904,907,910,918,921,924,927,945,949,959,965,1025,1028,1031,1034,1041,1050,1055,1061,1066,1072,1077,1084,1087,1091,1097,1114,1117,1193,1200,1207,1211,1220,1246],[12,13,14,15,21],"p",{},"Jusqu'à récemment, Git ne pouvait stocker des références qu'au format « fichiers ». Avec la ",[16,17,20],"a",{"href":18,"rel":19},"https://about.gitlab.com/fr-fr/blog/whats-new-in-git-2-45-0/",[],"version 2.45.0 de Git",", Git peut désormais stocker des références au format « reftable ». Ce nouveau format binaire est un peu plus complexe, mais c'est précisément cette complexité qui lui permet de corriger plusieurs lacunes du format « fichiers ». Les objectifs du format « reftable » sont les suivants :",[23,24,25,29,32,35],"ul",{},[26,27,28],"li",{},"Rendre la recherche d'une référence unique et l'itération à travers des plages de références aussi efficaces et rapides que possible.",[26,30,31],{},"Prendre en charge des lectures cohérentes des références afin que Git ne lise jamais un état intermédiaire lorsqu'une mise à jour de plusieurs références n'a été appliquée que partiellement.",[26,33,34],{},"Prendre en charge des écritures atomiques de sorte que la mise à jour de plusieurs références peut être effectuée comme une opération tout ou rien.",[26,36,37],{},"Stocker efficacement des références et des journaux de référence (« reflog »).",[12,39,40],{},"Dans cet article, nous allons examiner le format « reftable » pour comprendre son fonctionnement.",[42,43,45],"h2",{"id":44},"stockage-des-références-dans-git","Stockage des références dans Git",[12,47,48,49,55],{},"Avant d'entrer dans les détails, récapitulons rapidement la façon dont ",[16,50,54],{"href":51,"rel":52,"title":53},"https://about.gitlab.com/fr-fr/blog/what-is-git/",[],"Qu'est-ce que Git ? ","Git"," stockait les références jusqu'à présent. Si le sujet vous est familier, vous pouvez passer cette section.",[12,57,58],{},"Un dépôt Git contient deux structures de données importantes :",[23,60,61,69],{},[26,62,63,68],{},[16,64,67],{"href":65,"rel":66},"https://git-scm.com/book/fr/v2/Les-tripes-de-Git-Les-objets-de-Git",[],"Les objets",", qui contiennent les données réelles de votre dépôt. Ils incluent les validations (« commits »), la structure d'arborescence des répertoires (« tree ») et les blobs qui contiennent votre code source. Les objets sont organisés de manière à ce qu'ils pointent les uns vers les autres, formant ainsi un graphe des objets. En outre, chaque objet est associé à un identifiant unique, appelé ID d'objet.",[26,70,71,72,76,77,80],{},"Les références, telles que les branches et les étiquettes (« tags »). Ces pointeurs sur des objets du graphe vous permettent de donner des noms à des objets qui sont plus faciles à mémoriser et de suivre les différentes étapes et directions de votre historique de développement. Par exemple, un dépôt peut contenir une branche ",[73,74,75],"code",{},"main"," : il s'agit d'une référence nommée ",[73,78,79],{},"refs/heads/main"," qui pointe vers une validation spécifique.",[12,82,83],{},"Les références sont stockées dans la base de données des références. Jusqu'à la version 2.45.0 de Git, le format « fichiers » constituait le seul format de base de données disponible. Ce format stocke chaque référence en tant que fichier normal contenant l'un des éléments suivants :",[23,85,86,89],{},[26,87,88],{},"Une référence standard qui contient l'ID d'objet de la validation vers laquelle elle pointe.",[26,90,91],{},"Une référence symbolique qui contient le nom d'une autre référence, de la même manière qu'un lien symbolique pointe vers un autre fichier.",[12,93,94,95,98],{},"Ces références sont régulièrement empaquetées dans un seul fichier ",[73,96,97],{},"packed-refs"," afin de faciliter les recherches.",[12,100,101],{},"Les exemples suivants illustrent le fonctionnement du format « fichiers » :",[103,104,109],"pre",{"className":105,"code":106,"language":107,"meta":108,"style":108},"language-shell shiki shiki-themes github-light","$ git init .\n$ git commit --allow-empty --message \"Initial commit\"\n[main (root-commit) 6917c17] Initial commit\n\n# HEAD is a symbolic reference pointing to refs/heads/main.\n$ cat .git/HEAD\nref: refs/heads/main\n\n# refs/heads/main is a regular reference pointing to a commit.\n$ cat .git/refs/heads/main\n6917c178cfc3c50215a82cf959204e9934af24c8\n\n# git-pack-refs(1) packs these references into the packed-refs file.\n$ git pack-refs --all\n$ cat .git/packed-refs\n# pack-refs with: peeled fully-peeled sorted\n6917c178cfc3c50215a82cf959204e9934af24c8 refs/heads/main\n","shell","",[73,110,111,130,150,164,171,178,189,198,203,209,219,225,230,236,249,259,265],{"__ignoreMap":108},[112,113,116,120,124,127],"span",{"class":114,"line":115},"line",1,[112,117,119],{"class":118},"s7eDp","$",[112,121,123],{"class":122},"sYBdl"," git",[112,125,126],{"class":122}," init",[112,128,129],{"class":122}," .\n",[112,131,133,135,137,140,144,147],{"class":114,"line":132},2,[112,134,119],{"class":118},[112,136,123],{"class":122},[112,138,139],{"class":122}," commit",[112,141,143],{"class":142},"sYu0t"," --allow-empty",[112,145,146],{"class":142}," --message",[112,148,149],{"class":122}," \"Initial commit\"\n",[112,151,153,157,161],{"class":114,"line":152},3,[112,154,156],{"class":155},"sgsFI","[main (root",[112,158,160],{"class":159},"sD7c4","-",[112,162,163],{"class":155},"commit) 6917c17] Initial commit\n",[112,165,167],{"class":114,"line":166},4,[112,168,170],{"emptyLinePlaceholder":169},true,"\n",[112,172,174],{"class":114,"line":173},5,[112,175,177],{"class":176},"sAwPA","# HEAD is a symbolic reference pointing to refs/heads/main.\n",[112,179,181,183,186],{"class":114,"line":180},6,[112,182,119],{"class":118},[112,184,185],{"class":122}," cat",[112,187,188],{"class":122}," .git/HEAD\n",[112,190,192,195],{"class":114,"line":191},7,[112,193,194],{"class":118},"ref:",[112,196,197],{"class":122}," refs/heads/main\n",[112,199,201],{"class":114,"line":200},8,[112,202,170],{"emptyLinePlaceholder":169},[112,204,206],{"class":114,"line":205},9,[112,207,208],{"class":176},"# refs/heads/main is a regular reference pointing to a commit.\n",[112,210,212,214,216],{"class":114,"line":211},10,[112,213,119],{"class":118},[112,215,185],{"class":122},[112,217,218],{"class":122}," .git/refs/heads/main\n",[112,220,222],{"class":114,"line":221},11,[112,223,224],{"class":118},"6917c178cfc3c50215a82cf959204e9934af24c8\n",[112,226,228],{"class":114,"line":227},12,[112,229,170],{"emptyLinePlaceholder":169},[112,231,233],{"class":114,"line":232},13,[112,234,235],{"class":176},"# git-pack-refs(1) packs these references into the packed-refs file.\n",[112,237,239,241,243,246],{"class":114,"line":238},14,[112,240,119],{"class":118},[112,242,123],{"class":122},[112,244,245],{"class":122}," pack-refs",[112,247,248],{"class":142}," --all\n",[112,250,252,254,256],{"class":114,"line":251},15,[112,253,119],{"class":118},[112,255,185],{"class":122},[112,257,258],{"class":122}," .git/packed-refs\n",[112,260,262],{"class":114,"line":261},16,[112,263,264],{"class":176},"# pack-refs with: peeled fully-peeled sorted\n",[112,266,268,271],{"class":114,"line":267},17,[112,269,270],{"class":118},"6917c178cfc3c50215a82cf959204e9934af24c8",[112,272,197],{"class":122},[42,274,276],{"id":275},"vue-densemble-de-la-structure-reftable","Vue d'ensemble de la structure « reftable »",[12,278,279,280,283],{},"Si vous avez installé la version 2.45.0 de Git ou une version plus récente, vous pouvez créer un dépôt au format « reftable » en utilisant l'option ",[73,281,282],{},"--ref-format=reftable"," :",[103,285,287],{"className":105,"code":286,"language":107,"meta":108,"style":108},"$ git init --ref-format=reftable .\nInitialized empty Git repository in /tmp/repo/.git/\n$ git rev-parse --show-ref-format\nreftable\n\n# Irrelevant files have been removed for ease of understanding.\n$ tree .git\n.git\n├── config\n├── HEAD\n├── index\n├── objects\n├── refs\n│   └── heads\n└── reftable\n    ├── 0x000000000001-0x000000000002-40a482a9.ref\n    └── tables.list\n\n4 directories, 6 files\n",[73,288,289,302,322,334,339,343,348,358,363,371,378,385,392,399,410,418,426,434,439],{"__ignoreMap":108},[112,290,291,293,295,297,300],{"class":114,"line":115},[112,292,119],{"class":118},[112,294,123],{"class":122},[112,296,126],{"class":122},[112,298,299],{"class":142}," --ref-format=reftable",[112,301,129],{"class":122},[112,303,304,307,310,313,316,319],{"class":114,"line":132},[112,305,306],{"class":118},"Initialized",[112,308,309],{"class":122}," empty",[112,311,312],{"class":122}," Git",[112,314,315],{"class":122}," repository",[112,317,318],{"class":122}," in",[112,320,321],{"class":122}," /tmp/repo/.git/\n",[112,323,324,326,328,331],{"class":114,"line":152},[112,325,119],{"class":118},[112,327,123],{"class":122},[112,329,330],{"class":122}," rev-parse",[112,332,333],{"class":142}," --show-ref-format\n",[112,335,336],{"class":114,"line":166},[112,337,338],{"class":118},"reftable\n",[112,340,341],{"class":114,"line":173},[112,342,170],{"emptyLinePlaceholder":169},[112,344,345],{"class":114,"line":180},[112,346,347],{"class":176},"# Irrelevant files have been removed for ease of understanding.\n",[112,349,350,352,355],{"class":114,"line":191},[112,351,119],{"class":118},[112,353,354],{"class":122}," tree",[112,356,357],{"class":122}," .git\n",[112,359,360],{"class":114,"line":200},[112,361,362],{"class":118},".git\n",[112,364,365,368],{"class":114,"line":205},[112,366,367],{"class":118},"├──",[112,369,370],{"class":122}," config\n",[112,372,373,375],{"class":114,"line":211},[112,374,367],{"class":118},[112,376,377],{"class":122}," HEAD\n",[112,379,380,382],{"class":114,"line":221},[112,381,367],{"class":118},[112,383,384],{"class":122}," index\n",[112,386,387,389],{"class":114,"line":227},[112,388,367],{"class":118},[112,390,391],{"class":122}," objects\n",[112,393,394,396],{"class":114,"line":232},[112,395,367],{"class":118},[112,397,398],{"class":122}," refs\n",[112,400,401,404,407],{"class":114,"line":238},[112,402,403],{"class":118},"│",[112,405,406],{"class":122},"   └──",[112,408,409],{"class":122}," heads\n",[112,411,412,415],{"class":114,"line":251},[112,413,414],{"class":118},"└──",[112,416,417],{"class":122}," reftable\n",[112,419,420,423],{"class":114,"line":261},[112,421,422],{"class":118},"    ├──",[112,424,425],{"class":122}," 0x000000000001-0x000000000002-40a482a9.ref\n",[112,427,428,431],{"class":114,"line":267},[112,429,430],{"class":118},"    └──",[112,432,433],{"class":122}," tables.list\n",[112,435,437],{"class":114,"line":436},18,[112,438,170],{"emptyLinePlaceholder":169},[112,440,442,445,448,451],{"class":114,"line":441},19,[112,443,444],{"class":118},"4",[112,446,447],{"class":122}," directories,",[112,449,450],{"class":142}," 6",[112,452,453],{"class":122}," files\n",[12,455,456,457,283],{},"Regardez la configuration du dépôt. Remarquez tout d'abord sa clé de configuration ",[73,458,459],{},"extension.refstorage",[103,461,463],{"className":105,"code":462,"language":107,"meta":108,"style":108},"$ cat .git/config\n[core]\n    repositoryformatversion = 1\n    filemode = true\n    bare = false\n    logallrefupdates = true\n[extensions]\n    refstorage = reftable\n",[73,464,465,474,479,490,500,510,519,524],{"__ignoreMap":108},[112,466,467,469,471],{"class":114,"line":115},[112,468,119],{"class":118},[112,470,185],{"class":122},[112,472,473],{"class":122}," .git/config\n",[112,475,476],{"class":114,"line":132},[112,477,478],{"class":155},"[core]\n",[112,480,481,484,487],{"class":114,"line":152},[112,482,483],{"class":118},"    repositoryformatversion",[112,485,486],{"class":122}," =",[112,488,489],{"class":142}," 1\n",[112,491,492,495,497],{"class":114,"line":166},[112,493,494],{"class":118},"    filemode",[112,496,486],{"class":122},[112,498,499],{"class":142}," true\n",[112,501,502,505,507],{"class":114,"line":173},[112,503,504],{"class":118},"    bare",[112,506,486],{"class":122},[112,508,509],{"class":142}," false\n",[112,511,512,515,517],{"class":114,"line":180},[112,513,514],{"class":118},"    logallrefupdates",[112,516,486],{"class":122},[112,518,499],{"class":142},[112,520,521],{"class":114,"line":191},[112,522,523],{"class":155},"[extensions]\n",[112,525,526,529,531],{"class":114,"line":200},[112,527,528],{"class":118},"    refstorage",[112,530,486],{"class":122},[112,532,417],{"class":122},[12,534,535],{},"Cette configuration indique à Git que le dépôt a été initialisé avec le format « reftable » et que Git doit utiliser le backend « reftable » pour y accéder.",[12,537,538],{},"Curieusement, le dépôt contient encore des fichiers qui semblent utilisés par le backend « fichiers » :",[23,540,541,554],{},[26,542,543,546,547,549,550,553],{},[73,544,545],{},"HEAD"," est une référence symbolique dans Git qui indique généralement la branche sur laquelle vous travaillez actuellement. Bien que le format « reftable » n'utilise pas HEAD, la présence de cette référence est nécessaire pour qu'un répertoire soit reconnu comme un dépôt Git par les clients Git. Par conséquent, lorsque vous utilisez le format « reftable », ",[73,548,545],{}," est juste une entité fictive et temporaire dont le contenu est ",[73,551,552],{},"ref: refs/heads/.invalid",".",[26,555,556,559,560,563],{},[73,557,558],{},"refs/head"," est un fichier dont le contenu est : ",[73,561,562],{},"this repository uses the reftable format",". Les clients Git qui ne connaissent pas le format « reftable » s'attendent généralement à ce que le chemin d'accès soit un répertoire. Par conséquent, la création de ce chemin d'accès en tant que fichier entraîne intentionnellement l'échec des anciens clients Git s'ils tentent d'accéder au dépôt par le biais du backend « fichiers ».",[12,565,566,567,283],{},"Les références réelles sont stockées dans le répertoire ",[73,568,569],{},"reftable/",[103,571,573],{"className":105,"code":572,"language":107,"meta":108,"style":108},"$ tree .git/reftable\n.git/reftable/\n├── 0x000000000001-0x000000000001-794bd722.ref\n└── tables.list\n\n$ cat .git/reftable/tables.list\n0x000000000001-0x000000000001-794bd722.ref\n",[73,574,575,584,589,596,602,606,615],{"__ignoreMap":108},[112,576,577,579,581],{"class":114,"line":115},[112,578,119],{"class":118},[112,580,354],{"class":122},[112,582,583],{"class":122}," .git/reftable\n",[112,585,586],{"class":114,"line":132},[112,587,588],{"class":118},".git/reftable/\n",[112,590,591,593],{"class":114,"line":152},[112,592,367],{"class":118},[112,594,595],{"class":122}," 0x000000000001-0x000000000001-794bd722.ref\n",[112,597,598,600],{"class":114,"line":166},[112,599,414],{"class":118},[112,601,433],{"class":122},[112,603,604],{"class":114,"line":173},[112,605,170],{"emptyLinePlaceholder":169},[112,607,608,610,612],{"class":114,"line":180},[112,609,119],{"class":118},[112,611,185],{"class":122},[112,613,614],{"class":122}," .git/reftable/tables.list\n",[112,616,617],{"class":114,"line":191},[112,618,619],{"class":118},"0x000000000001-0x000000000001-794bd722.ref\n",[12,621,622],{},"Il y a ici deux fichiers :",[23,624,625,631],{},[26,626,627,630],{},[73,628,629],{},"0x000000000001-0x000000000001-794bd722.ref"," est une table contenant des références et des données de reflog dans un format binaire.",[26,632,633,636],{},[73,634,635],{},"tables.list"," est, comme son nom l'indique, une liste de tables. Dans l'état actuel du dépôt, le fichier contient une seule ligne, qui est le nom de la table. Ce fichier suit l'ensemble actuel des tables actives dans la base de données « reftable ». Il est mis à jour chaque fois que de nouvelles tables sont ajoutées au dépôt.",[12,638,639],{},"La mise à jour d'une référence crée une nouvelle table :",[103,641,643],{"className":105,"code":642,"language":107,"meta":108,"style":108},"$ git commit --allow-empty --message \"Initial commit\"\n[main (root-commit) 1472a58] Initial commit\n\n$ tree .git/reftable\n.git/reftable/\n├── 0x000000000001-0x000000000002-eb87d12b.ref\n└── tables.list\n\n$ cat .git/reftable/tables.list\n0x000000000001-0x000000000002-eb87d12b.ref\n",[73,644,645,659,668,672,680,684,691,697,701,709],{"__ignoreMap":108},[112,646,647,649,651,653,655,657],{"class":114,"line":115},[112,648,119],{"class":118},[112,650,123],{"class":122},[112,652,139],{"class":122},[112,654,143],{"class":142},[112,656,146],{"class":142},[112,658,149],{"class":122},[112,660,661,663,665],{"class":114,"line":132},[112,662,156],{"class":155},[112,664,160],{"class":159},[112,666,667],{"class":155},"commit) 1472a58] Initial commit\n",[112,669,670],{"class":114,"line":152},[112,671,170],{"emptyLinePlaceholder":169},[112,673,674,676,678],{"class":114,"line":166},[112,675,119],{"class":118},[112,677,354],{"class":122},[112,679,583],{"class":122},[112,681,682],{"class":114,"line":173},[112,683,588],{"class":118},[112,685,686,688],{"class":114,"line":180},[112,687,367],{"class":118},[112,689,690],{"class":122}," 0x000000000001-0x000000000002-eb87d12b.ref\n",[112,692,693,695],{"class":114,"line":191},[112,694,414],{"class":118},[112,696,433],{"class":122},[112,698,699],{"class":114,"line":200},[112,700,170],{"emptyLinePlaceholder":169},[112,702,703,705,707],{"class":114,"line":205},[112,704,119],{"class":118},[112,706,185],{"class":122},[112,708,614],{"class":122},[112,710,711],{"class":114,"line":211},[112,712,713],{"class":118},"0x000000000001-0x000000000002-eb87d12b.ref\n",[12,715,716,717,719],{},"Comme vous pouvez le constater, la table précédente a été remplacée par une nouvelle. En outre, le fichier ",[73,718,635],{}," a été mis à jour pour contenir la nouvelle table.",[42,721,723],{"id":722},"structure-dune-table","Structure d'une table",[12,725,726],{},"Comme mentionné précédemment, les données réelles de la base de données des références sont contenues dans des tables. Pour faire simple, une table se divise en plusieurs sections :",[23,728,729,732,735,738,741],{},[26,730,731],{},"L'en-tête contient des métadonnées sur la table. En plus d'autres informations, il inclut la version du format, la taille des blocs de données et la fonction de hachage utilisée par le dépôt (par exemple, SHA1 ou SHA256).",[26,733,734],{},"La section « ref » contient vos références. Ces enregistrements ont une clé identique au nom de la référence et pointent soit vers un ID d'objet pour les références standards, soit vers une autre référence pour les références symboliques.",[26,736,737],{},"La section « obj » contient la correspondance inverse entre les ID d'objet et les références qui pointent vers eux. Celle-ci permet à Git de rechercher efficacement les références qui pointent vers un ID d'objet spécifique.",[26,739,740],{},"La section « log » contient vos éléments reflog. Ces enregistrements ont une clé identique au nom de la référence, plus un index qui représente le numéro de l'élément du journal. Ils contiennent en outre les anciens et nouveaux ID d'objet, ainsi que le message pour cet élément reflog.",[26,742,743],{},"Le « footer » contient des offsets pour les différentes sections.",[12,745,746],{},[747,748],"img",{"alt":749,"src":750},"table longue avec toutes les sections reftable","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675179/Blog/Content%20Images/Frame_1_-_Reftable_overview.svg",[12,752,753,754,757,758,761,762,764,765,553],{},"Chaque type de section est structuré de manière similaire. Les sections contiennent un ensemble d'enregistrements qui sont classés en fonction de la clé de chaque enregistrement. Par exemple, lorsque vous avez ces deux enregistrements de références : ",[73,755,756],{},"refs/heads/aaaaa"," et ",[73,759,760],{},"refs/heads/bbb",", vous avez deux enregistrements de références dont les noms de référence sont les clés respectives, et ",[73,763,756],{}," vient avant ",[73,766,760],{},[12,768,769],{},"Chaque section est par ailleurs divisée en blocs d'une longueur fixe. La longueur d'un bloc est encodée dans l'en-tête et remplit deux fonctions :",[23,771,772,775],{},[26,773,774],{},"En se basant sur le début de la section ainsi que la taille des blocs de données, le processus qui lit les tables sait implicitement où chacun des blocs commence. Git peut ainsi facilement effectuer une recherche au milieu d'une section sans lire les blocs précédents, ce qui permet d'effectuer des recherches par dichotomie sur des blocs pour accélérer la recherche d'enregistrements.",[26,776,777],{},"Elle permet au processus qui lit les tables de savoir combien de données lire sur le disque à la fois. Par conséquent, la taille des blocs de données est par défaut définie à 4 KiB, ce qui correspond à la taille de secteur la plus courante pour les disques durs. La taille maximale des blocs de données est de 16 Mo.",[12,779,780],{},"Intéressons-nous à une section « ref » : elle ressemble à peu près au graphique suivant. Notez comment ses enregistrements sont ordonnés lexicographiquement à l'intérieur des blocs, mais aussi entre différents blocs.",[12,782,783],{},[747,784],{"alt":785,"src":786},"bloc de référence non compressé","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675179/Blog/Content%20Images/Frame_2_-_Ref_block_uncompressed.svg",[12,788,789],{},"Maintenant que vous disposez de ces informations, vous pouvez localiser un enregistrement en suivant les étapes suivantes :",[791,792,793,796],"ol",{},[26,794,795],{},"Effectuez une recherche par dichotomie sur les blocs en regardant les clés de leurs premiers enregistrements respectifs, ce qui permet d'identifier le bloc qui doit contenir l'enregistrement.",[26,797,798],{},"Effectuez une recherche linéaire sur les enregistrements de ce bloc.",[12,800,801],{},"Ces deux étapes sont encore quelque peu inefficaces. S'il y a beaucoup de blocs, vous devrez peut-être effectuer une lecture logarithmique d'un bon nombre d'entre eux au cours de la recherche par dichotomie pour trouver celui que vous recherchez. Et lorsque les blocs contiennent de nombreux enregistrements, une recherche linéaire doit potentiellement tous les lire.",[12,803,804],{},"Le format « reftable » intègre des mécanismes supplémentaires pour résoudre ces problèmes de performance. Nous les mentionnerons dans les prochaines sections.",[806,807,809],"h3",{"id":808},"compression-de-préfixe","Compression de préfixe",[12,811,812,813,816],{},"Comme vous l'avez peut-être remarqué, toutes les clés d'enregistrement partagent le même préfixe ",[73,814,815],{},"refs/",". C'est une norme établie dans Git :",[23,818,819,825],{},[26,820,821,822,553],{},"Toutes les branches commencent par ",[73,823,824],{},"refs/heads/",[26,826,827,828,553],{},"Toutes les étiquettes (« tags ») commencent par ",[73,829,830],{},"refs/tags/",[12,832,833],{},"Par conséquent, il est très probable que les enregistrements suivants partagent une partie importante du préfixe de leur clé. C'est une bonne occasion d'économiser de l'espace de stockage précieux. Comme nous savons que la plupart des clés partagent un préfixe commun, il est logique d'utiliser ce dernier à des fins d'optimisation.",[12,835,836,837,757,840,843,844,847,848,850,851,853,854,553],{},"Celle-ci passe par la compression de préfixe. Chaque enregistrement encode une longueur de préfixe qui indique au processus qui lit les tables le nombre d'octets à réutiliser à partir de la clé de l'enregistrement précédent. Si vous avez deux enregistrements, ",[73,838,839],{},"refs/heads/a",[73,841,842],{},"refs/heads/b",", ce dernier peut être encodé en spécifiant une longueur de préfixe de 11, puis en stockant uniquement le suffixe ",[73,845,846],{},"b",". Le processus qui lit les tables prendra alors les 11 premiers octets de ",[73,849,839],{},", c'est-à-dire ",[73,852,824],{},", et y ajoutera le suffixe ",[73,855,846],{},[12,857,858],{},[747,859],{"alt":860,"src":861},"compression de préfixe","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675179/Blog/Content%20Images/Frame_3_-_Ref_block_prefix_compression.svg",[806,863,865],{"id":864},"restart-points","« Restart points »",[12,867,868],{},"Comme expliqué précédemment et d'après vos connaissances actuelles du format « reftable », une recherche linéaire constitue la meilleure façon de chercher une référence dans un bloc, car la longueur des enregistrements n'est pas fixe. Il est donc impossible de savoir où les enregistrements devraient commencer sans parcourir l'intégralité du bloc depuis le début. En outre, même si les enregistrements étaient de longueur fixe, il ne serait pas possible de rechercher au milieu d'un bloc, car la compression de préfixe nous oblige également à lire les enregistrements précédents.",[12,870,871],{},"Une recherche linéaire serait assez inefficace, dans la mesure où les blocs peuvent contenir des centaines, voire des milliers d'enregistrements. Pour résoudre ce problème, le format « reftable » encode des « restart points » dans chaque bloc. Les « restart points » sont des enregistrements non compressés où la compression de préfixe est réinitialisée. Par conséquent, les enregistrements des « restart points » contiennent toujours leur clé complète. Il devient donc possible de rechercher et de lire directement l'enregistrement, sans avoir à lire les enregistrements précédents. Ces « restart points » sont répertoriés dans le footer de chaque bloc.",[12,873,874,875,879],{},"Grâce à ces informations, vous pouvez maintenant éviter d'effectuer une recherche linéaire sur le bloc. Effectuez plutôt une recherche par dichotomie sur les « restart points » en cherchant le premier « restart point » dont la clé est lexicographiquement supérieure à la clé recherchée. Il s'ensuit que l'enregistrement que vous recherchez doit être situé dans la section s'étendant entre le « restart point » ",[876,877,878],"em",{},"précédent"," et celui identifié.",[12,881,882],{},"La procédure initiale pour rechercher un enregistrement (recherche par dichotomie du bloc, recherche linéaire de l'enregistrement) est donc la suivante :",[791,884,885,888,891],{},[26,886,887],{},"Effectuez une recherche par dichotomie sur les blocs, pour identifier celui qui doit contenir l'enregistrement.",[26,889,890],{},"Effectuez une recherche par dichotomie sur les « restart points », en identifiant la sous-section du bloc qui doit contenir l'enregistrement.",[26,892,893],{},"Effectuez une recherche linéaire sur les enregistrements de cette sous-section.",[12,895,896],{},[747,897],{"alt":898,"src":899},"Recherche linéaire pour un enregistrement","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675179/Blog/Content%20Images/Frame_4_-_Restart_points.svg",[806,901,903],{"id":902},"index","Index",[12,905,906],{},"Bien que la recherche d'enregistrements à l'intérieur d'un bloc soit désormais raisonnablement efficace, ce n'est pas le cas pour l'identification du bloc spécifique. Une recherche par dichotomie peut être relativement performante sur quelques blocs, mais les dépôts contenant des millions de références peuvent comporter des centaines, voire des milliers de blocs. En l'absence d'une structure de données supplémentaire visant à minimiser les accès au disque, chaque recherche de bloc pourrait entraîner en moyenne un nombre important d'accès au disque.",[12,908,909],{},"Pour éviter cette situation, chaque section peut être suivie d'une section d'indexation qui fournit un moyen efficace de rechercher un bloc. Chaque enregistrement d'index contient les informations suivantes :",[23,911,912,915],{},[26,913,914],{},"L'emplacement du bloc qu'il indexe.",[26,916,917],{},"La clé du dernier enregistrement du bloc qu'il indexe.",[12,919,920],{},"Pour trois blocs ou moins, une recherche par dichotomie nécessite toujours, au plus, deux lectures de disque pour trouver le bloc cible souhaité. Le nombre de lectures est le même pour un index : une pour lire l'index et une pour lire le bloc souhaité. Par conséquent, les index ne sont écrits que lorsqu'ils évitent de fait plusieurs lectures, ce qui est le cas lorsque quatre blocs ou plus sont indexés.",[12,922,923],{},"La question se pose alors de savoir ce qu'il se passe lorsque l'index lui-même devient si grand qu'il s'étend sur plusieurs blocs. Vous l'avez peut-être deviné : nous écrivons un nouvel index qui indexe l'index. Ces index à plusieurs niveaux ne deviennent vraiment nécessaires que lorsque vos dépôts contiennent des centaines de milliers de références.",[12,925,926],{},"À l'aide de ces index, vous pouvez désormais accélérer la recherche d'enregistrements :",[791,928,929,940,943],{},[26,930,931,932],{},"Déterminez s'il existe un index en consultant le footer de la table.\n",[23,933,934,937],{},[26,935,936],{},"Si c'est le cas, effectuez une recherche par dichotomie dans l'index pour trouver le bloc souhaité. Ce bloc peut pointer vers un bloc d'index, auquel cas il vous faut répéter l'opération jusqu'à atteindre un enregistrement du type souhaité.",[26,938,939],{},"Dans le cas contraire, effectuez une recherche par dichotomie dans les blocs comme auparavant.",[26,941,942],{},"Effectuez une recherche par dichotomie sur les « restart points » pour identifier la sous-section du bloc qui doit contenir l'enregistrement.",[26,944,893],{},[42,946,948],{"id":947},"tables-multiples","Tables multiples",[12,950,951,952,955,956,958],{},"Jusqu'à présent, nous n'avons discuté que de la façon de lire une table ",[876,953,954],{},"unique",". Comme l'indique le nom ",[73,957,635],{},", votre base de données « reftable » peut contenir une liste de tables.",[12,960,961,962,964],{},"Chaque fois que vous mettez à jour une référence dans votre dépôt, une nouvelle table est créée et ajoutée à ",[73,963,635],{},". Vous obtiendrez donc plusieurs tables, comme suit :",[103,966,968],{"className":105,"code":967,"language":107,"meta":108,"style":108},"$ tree .git/reftable/\n.git/reftable/\n├── 0x000000000001-0x000000000007-8dcd8a77.ref\n├── 0x000000000008-0x000000000008-30e0f6f6.ref\n└── tables.list\n\n$ cat .git/reftable/tables.list\n0x000000000001-0x000000000007-8dcd8a77.ref\n0x000000000008-0x000000000008-30e0f6f6.ref\n",[73,969,970,979,983,990,997,1003,1007,1015,1020],{"__ignoreMap":108},[112,971,972,974,976],{"class":114,"line":115},[112,973,119],{"class":118},[112,975,354],{"class":122},[112,977,978],{"class":122}," .git/reftable/\n",[112,980,981],{"class":114,"line":132},[112,982,588],{"class":118},[112,984,985,987],{"class":114,"line":152},[112,986,367],{"class":118},[112,988,989],{"class":122}," 0x000000000001-0x000000000007-8dcd8a77.ref\n",[112,991,992,994],{"class":114,"line":166},[112,993,367],{"class":118},[112,995,996],{"class":122}," 0x000000000008-0x000000000008-30e0f6f6.ref\n",[112,998,999,1001],{"class":114,"line":173},[112,1000,414],{"class":118},[112,1002,433],{"class":122},[112,1004,1005],{"class":114,"line":180},[112,1006,170],{"emptyLinePlaceholder":169},[112,1008,1009,1011,1013],{"class":114,"line":191},[112,1010,119],{"class":118},[112,1012,185],{"class":122},[112,1014,614],{"class":122},[112,1016,1017],{"class":114,"line":200},[112,1018,1019],{"class":118},"0x000000000001-0x000000000007-8dcd8a77.ref\n",[112,1021,1022],{"class":114,"line":205},[112,1023,1024],{"class":118},"0x000000000008-0x000000000008-30e0f6f6.ref\n",[12,1026,1027],{},"La lecture de l'état réel d'un dépôt nous oblige à fusionner ces multiples tables en une seule table virtuelle.",[12,1029,1030],{},"Vous vous demandez peut-être comment le format « reftable » connaît la valeur la plus récente d'une référence donnée, si une table est créée pour chaque mise à jour de référence et que la même référence est mise à jour plusieurs fois. Intuitivement, on pourrait supposer que la valeur serait celle de la table la plus récente contenant la référence.",[12,1032,1033],{},"En réalité, chaque enregistrement a un index de mise à jour qui encode la « priorisation » d'un enregistrement. Par exemple, s'il existe deux enregistrements pour le même nom de référence, celui qui a l'index de mise à jour le plus élevé remplace celui qui a l'index de mise à jour le plus bas.",[12,1035,1036,1037,1040],{},"Ces index de mise à jour sont visibles dans la structure de fichiers ci-dessus. Les longues chaînes hexagonales (par exemple ",[73,1038,1039],{},"0x000000000001",") sont les index de mise à jour. L'index de mise à jour minimum contenu dans la table se trouve dans la partie gauche de son nom de fichier et l'index de mise à jour maximum dans la partie droite.",[12,1042,1043,1044,1049],{},"Le merge des tables se fait ensuite via une ",[16,1045,1048],{"href":1046,"rel":1047},"https://fr.wikipedia.org/wiki/File_de_priorit%C3%A9",[],"file d'attente de priorisation"," qui est triée par clé d’enregistrement ainsi que son index de mise à jour. Imaginez que vous voulez parcourir tous les enregistrements de références. Vous devez suivre les étapes suivantes :",[791,1051,1052],{},[26,1053,1054],{},"Pour chaque table, ajoutez son premier enregistrement à la file d'attente de priorisation.",[12,1056,1057],{},[747,1058],{"alt":1059,"src":1060},"Ajout du premier enregistrement à la file d'attente de priorisation","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675179/Blog/Content%20Images/Frame_5_-_Priority_queue_1.svg",[791,1062,1063],{"start":132},[26,1064,1065],{},"Récupérez et retirez de la file d'attente l'enregistrement en tête de la file. Comme la file d'attente est triée par index de mise à jour, cet enregistrement doit être la version la plus récente. Ajoutez l'enregistrement suivant de la table de cet enregistrement à la file d'attente de priorisation.",[12,1067,1068],{},[747,1069],{"alt":1070,"src":1071},"Définition de la tête de la file d'attente de priorisation","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675179/Blog/Content%20Images/Frame_6_-_Priority_queue_2.svg",[791,1073,1074],{"start":152},[26,1075,1076],{},"Retirez tous les enregistrements de la file d'attente qui ont la même clé que l’enregistrement récupéré. Ces enregistrements sont dépassés et ne seront pas utilisés. Pour chaque table pour laquelle vous supprimez des enregistrements, ajoutez l'enregistrement suivant à la file d'attente de priorisation.",[12,1078,1079,1083],{},[747,1080],{"alt":1081,"src":1082},"Dépôt de tous les enregistrements de la file qui ont le même nom","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675179/Blog/Content%20Images/Frame_7_-_Priority_queue_3.svg","\nVous pouvez maintenant répéter les étapes ci-dessus pour lire les enregistrements pour d'autres clés.",[12,1085,1086],{},"Les tables peuvent contenir des enregistrements spéciaux « tombstone » qui marquent un enregistrement supprimé. Vous pouvez ainsi supprimer des enregistrements sans avoir à réécrire toutes les tables afin qu'elles ne contiennent plus ces enregistrements.",[806,1088,1090],{"id":1089},"compactage-automatique","Compactage automatique",[12,1092,1093,1094,1096],{},"La file d'attente de priorisation a beau être un concept simple, elle ne parviendrait pas à fusionner efficacement des centaines de tables, ni même des dizaines. S'il est vrai que chaque mise à jour de vos références ajoute une nouvelle table à votre fichier ",[73,1095,635],{},", ce n'est pas tout.",[12,1098,1099,1100,1105,1106,1109,1110,1113],{},"Le compactage automatique entre ici en scène : lorsqu'une nouvelle table a été ajoutée à la liste des tables, le backend « reftable » vérifie si certaines des tables doivent être fusionnées. Ce processus utilise une méthode simple : nous vérifions que les tailles de fichiers de la liste des tables forment une ",[16,1101,1104],{"href":1102,"rel":1103},"https://en.wikipedia.org/wiki/Geometric_progression",[],"séquence géométrique",". Chaque table ",[73,1107,1108],{},"n"," doit être au moins deux fois plus grande que la table suivante la plus récente ",[73,1111,1112],{},"n + 1",". Si cette séquence géométrique n'est pas respectée, le backend compacte les tables afin de restaurer la séquence géométrique.",[12,1115,1116],{},"Ce processus aboutit à des structures de ce type :",[103,1118,1120],{"className":105,"code":1119,"language":107,"meta":108,"style":108},"$ du --apparent-size .git/reftable/*\n429    .git/reftable/0x000000000001-0x00000000bd7c-d9819000.ref\n101    .git/reftable/0x00000000bd7d-0x00000000c5ac-c34b88a4.ref\n32    .git/reftable/0x00000000c5ad-0x00000000cc6c-60391f53.ref\n8    .git/reftable/0x00000000cc6d-0x00000000cdc1-61c30db1.ref\n3    .git/reftable/0x00000000cdc2-0x00000000ce67-d9b55a96.ref\n1    .git/reftable/0x00000000ce68-0x00000000ce6b-44721696.ref\n1    .git/reftable/tables.list\n",[73,1121,1122,1138,1146,1154,1162,1170,1178,1186],{"__ignoreMap":108},[112,1123,1124,1126,1129,1132,1135],{"class":114,"line":115},[112,1125,119],{"class":118},[112,1127,1128],{"class":122}," du",[112,1130,1131],{"class":142}," --apparent-size",[112,1133,1134],{"class":122}," .git/reftable/",[112,1136,1137],{"class":142},"*\n",[112,1139,1140,1143],{"class":114,"line":132},[112,1141,1142],{"class":118},"429",[112,1144,1145],{"class":122},"    .git/reftable/0x000000000001-0x00000000bd7c-d9819000.ref\n",[112,1147,1148,1151],{"class":114,"line":152},[112,1149,1150],{"class":118},"101",[112,1152,1153],{"class":122},"    .git/reftable/0x00000000bd7d-0x00000000c5ac-c34b88a4.ref\n",[112,1155,1156,1159],{"class":114,"line":166},[112,1157,1158],{"class":118},"32",[112,1160,1161],{"class":122},"    .git/reftable/0x00000000c5ad-0x00000000cc6c-60391f53.ref\n",[112,1163,1164,1167],{"class":114,"line":173},[112,1165,1166],{"class":118},"8",[112,1168,1169],{"class":122},"    .git/reftable/0x00000000cc6d-0x00000000cdc1-61c30db1.ref\n",[112,1171,1172,1175],{"class":114,"line":180},[112,1173,1174],{"class":118},"3",[112,1176,1177],{"class":122},"    .git/reftable/0x00000000cdc2-0x00000000ce67-d9b55a96.ref\n",[112,1179,1180,1183],{"class":114,"line":191},[112,1181,1182],{"class":118},"1",[112,1184,1185],{"class":122},"    .git/reftable/0x00000000ce68-0x00000000ce6b-44721696.ref\n",[112,1187,1188,1190],{"class":114,"line":200},[112,1189,1182],{"class":118},[112,1191,1192],{"class":122},"    .git/reftable/tables.list\n",[12,1194,1195,1196,1199],{},"Notez que la propriété ",[73,1197,1198],{},"size(n) > size(n+1) * 2"," est respectée pour chaque table.",[12,1201,1202,1203,1206],{},"L'une des conséquences du compactage automatique est la maintenance automatique du backend « reftable ». Il n'est plus nécessaire d'exécuter ",[73,1204,1205],{},"git pack-refs"," dans un dépôt.",[42,1208,1210],{"id":1209},"vous-souhaitez-en-savoir-plus","Vous souhaitez en savoir plus ?",[12,1212,1213,1214,1219],{},"À présent, le fonctionnement du nouveau format « reftable » ne devrait plus avoir de secret pour vous. Si vous souhaitez approfondir vos connaissances, vous pouvez consulter la ",[16,1215,1218],{"href":1216,"rel":1217},"https://git-scm.com/docs/reftable",[],"documentation technique"," fournie par le projet Git.",[1221,1222,1223],"blockquote",{},[12,1224,1225,1226,1231,1232,1238,1239,1245],{},"Lisez notre ",[16,1227,1230],{"href":1228,"rel":1229},"https://about.gitlab.com/blog/whats-new-in-git-2-45-0/",[],"récapitulatif sur Git 2.45.0",", ",[16,1233,1237],{"href":1234,"rel":1235,"title":1236},"https://about.gitlab.com/fr-fr/blog/whats-new-in-git-2-46-0/",[],"Nouveautés Git 2.46.0","Git 2.46.0"," et Git ",[16,1240,1244],{"href":1241,"rel":1242,"title":1243},"https://about.gitlab.com/fr-fr/blog/whats-new-in-git-2-47-0/",[],"Nouveautés Git 2.47.0","2.47.0"," pour découvrir les autres points forts de cette version.",[1247,1248,1249],"style",{},"html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":108,"searchDepth":132,"depth":132,"links":1251},[1252,1253,1254,1259,1262],{"id":44,"depth":132,"text":45},{"id":275,"depth":132,"text":276},{"id":722,"depth":132,"text":723,"children":1255},[1256,1257,1258],{"id":808,"depth":152,"text":809},{"id":864,"depth":152,"text":865},{"id":902,"depth":152,"text":903},{"id":947,"depth":132,"text":948,"children":1260},[1261],{"id":1089,"depth":152,"text":1090},{"id":1209,"depth":132,"text":1210},"open-source","2024-05-30","Dans la version 2.45.0 de Git, GitLab a introduit le backend « reftable », révolutionnant ainsi le stockage des références. Découvrez en détail le fonctionnement de ce nouveau format.","md",null,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664595/Blog/Hero%20Images/blog-image-template-1800x945__9_.png",{},"/fr-fr/blog/a-beginners-guide-to-the-git-reftable-format",{"title":5,"description":1265,"ogTitle":5,"ogDescription":1265,"noIndex":1272,"ogImage":1268,"ogUrl":1273,"ogSiteName":1274,"ogType":1275,"canonicalUrls":1273},false,"https://about.gitlab.com/blog/a-beginners-guide-to-the-git-reftable-format","https://about.gitlab.com","article","a-beginners-guide-to-the-git-reftable-format","fr-fr/blog/a-beginners-guide-to-the-git-reftable-format",[1279,1280,1281,1282],"git","tutorial","open source","performance","BlogPost","2024-12-19","pkyXZVhU-FuSSxhubIgcVpsNk4Av29p95gAcmBkbq3o",{"logo":1287,"freeTrial":1292,"sales":1297,"login":1302,"items":1307,"search":1636,"minimal":1672,"duo":1691,"switchNav":1700,"pricingDeployment":1711},{"config":1288},{"href":1289,"dataGaName":1290,"dataGaLocation":1291},"/fr-fr/","gitlab logo","header",{"text":1293,"config":1294},"Commencer un essai gratuit",{"href":1295,"dataGaName":1296,"dataGaLocation":1291},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/fr-fr&glm_content=default-saas-trial/","free trial",{"text":1298,"config":1299},"Demander une démo",{"href":1300,"dataGaName":1301,"dataGaLocation":1291},"/fr-fr/sales/?contact-topic=request-demo","sales",{"text":1303,"config":1304},"Connexion",{"href":1305,"dataGaName":1306,"dataGaLocation":1291},"https://gitlab.com/users/sign_in/","sign in",[1308,1337,1439,1444,1558,1614],{"text":1309,"config":1310,"menu":1312},"Plateforme",{"dataNavLevelOne":1311},"platform",{"type":1313,"columns":1314},"cards",[1315,1321,1329],{"title":1309,"description":1316,"link":1317},"La plateforme d'orchestration intelligente pour le DevSecOps",{"text":1318,"config":1319},"Explorer notre plateforme",{"href":1320,"dataGaName":1311,"dataGaLocation":1291},"/fr-fr/platform/",{"title":1322,"description":1323,"link":1324},"GitLab Duo Agent Platform","L'IA agentique pour l'ensemble du cycle de développement logiciel",{"text":1325,"config":1326},"Découvrir GitLab Duo",{"href":1327,"dataGaName":1328,"dataGaLocation":1291},"/fr-fr/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":1330,"description":1331,"link":1332},"Pourquoi GitLab ?","Découvrez les principales raisons pour lesquelles les entreprises choisissent GitLab",{"text":1333,"config":1334},"En savoir plus",{"href":1335,"dataGaName":1336,"dataGaLocation":1291},"/fr-fr/why-gitlab/","why gitlab",{"text":1338,"left":169,"config":1339,"menu":1341},"Produit",{"dataNavLevelOne":1340},"solutions",{"type":1342,"link":1343,"columns":1347,"feature":1418},"lists",{"text":1344,"config":1345},"Voir toutes les solutions",{"href":1346,"dataGaName":1340,"dataGaLocation":1291},"/fr-fr/solutions/",[1348,1373,1396],{"title":1349,"description":1350,"link":1351,"items":1356},"Automatisation","CI/CD et automatisation pour accélérer le déploiement",{"config":1352},{"icon":1353,"href":1354,"dataGaName":1355,"dataGaLocation":1291},"AutomatedCodeAlt","/fr-fr/solutions/delivery-automation/","automated software delivery",[1357,1361,1364,1369],{"text":1358,"config":1359},"CI/CD",{"href":1360,"dataGaLocation":1291,"dataGaName":1358},"/fr-fr/solutions/continuous-integration/",{"text":1322,"config":1362},{"href":1327,"dataGaLocation":1291,"dataGaName":1363},"gitlab duo agent platform - product menu",{"text":1365,"config":1366},"Gestion du code source",{"href":1367,"dataGaLocation":1291,"dataGaName":1368},"/fr-fr/solutions/source-code-management/","Source Code Management",{"text":1370,"config":1371},"Livraison de logiciels automatisée",{"href":1354,"dataGaLocation":1291,"dataGaName":1372},"Automated software delivery",{"title":1374,"description":1375,"link":1376,"items":1381},"Sécurité","Livrez du code plus rapidement sans compromettre la sécurité",{"config":1377},{"href":1378,"dataGaName":1379,"dataGaLocation":1291,"icon":1380},"/fr-fr/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[1382,1386,1391],{"text":1383,"config":1384},"Tests de sécurité des applications",{"href":1378,"dataGaName":1385,"dataGaLocation":1291},"Application security testing",{"text":1387,"config":1388},"Sécurité de la chaîne d'approvisionnement logicielle",{"href":1389,"dataGaLocation":1291,"dataGaName":1390},"/fr-fr/solutions/supply-chain/","Software supply chain security",{"text":1392,"config":1393},"Conformité logicielle",{"href":1394,"dataGaName":1395,"dataGaLocation":1291},"/fr-fr/solutions/software-compliance/","software compliance",{"title":1397,"link":1398,"items":1403},"Mesures",{"config":1399},{"icon":1400,"href":1401,"dataGaName":1402,"dataGaLocation":1291},"DigitalTransformation","/fr-fr/solutions/visibility-measurement/","visibility and measurement",[1404,1408,1413],{"text":1405,"config":1406},"Visibilité et mesures",{"href":1401,"dataGaLocation":1291,"dataGaName":1407},"Visibility and Measurement",{"text":1409,"config":1410},"Gestion de la chaîne de valeur",{"href":1411,"dataGaLocation":1291,"dataGaName":1412},"/fr-fr/solutions/value-stream-management/","Value Stream Management",{"text":1414,"config":1415},"Analyses et informations",{"href":1416,"dataGaLocation":1291,"dataGaName":1417},"/fr-fr/solutions/analytics-and-insights/","Analytics and insights",{"title":1419,"type":1342,"items":1420},"GitLab",[1421,1427,1433],{"text":1422,"config":1423},"Entreprises",{"icon":1424,"href":1425,"dataGaLocation":1291,"dataGaName":1426},"Building","/fr-fr/enterprise/","enterprise",{"text":1428,"config":1429},"Pour les PME",{"icon":1430,"href":1431,"dataGaLocation":1291,"dataGaName":1432},"Work","/fr-fr/small-business/","small business",{"text":1434,"config":1435},"Pour le secteur public",{"icon":1436,"href":1437,"dataGaLocation":1291,"dataGaName":1438},"Organization","/fr-fr/solutions/public-sector/","public sector",{"text":1440,"config":1441},"Tarifs",{"href":1442,"dataGaName":1443,"dataGaLocation":1291,"dataNavLevelOne":1443},"/fr-fr/pricing/","pricing",{"text":1445,"config":1446,"menu":1448},"Ressources",{"dataNavLevelOne":1447},"resources",{"type":1342,"link":1449,"columns":1453,"feature":1547},{"text":1450,"config":1451},"Afficher toutes les ressources",{"href":1452,"dataGaName":1447,"dataGaLocation":1291},"/fr-fr/resources/",[1454,1487,1514],{"title":1455,"items":1456},"Premiers pas",[1457,1462,1467,1472,1477,1482],{"text":1458,"config":1459},"Installation",{"href":1460,"dataGaName":1461,"dataGaLocation":1291},"/fr-fr/install/","install",{"text":1463,"config":1464},"Guides de démarrage",{"href":1465,"dataGaName":1466,"dataGaLocation":1291},"/fr-fr/get-started/","quick setup checklists",{"text":1468,"config":1469},"Apprentissage",{"href":1470,"dataGaLocation":1291,"dataGaName":1471},"https://university.gitlab.com/","learn",{"text":1473,"config":1474},"Documentation",{"href":1475,"dataGaName":1476,"dataGaLocation":1291},"https://docs.gitlab.com/","product documentation",{"text":1478,"config":1479},"Vidéos sur les bonnes pratiques",{"href":1480,"dataGaName":1481,"dataGaLocation":1291},"/fr-fr/getting-started-videos/","best practice videos",{"text":1483,"config":1484},"Intégrations",{"href":1485,"dataGaName":1486,"dataGaLocation":1291},"/fr-fr/integrations/","integrations",{"title":1488,"items":1489},"Découvrir",[1490,1495,1500,1505,1509],{"text":1491,"config":1492},"Témoignages clients",{"href":1493,"dataGaName":1494,"dataGaLocation":1291},"/fr-fr/customers/","customer success stories",{"text":1496,"config":1497},"Blog",{"href":1498,"dataGaName":1499,"dataGaLocation":1291},"/fr-fr/blog/","blog",{"text":1501,"config":1502},"Demo Hub",{"href":1503,"dataGaName":1504,"dataGaLocation":1291},"/fr-fr/demo-hub/","demo hub",{"text":1506,"config":1507},"The Source",{"href":1508,"dataGaName":1499,"dataGaLocation":1291},"/fr-fr/the-source/",{"text":1510,"config":1511},"Travail à distance",{"href":1512,"dataGaName":1513,"dataGaLocation":1291},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":1515,"items":1516},"Connecter",[1517,1522,1527,1532,1537,1542],{"text":1518,"config":1519},"Services GitLab",{"href":1520,"dataGaName":1521,"dataGaLocation":1291},"/fr-fr/services/","services",{"text":1523,"config":1524},"Contribuer",{"href":1525,"dataGaName":1526,"dataGaLocation":1291},"https://contributors.gitlab.com","contribute",{"text":1528,"config":1529},"Communauté",{"href":1530,"dataGaName":1531,"dataGaLocation":1291},"/community/","community",{"text":1533,"config":1534},"Forum",{"href":1535,"dataGaName":1536,"dataGaLocation":1291},"https://forum.gitlab.com/","forum",{"text":1538,"config":1539},"Événements",{"href":1540,"dataGaName":1541,"dataGaLocation":1291},"/events/","events",{"text":1543,"config":1544},"Partenaires",{"href":1545,"dataGaName":1546,"dataGaLocation":1291},"/fr-fr/partners/","partners",{"config":1548,"title":1551,"text":1552,"link":1553},{"background":1549,"textColor":1550},"url('https://res.cloudinary.com/about-gitlab-com/image/upload/v1777322348/qpq8yrgn8knii57omj0c.png')","#000","Nouveautés de GitLab","Découvrez les dernières fonctionnalités et améliorations.",{"text":1554,"config":1555},"Lire les articles les plus récents",{"href":1556,"dataGaName":1557,"dataGaLocation":1291},"/fr-fr/whats-new/","whats new",{"text":1559,"config":1560,"menu":1562},"Société",{"dataNavLevelOne":1561},"company",{"type":1342,"columns":1563},[1564],{"items":1565},[1566,1571,1577,1579,1584,1589,1594,1599,1604,1609],{"text":1567,"config":1568},"À propos",{"href":1569,"dataGaName":1570,"dataGaLocation":1291},"/fr-fr/company/","about",{"text":1572,"config":1573,"footerGa":1576},"Carrières",{"href":1574,"dataGaName":1575,"dataGaLocation":1291},"/jobs/","jobs",{"dataGaName":1575},{"text":1538,"config":1578},{"href":1540,"dataGaName":1541,"dataGaLocation":1291},{"text":1580,"config":1581},"Leadership",{"href":1582,"dataGaName":1583,"dataGaLocation":1291},"/company/team/e-group/","leadership",{"text":1585,"config":1586},"Manuel",{"href":1587,"dataGaName":1588,"dataGaLocation":1291},"https://handbook.gitlab.com/","handbook",{"text":1590,"config":1591},"Relations avec les investisseurs",{"href":1592,"dataGaName":1593,"dataGaLocation":1291},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":1595,"config":1596},"Trust Center",{"href":1597,"dataGaName":1598,"dataGaLocation":1291},"/fr-fr/security/","trust center",{"text":1600,"config":1601},"Centre pour la transparence de l'IA",{"href":1602,"dataGaName":1603,"dataGaLocation":1291},"/fr-fr/ai-transparency-center/","ai transparency center",{"text":1605,"config":1606},"Newsletter",{"href":1607,"dataGaName":1608,"dataGaLocation":1291},"/company/contact/#contact-forms","newsletter",{"text":1610,"config":1611},"Presse",{"href":1612,"dataGaName":1613,"dataGaLocation":1291},"/press/","press",{"text":1615,"config":1616,"menu":1617},"Nous contacter",{"dataNavLevelOne":1561},{"type":1342,"columns":1618},[1619],{"items":1620},[1621,1626,1631],{"text":1622,"config":1623},"Contacter l'équipe commerciale",{"href":1624,"dataGaName":1625,"dataGaLocation":1291},"/fr-fr/sales/","talk to sales",{"text":1627,"config":1628},"Assistance GitLab",{"href":1629,"dataGaName":1630,"dataGaLocation":1291},"https://support.gitlab.com/hc/en-us","support portal",{"text":1632,"config":1633},"Portail clients GitLab",{"href":1634,"dataGaName":1635,"dataGaLocation":1291},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":1637,"login":1638,"suggestions":1645},"Fermer",{"text":1639,"link":1640},"Pour rechercher des dépôts et des projets, connectez-vous à",{"text":1641,"config":1642},"GitLab.com",{"href":1305,"dataGaName":1643,"dataGaLocation":1644},"search login","search",{"text":1646,"default":1647},"Suggestions",[1648,1651,1656,1658,1663,1668],{"text":1322,"config":1649},{"href":1327,"dataGaName":1650,"dataGaLocation":1644},"GitLab Duo Agent Platform",{"text":1652,"config":1653},"Suggestions de code (IA)",{"href":1654,"dataGaName":1655,"dataGaLocation":1644},"/fr-fr/solutions/code-suggestions/","Code Suggestions (AI)",{"text":1358,"config":1657},{"href":1360,"dataGaName":1358,"dataGaLocation":1644},{"text":1659,"config":1660},"GitLab sur AWS",{"href":1661,"dataGaName":1662,"dataGaLocation":1644},"/fr-fr/partners/technology-partners/aws/","GitLab on AWS",{"text":1664,"config":1665},"GitLab sur Google Cloud",{"href":1666,"dataGaName":1667,"dataGaLocation":1644},"/fr-fr/partners/technology-partners/google-cloud-platform/","GitLab on Google Cloud",{"text":1669,"config":1670},"Pourquoi utiliser GitLab ?",{"href":1335,"dataGaName":1671,"dataGaLocation":1644},"Why GitLab?",{"freeTrial":1673,"mobileIcon":1678,"desktopIcon":1683,"secondaryButton":1686},{"text":1674,"config":1675},"Commencer votre essai gratuit",{"href":1676,"dataGaName":1296,"dataGaLocation":1677},"https://gitlab.com/-/trials/new/","nav",{"altText":1679,"config":1680},"Icône GitLab",{"src":1681,"dataGaName":1682,"dataGaLocation":1677},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":1679,"config":1684},{"src":1685,"dataGaName":1682,"dataGaLocation":1677},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":1687,"config":1688},"Commencer",{"href":1689,"dataGaName":1690,"dataGaLocation":1677},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/fr-fr/get-started/","get started",{"freeTrial":1692,"mobileIcon":1696,"desktopIcon":1698},{"text":1693,"config":1694},"En savoir plus sur GitLab Duo",{"href":1327,"dataGaName":1695,"dataGaLocation":1677},"gitlab duo",{"altText":1679,"config":1697},{"src":1681,"dataGaName":1682,"dataGaLocation":1677},{"altText":1679,"config":1699},{"src":1685,"dataGaName":1682,"dataGaLocation":1677},{"button":1701,"mobileIcon":1706,"desktopIcon":1708},{"text":1702,"config":1703},"/switch",{"href":1704,"dataGaName":1705,"dataGaLocation":1677},"#contact","switch",{"altText":1679,"config":1707},{"src":1681,"dataGaName":1682,"dataGaLocation":1677},{"altText":1679,"config":1709},{"src":1710,"dataGaName":1682,"dataGaLocation":1677},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":1712,"mobileIcon":1717,"desktopIcon":1719},{"text":1713,"config":1714},"Retour aux tarifs",{"href":1442,"dataGaName":1715,"dataGaLocation":1677,"icon":1716},"back to pricing","GoBack",{"altText":1679,"config":1718},{"src":1681,"dataGaName":1682,"dataGaLocation":1677},{"altText":1679,"config":1720},{"src":1685,"dataGaName":1682,"dataGaLocation":1677},{"title":1722,"button":1723,"config":1727},"GitLab Orbit est arrivé : la couche de contexte pour les agents d'IA.",{"text":1333,"config":1724},{"href":1725,"dataGaName":1726,"dataGaLocation":1291},"/fr-fr/gitlab-orbit/","orbit",{"layout":1728,"disabled":1272},"release",{"data":1730},{"text":1731,"source":1732,"edit":1738,"contribute":1743,"config":1747,"items":1752,"minimal":1960},"Git est une marque déposée de Software Freedom Conservancy et notre utilisation de « GitLab » est sous licence.",{"text":1733,"config":1734},"Afficher le code source de la page",{"href":1735,"dataGaName":1736,"dataGaLocation":1737},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":1739,"config":1740},"Modifier cette page",{"href":1741,"dataGaName":1742,"dataGaLocation":1737},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":1523,"config":1744},{"href":1745,"dataGaName":1746,"dataGaLocation":1737},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":1748,"facebook":1749,"youtube":1750,"linkedin":1751},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[1753,1799,1852,1895,1927],{"title":1440,"links":1754,"subMenu":1769},[1755,1759,1764],{"text":1756,"config":1757},"Voir les forfaits",{"href":1442,"dataGaName":1758,"dataGaLocation":1737},"view plans",{"text":1760,"config":1761},"GitLab Premium",{"href":1762,"dataGaName":1763,"dataGaLocation":1737},"/fr-fr/pricing/premium/","why premium",{"text":1765,"config":1766},"GitLab Ultimate",{"href":1767,"dataGaName":1768,"dataGaLocation":1737},"/fr-fr/pricing/ultimate/","why ultimate",[1770],{"title":1615,"links":1771},[1772,1774,1776,1779,1784,1789,1794],{"text":1622,"config":1773},{"href":1624,"dataGaName":1301,"dataGaLocation":1737},{"text":1627,"config":1775},{"href":1629,"dataGaName":1630,"dataGaLocation":1737},{"text":1777,"config":1778},"Portail clients",{"href":1634,"dataGaName":1635,"dataGaLocation":1737},{"text":1780,"config":1781},"Statut",{"href":1782,"dataGaName":1783,"dataGaLocation":1737},"https://status.gitlab.com/","status",{"text":1785,"config":1786},"Conditions d'utilisation",{"href":1787,"dataGaName":1788,"dataGaLocation":1737},"/terms/","terms of use",{"text":1790,"config":1791},"Politique de confidentialité",{"href":1792,"dataGaName":1793,"dataGaLocation":1737},"/fr-fr/privacy/","privacy statement",{"text":1795,"config":1796},"Gestion des cookies",{"dataGaName":1797,"dataGaLocation":1737,"id":1798,"isOneTrustButton":169},"cookie preferences","ot-sdk-btn",{"title":1338,"links":1800,"subMenu":1809},[1801,1805],{"text":1802,"config":1803},"Plateforme DevSecOps",{"href":1320,"dataGaName":1804,"dataGaLocation":1737},"devsecops platform",{"text":1806,"config":1807},"Développement assisté par l'IA",{"href":1327,"dataGaName":1808,"dataGaLocation":1737},"ai-assisted development",[1810],{"title":1811,"links":1812},"Thèmes",[1813,1817,1822,1827,1832,1837,1842,1847],{"text":1358,"config":1814},{"href":1815,"dataGaName":1816,"dataGaLocation":1737},"/fr-fr/topics/ci-cd/","cicd",{"text":1818,"config":1819},"GitOps",{"href":1820,"dataGaName":1821,"dataGaLocation":1737},"/fr-fr/topics/gitops/","gitops",{"text":1823,"config":1824},"DevOps",{"href":1825,"dataGaName":1826,"dataGaLocation":1737},"/fr-fr/topics/devops/","devops",{"text":1828,"config":1829},"Contrôle de version",{"href":1830,"dataGaName":1831,"dataGaLocation":1737},"/fr-fr/topics/version-control/","version control",{"text":1833,"config":1834},"DevSecOps",{"href":1835,"dataGaName":1836,"dataGaLocation":1737},"/fr-fr/topics/devsecops/","devsecops",{"text":1838,"config":1839},"Cloud-native",{"href":1840,"dataGaName":1841,"dataGaLocation":1737},"/fr-fr/topics/cloud-native/","cloud native",{"text":1843,"config":1844},"IA pour la programmation",{"href":1845,"dataGaName":1846,"dataGaLocation":1737},"/fr-fr/topics/devops/ai-for-coding/","ai for coding",{"text":1848,"config":1849},"IA agentique",{"href":1850,"dataGaName":1851,"dataGaLocation":1737},"/fr-fr/topics/agentic-ai/","agentic ai",{"title":1853,"links":1854},"Solutions",[1855,1858,1860,1865,1868,1871,1874,1877,1879,1882,1885,1890],{"text":1383,"config":1856},{"href":1378,"dataGaName":1857,"dataGaLocation":1737},"Application Security Testing",{"text":1370,"config":1859},{"href":1354,"dataGaName":1355,"dataGaLocation":1737},{"text":1861,"config":1862},"Développement Agile",{"href":1863,"dataGaName":1864,"dataGaLocation":1737},"/fr-fr/solutions/agile-delivery/","agile delivery",{"text":1365,"config":1866},{"href":1367,"dataGaName":1867,"dataGaLocation":1737},"source code management",{"text":1358,"config":1869},{"href":1360,"dataGaName":1870,"dataGaLocation":1737},"continuous integration & delivery",{"text":1409,"config":1872},{"href":1411,"dataGaName":1873,"dataGaLocation":1737},"value stream management",{"text":1818,"config":1875},{"href":1876,"dataGaName":1821,"dataGaLocation":1737},"/fr-fr/solutions/gitops/",{"text":1422,"config":1878},{"href":1425,"dataGaName":1426,"dataGaLocation":1737},{"text":1880,"config":1881},"PME",{"href":1431,"dataGaName":1432,"dataGaLocation":1737},{"text":1883,"config":1884},"Secteur public",{"href":1437,"dataGaName":1438,"dataGaLocation":1737},{"text":1886,"config":1887},"Éducation",{"href":1888,"dataGaName":1889,"dataGaLocation":1737},"/fr-fr/solutions/education/","education",{"text":1891,"config":1892},"Services financiers",{"href":1893,"dataGaName":1894,"dataGaLocation":1737},"/fr-fr/solutions/finance/","financial services",{"title":1445,"links":1896},[1897,1899,1901,1903,1906,1908,1911,1913,1915,1917,1919,1921,1923,1925],{"text":1458,"config":1898},{"href":1460,"dataGaName":1461,"dataGaLocation":1737},{"text":1463,"config":1900},{"href":1465,"dataGaName":1466,"dataGaLocation":1737},{"text":1468,"config":1902},{"href":1470,"dataGaName":1471,"dataGaLocation":1737},{"text":1473,"config":1904},{"href":1475,"dataGaName":1905,"dataGaLocation":1737},"docs",{"text":1496,"config":1907},{"href":1498,"dataGaName":1499,"dataGaLocation":1737},{"text":1909,"config":1910},"Nouveautés",{"href":1556,"dataGaName":1557,"dataGaLocation":1737},{"text":1491,"config":1912},{"href":1493,"dataGaName":1494,"dataGaLocation":1737},{"text":1510,"config":1914},{"href":1512,"dataGaName":1513,"dataGaLocation":1737},{"text":1518,"config":1916},{"href":1520,"dataGaName":1521,"dataGaLocation":1737},{"text":1523,"config":1918},{"href":1525,"dataGaName":1526,"dataGaLocation":1737},{"text":1528,"config":1920},{"href":1530,"dataGaName":1531,"dataGaLocation":1737},{"text":1533,"config":1922},{"href":1535,"dataGaName":1536,"dataGaLocation":1737},{"text":1538,"config":1924},{"href":1540,"dataGaName":1541,"dataGaLocation":1737},{"text":1543,"config":1926},{"href":1545,"dataGaName":1546,"dataGaLocation":1737},{"title":1559,"links":1928},[1929,1931,1933,1935,1937,1939,1944,1949,1951,1953,1955],{"text":1567,"config":1930},{"href":1569,"dataGaName":1561,"dataGaLocation":1737},{"text":1572,"config":1932},{"href":1574,"dataGaName":1575,"dataGaLocation":1737},{"text":1580,"config":1934},{"href":1582,"dataGaName":1583,"dataGaLocation":1737},{"text":1585,"config":1936},{"href":1587,"dataGaName":1588,"dataGaLocation":1737},{"text":1590,"config":1938},{"href":1592,"dataGaName":1593,"dataGaLocation":1737},{"text":1940,"config":1941},"Développement durable",{"href":1942,"dataGaName":1943,"dataGaLocation":1737},"/sustainability/","Sustainability",{"text":1945,"config":1946},"Diversité, inclusion et appartenance (DIB)",{"href":1947,"dataGaName":1948,"dataGaLocation":1737},"/fr-fr/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":1595,"config":1950},{"href":1597,"dataGaName":1598,"dataGaLocation":1737},{"text":1605,"config":1952},{"href":1607,"dataGaName":1608,"dataGaLocation":1737},{"text":1610,"config":1954},{"href":1612,"dataGaName":1613,"dataGaLocation":1737},{"text":1956,"config":1957},"Déclaration de transparence sur l'esclavage moderne",{"href":1958,"dataGaName":1959,"dataGaLocation":1737},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":1961},[1962,1964,1966],{"text":1785,"config":1963},{"href":1787,"dataGaName":1788,"dataGaLocation":1737},{"text":1795,"config":1965},{"dataGaName":1797,"dataGaLocation":1737,"id":1798,"isOneTrustButton":169},{"text":1790,"config":1967},{"href":1792,"dataGaName":1793,"dataGaLocation":1737},[1969],{"id":1970,"title":7,"body":1267,"config":1971,"content":1973,"description":1267,"extension":1977,"meta":1978,"navigation":169,"path":1979,"seo":1980,"stem":1981,"__hash__":1982},"blogAuthors/en-us/blog/authors/patrick-steinhardt.yml",{"template":1972},"BlogAuthor",{"name":7,"config":1974},{"headshot":1975,"ctfId":1976},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749661952/Blog/Author%20Headshots/pks-gitlab-headshot.png","pksgitlab","yml",{},"/en-us/blog/authors/patrick-steinhardt",{},"en-us/blog/authors/patrick-steinhardt","SV9Yd_vW69UbvntDP-SEOV9NKT_VwUAj5nfftf2ElSw",[1984,1992,1999],{"title":1985,"description":1986,"heroImage":1987,"category":1263,"date":1988,"authors":1989,"slug":1991,"externalUrl":1267},"Nouveautés de Git 2.55.0","Découvrez les nouveautés de Git 2.55 : commande fixup de git-history(1), daemon fsmonitor pour Linux, push vers des groupes de dépôts distants et plus encore.","https://res.cloudinary.com/about-gitlab-com/image/upload/f_auto,q_auto,c_lfill/v1782732487/ztwgrvlolpifo01vj8qc.png","2026-07-01",[1990],"Toon Claes","whats-new-in-git-2-55-0",{"title":1993,"description":1994,"heroImage":1995,"category":1263,"date":1996,"authors":1997,"slug":1998,"externalUrl":1267},"Nouveautés de Git 2.54.0","Découvrez les contributions à cette release de Git 2.54.0, notamment la nouvelle maintenance des dépôts, une nouvelle commande pour modifier l'historique des commits, le remplacement de git-sizer(1) et plus encore.","https://res.cloudinary.com/about-gitlab-com/image/upload/f_auto,q_auto,c_lfill/v1776711651/sj7xxyyuimlarswbyft5.png","2026-04-27",[7],"whats-new-in-git-2-54-0",{"title":2000,"description":2001,"heroImage":2002,"category":1263,"date":2003,"authors":2004,"slug":2006,"externalUrl":1267},"GitLab AI Hackathon 2026 : découvrez les gagnants","Près de 7 000 développeurs ont créé plus de 600 agents et flows d'IA sur GitLab Duo Agent Platform. Découvrez les gagnants et leurs projets.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1776457632/llddiylsgwuze0u1rjks.png","2026-04-22",[2005],"Nick Veenhof","gitlab-ai-hackathon-2026-meet-the-winners",{"promotions":2008},[2009,2023,2035,2047],{"id":2010,"categories":2011,"header":2013,"text":2014,"button":2015,"image":2020},"ai-modernization",[2012],"ai","L'IA tient-elle ses promesses à grande échelle ?","Le questionnaire ne prendra pas plus de 5 minutes.",{"text":2016,"config":2017},"Obtenez votre score de maturité IA",{"href":2018,"dataGaName":2019,"dataGaLocation":1499},"/fr-fr/assessments/ai-modernization-assessment/","modernization assessment",{"config":2021},{"src":2022},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":2024,"categories":2025,"header":2027,"text":2014,"button":2028,"image":2032},"devops-modernization",[2026,1836],"product","Vous contentez-vous de gérer des outils ou de livrer des innovations ?",{"text":2029,"config":2030},"Obtenez votre score de maturité DevOps",{"href":2031,"dataGaName":2019,"dataGaLocation":1499},"/fr-fr/assessments/devops-modernization-assessment/",{"config":2033},{"src":2034},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":2036,"categories":2037,"header":2039,"text":2014,"button":2040,"image":2044},"security-modernization",[2038],"security","Faut-il sacrifier la rapidité pour garantir la sécurité ?",{"text":2041,"config":2042},"Obtenez votre score de maturité en matière de sécurité",{"href":2043,"dataGaName":2019,"dataGaLocation":1499},"/fr-fr/assessments/security-modernization-assessment/",{"config":2045},{"src":2046},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":2048,"paths":2049,"header":2052,"text":2053,"button":2054,"image":2059},"github-azure-migration",[2050,2051],"migration-from-azure-devops-to-gitlab","integrating-azure-devops-scm-and-gitlab","Votre équipe est-elle prête pour la migration de GitHub vers Azure ?","GitHub a déjà commencé sa migration vers Azure. Découvrez ce que cela signifie pour vous.",{"text":2055,"config":2056},"Découvrez les différences entre GitLab et GitHub",{"href":2057,"dataGaName":2058,"dataGaLocation":1499},"/fr-fr/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":2060},{"src":2034},{"header":2062,"blurb":2063,"button":2064,"secondaryButton":2068},"Commencez à développer plus rapidement dès aujourd'hui","Découvrez ce que votre équipe peut accomplir avec la plateforme d'orchestration intelligente pour le DevSecOps.\n",{"text":1293,"config":2065},{"href":2066,"dataGaName":1296,"dataGaLocation":2067},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/fr-fr/","feature",{"text":1622,"config":2069},{"href":1624,"dataGaName":1301,"dataGaLocation":2067},1786803775694]