[{"data":1,"prerenderedAt":1822},["ShallowReactive",2],{"/de-de/blog/a-beginners-guide-to-the-git-reftable-format":3,"navigation-de-de":1038,"banner-de-de":1470,"footer-de-de":1478,"blog-post-authors-de-de-Patrick Steinhardt":1719,"blog-related-posts-de-de-a-beginners-guide-to-the-git-reftable-format":1734,"blog-promotions-de-de":1758,"next-steps-de-de":1812},{"id":4,"title":5,"authors":6,"body":8,"category":1015,"date":1016,"description":1017,"extension":1018,"externalUrl":1019,"faq":1019,"featured":144,"heroImage":1020,"meta":1021,"navigation":144,"path":1022,"seo":1023,"slug":1028,"stem":1029,"tags":1030,"template":1035,"updatedDate":1036,"__hash__":1037},"blogPosts/de-de/blog/a-beginners-guide-to-the-git-reftable-format.md","Der Anfängerleitfaden zum „reftable“-Format von Git",[7],"Patrick Steinhardt",{"type":9,"value":10,"toc":1002},"minimark",[11,22,38,41,56,61,64,67,89,92,100,107,110,222,226,233,327,334,379,382,385,410,417,456,459,473,476,524,530,534,537,554,561,578,581,589,592,598,601,610,613,616,621,628,642,645,668,673,677,680,683,691,694,705,711,715,718,726,729,732,735,740,748,755,759,769,775,821,824,827,830,837,846,851,857,862,868,873,879,882,885,889,895,912,915,960,967,974,978,987,998],[12,13,14,15,21],"p",{},"Bis vor Kurzem war das „files“-Format die einzige Möglichkeit in Git, Referenzen zu speichern. Mit der ",[16,17,20],"a",{"href":18,"rel":19},"https://about.gitlab.com/de-de/blog/whats-new-in-git-2-45-0/",[],"Version Git 2.45.0"," kann Git nun Referenzen im „reftable“-Format speichern. Dieses neue Format ist ein Binärformat, das deutlich komplexer als das alte “files” Format ist. Diese Komplexität ermöglicht es jedoch, einige Mängel des „files“-Formats zu beheben. Die Entwicklungsziele des „reftable“-Formats sind unter anderem folgende:",[23,24,25,29,32,35],"ul",{},[26,27,28],"li",{},"Die Suche nach einzelnen Referenzen und die Iterationen über zahlreichen Referenzen soll so effizient und schnell wie möglich sein.",[26,30,31],{},"Das konsistente Lesen von Referenzen soll unterstützt werden, sodass Git nie einen Zwischenzustand liest, wenn ein Update an mehreren Referenzen nur teilweise angewendet wurde.",[26,33,34],{},"Atomares Schreiben soll unterstützt werden, sodass die Aktualisierung von mehreren Referenzen nur entweder vollständig oder gar nicht möglich ist.",[26,36,37],{},"Effiziente Speicherung von Referenzen und Reflog-Einträgen.",[12,39,40],{},"In diesem Artikel kommen wir allen Feinheiten des „reftable“-Formats auf die Schliche und sehen uns genau an, wie es funktioniert.",[42,43,44],"blockquote",{},[12,45,46,50,51],{},[47,48,49],"strong",{},"Über 6,4 Mio. Builds pro Monat: So transformiert Siemens seine Softwareentwicklung mit GitLab"," Über 40.000 Entwickler(innen) bei Siemens nutzen GitLab, um weltweit zusammenzuarbeiten und jeden Monat mehr als 6,4 Millionen Software-Versionen automatisch bereitzustellen. Erfahre, wie eine offene DevOps-Kultur und eine zentrale Plattform die Effizienz und Sicherheit steigern. ",[16,52,55],{"href":53,"rel":54},"https://about.gitlab.com/de-de/customers/siemens/",[],"Erfolgsstory lesen",[57,58,60],"h2",{"id":59},"so-speichert-git-referenzen","So speichert Git Referenzen",[12,62,63],{},"Bevor wir uns die Details des „reftable“-Formats ansehen, fassen wir nochmals kurz zusammen, wie Git in der Vergangenheit Referenzen gespeichert hat. Wenn du damit bereits vertraut bist, kannst du gleich zum nächsten Abschnitt springen.",[12,65,66],{},"Ein Git-Repository enthält zwei wesentliche Datenstrukturen:",[23,68,69,77],{},[26,70,71,76],{},[16,72,75],{"href":73,"rel":74},"https://git-scm.com/book/en/v2/Git-Internals-Git-Objects",[],"Objekte",", die die eigentlichen Daten deines Repositorys enthalten. Dazu gehören Commits, die Verzeichnisstruktur und die Blobs, die deinen Quellcode enthalten. Objekte verweisen aufeinander und bilden so einen Objektgraphen. Außerdem hat jedes Objekt eine Objekt-ID, durch die es eindeutig identifiziert wird.",[26,78,79,80,84,85,88],{},"Referenzen wie Branches und Tags sind Wegweiser im Objektgraphen, sodass du Objekten Namen geben kannst, die einfacher zu merken sind, und verschiedene Wege deines Entwicklungsverlaufs nachverfolgen kannst. Ein Repository kann zum Beispiel einen ",[81,82,83],"code",{},"main","-Branch enthalten, der eine Referenz mit dem Namen ",[81,86,87],{},"refs/heads/main"," ist und auf einen bestimmten Commit zeigt.",[12,90,91],{},"Referenzen werden in der Referenzdatenbank gespeichert. Bis Git 2.45.0 gab es nur das Datenbankformat „files“. In diesem Format wird jede Referenz als einfache Datei gespeichert, die eines der folgenden Elemente enthält:",[23,93,94,97],{},[26,95,96],{},"Eine normale Referenz, die die Objekt-ID des Commits enthält, auf den sie zeigt.",[26,98,99],{},"Eine symbolische Referenz, die den Namen einer anderen Referenz enthält. Dies ist ähnlich wie ein symbolischer Link, der auf eine andere Datei zeigt.",[12,101,102,103,106],{},"In regelmäßigen Abständen werden diese Referenzen in eine einzige ",[81,104,105],{},"packed-refs","-Datei komprimiert, damit Referenzen effizienter durchsucht werden können.",[12,108,109],{},"Die folgenden Beispiele sollen eine Vorstellung davon geben, wie das „files“-Format funktioniert:",[111,112,117],"pre",{"className":113,"code":114,"language":115,"meta":116,"style":116},"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 ist eine symbolische Referenz, die auf refs/heads/main zeigt.\n$ cat .git/HEAD\nref: refs/heads/main\n\n# refs/heads/main ist eine normal Referenz, die auf einen Commit zeigt.\n$ cat .git/refs/heads/main\n6917c178cfc3c50215a82cf959204e9934af24c8\n\n# git-pack-refs(1) komprimiert diese Referenzen in eine packed-refs Datei.\n$ git pack-refs --all\n$ cat .git/packed-refs\n# pack-refs with: peeled fully-peeled sorted\n6917c178cfc3c50215a82cf959204e9934af24c8 refs/heads/main\n","shell","",[81,118,119,127,133,139,146,152,158,164,169,175,181,187,192,198,204,210,216],{"__ignoreMap":116},[120,121,124],"span",{"class":122,"line":123},"line",1,[120,125,126],{},"$ git init .\n",[120,128,130],{"class":122,"line":129},2,[120,131,132],{},"$ git commit --allow-empty --message \"Initial commit\"\n",[120,134,136],{"class":122,"line":135},3,[120,137,138],{},"[main (root-commit) 6917c17] Initial commit\n",[120,140,142],{"class":122,"line":141},4,[120,143,145],{"emptyLinePlaceholder":144},true,"\n",[120,147,149],{"class":122,"line":148},5,[120,150,151],{},"# HEAD ist eine symbolische Referenz, die auf refs/heads/main zeigt.\n",[120,153,155],{"class":122,"line":154},6,[120,156,157],{},"$ cat .git/HEAD\n",[120,159,161],{"class":122,"line":160},7,[120,162,163],{},"ref: refs/heads/main\n",[120,165,167],{"class":122,"line":166},8,[120,168,145],{"emptyLinePlaceholder":144},[120,170,172],{"class":122,"line":171},9,[120,173,174],{},"# refs/heads/main ist eine normal Referenz, die auf einen Commit zeigt.\n",[120,176,178],{"class":122,"line":177},10,[120,179,180],{},"$ cat .git/refs/heads/main\n",[120,182,184],{"class":122,"line":183},11,[120,185,186],{},"6917c178cfc3c50215a82cf959204e9934af24c8\n",[120,188,190],{"class":122,"line":189},12,[120,191,145],{"emptyLinePlaceholder":144},[120,193,195],{"class":122,"line":194},13,[120,196,197],{},"# git-pack-refs(1) komprimiert diese Referenzen in eine packed-refs Datei.\n",[120,199,201],{"class":122,"line":200},14,[120,202,203],{},"$ git pack-refs --all\n",[120,205,207],{"class":122,"line":206},15,[120,208,209],{},"$ cat .git/packed-refs\n",[120,211,213],{"class":122,"line":212},16,[120,214,215],{},"# pack-refs with: peeled fully-peeled sorted\n",[120,217,219],{"class":122,"line":218},17,[120,220,221],{},"6917c178cfc3c50215a82cf959204e9934af24c8 refs/heads/main\n",[57,223,225],{"id":224},"hochrangige-struktur-von-reftables","Hochrangige Struktur von reftables",[12,227,228,229,232],{},"Wenn du nun Git 2.45.0 oder eine neuere Version installiert hast, kannst du ein Repository mit dem „reftable“-Format erstellen, indem du den Switch ",[81,230,231],{},"--ref-format=reftable"," verwendest:",[111,234,236],{"className":113,"code":235,"language":115,"meta":116,"style":116},"$ git init --ref-format=reftable .Initialized empty Git repository in /tmp/repo/.git/\n$ git rev-parse --show-ref-format\nreftable\n\n# Irrelevante Dateien wurden für ein einfacheres Verständnis entfernt.\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",[81,237,238,243,248,253,257,262,267,272,277,282,287,292,297,302,307,312,317,321],{"__ignoreMap":116},[120,239,240],{"class":122,"line":123},[120,241,242],{},"$ git init --ref-format=reftable .Initialized empty Git repository in /tmp/repo/.git/\n",[120,244,245],{"class":122,"line":129},[120,246,247],{},"$ git rev-parse --show-ref-format\n",[120,249,250],{"class":122,"line":135},[120,251,252],{},"reftable\n",[120,254,255],{"class":122,"line":141},[120,256,145],{"emptyLinePlaceholder":144},[120,258,259],{"class":122,"line":148},[120,260,261],{},"# Irrelevante Dateien wurden für ein einfacheres Verständnis entfernt.\n",[120,263,264],{"class":122,"line":154},[120,265,266],{},"$ tree .git\n",[120,268,269],{"class":122,"line":160},[120,270,271],{},".git\n",[120,273,274],{"class":122,"line":166},[120,275,276],{},"├── config\n",[120,278,279],{"class":122,"line":171},[120,280,281],{},"├── HEAD\n",[120,283,284],{"class":122,"line":177},[120,285,286],{},"├── index\n",[120,288,289],{"class":122,"line":183},[120,290,291],{},"├── objects\n",[120,293,294],{"class":122,"line":189},[120,295,296],{},"├── refs\n",[120,298,299],{"class":122,"line":194},[120,300,301],{},"│   └── heads\n",[120,303,304],{"class":122,"line":200},[120,305,306],{},"└── reftable\n",[120,308,309],{"class":122,"line":206},[120,310,311],{},"  ├── 0x000000000001-0x000000000002-40a482a9.ref\n",[120,313,314],{"class":122,"line":212},[120,315,316],{},"  └── tables.list\n",[120,318,319],{"class":122,"line":218},[120,320,145],{"emptyLinePlaceholder":144},[120,322,324],{"class":122,"line":323},18,[120,325,326],{},"4 directories, 6 files\n",[12,328,329,330,333],{},"Sieh dir zunächst die Repository-Konfiguration an. Du wirst feststellen, dass sie den Schlüssel ",[81,331,332],{},"extension.refstorage"," enthält:",[111,335,337],{"className":113,"code":336,"language":115,"meta":116,"style":116},"$ cat .git/config\n[core]\n    repositoryformatversion = 1\n    filemode = true\n    bare = false\n    logallrefupdates = true\n[extensions]\n    refstorage = reftable\n\n",[81,338,339,344,349,354,359,364,369,374],{"__ignoreMap":116},[120,340,341],{"class":122,"line":123},[120,342,343],{},"$ cat .git/config\n",[120,345,346],{"class":122,"line":129},[120,347,348],{},"[core]\n",[120,350,351],{"class":122,"line":135},[120,352,353],{},"    repositoryformatversion = 1\n",[120,355,356],{"class":122,"line":141},[120,357,358],{},"    filemode = true\n",[120,360,361],{"class":122,"line":148},[120,362,363],{},"    bare = false\n",[120,365,366],{"class":122,"line":154},[120,367,368],{},"    logallrefupdates = true\n",[120,370,371],{"class":122,"line":160},[120,372,373],{},"[extensions]\n",[120,375,376],{"class":122,"line":166},[120,377,378],{},"    refstorage = reftable\n",[12,380,381],{},"Diese Konfiguration teilt Git mit, dass das Repository mit dem „reftable“-Format initialisiert wurde und gibt an, dass Git das „reftable“-Backend nutzen muss, um darauf zuzugreifen.",[12,383,384],{},"Seltsamerweise enthält das Repository immer noch einige Dateien, die aussehen, als würde das „files“-Backend verwendet werden:",[23,386,387,400],{},[26,388,389,392,393,395,396,399],{},[81,390,391],{},"HEAD"," würde normalerweise eine symbolische Referenz sein, die auf deinen derzeit ausgecheckten Branch zeigt. Obwohl es nicht vom „reftable“-Backend verwendet wird, ist es für Git-Clients erforderlich, um das Verzeichnis als Git-Verzeichnis zu erkennen. Wenn du also das „reftable“-Format verwendest, ist ",[81,394,391],{}," ein Stub mit dem Inhalt ",[81,397,398],{},"ref: refs/heads/.invalid",".",[26,401,402,405,406,409],{},[81,403,404],{},"refs/heads"," ist eine Datei mit dem Inhalt ",[81,407,408],{},"this repository uses the reftable format",". Git-Clients, die das Format „reftable“ nicht kennen, würden normalerweise erwarten, dass dieser Pfad ein Verzeichnis ist. Wenn du also diesen Pfad bewusst als Datei erstellst, führt dies dazu, dass ältere Git-Clients fehlschlagen, wenn sie versuchen, mit dem „files“-Backend auf das Repository zuzugreifen.",[12,411,412,413,416],{},"Die tatsächlichen Referenzen werden im Verzeichnis ",[81,414,415],{},"reftable/"," gespeichert:",[111,418,420],{"className":113,"code":419,"language":115,"meta":116,"style":116},"$ 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",[81,421,422,427,432,437,442,446,451],{"__ignoreMap":116},[120,423,424],{"class":122,"line":123},[120,425,426],{},"$ tree .git/reftable\n",[120,428,429],{"class":122,"line":129},[120,430,431],{},".git/reftable/\n",[120,433,434],{"class":122,"line":135},[120,435,436],{},"├──0x000000000001-0x000000000001-794bd722.ref\n",[120,438,439],{"class":122,"line":141},[120,440,441],{},"└── tables.list\n",[120,443,444],{"class":122,"line":148},[120,445,145],{"emptyLinePlaceholder":144},[120,447,448],{"class":122,"line":154},[120,449,450],{},"$ cat .git/reftable/tables.list\n",[120,452,453],{"class":122,"line":160},[120,454,455],{},"0x000000000001-0x000000000001-794bd722.ref\n",[12,457,458],{},"Es gibt hier zwei Dateien:",[23,460,461,467],{},[26,462,463,466],{},[81,464,465],{},"0x000000000001-0x000000000001-794bd722.ref"," ist eine Tabelle mit Referenzen und den Reflog-Einträgen in einem Binärformat.",[26,468,469,472],{},[81,470,471],{},"tables.list"," ist eine Liste von Tabellen. Im aktuellen Status des Repositorys enthält die Datei eine Zeile, die der Name der Tabelle ist. Diese Datei verfolgt den aktuellen Satz aktiver Tabellen in der „reftable“-Datenbank und wird aktualisiert, wenn neue Tabellen zum Repository hinzugefügt werden.",[12,474,475],{},"Wenn du eine Referenz aktualisierst, wird eine neue Tabelle erstellt:",[111,477,479],{"className":113,"code":478,"language":115,"meta":116,"style":116},"$ 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",[81,480,481,485,490,494,498,502,507,511,515,519],{"__ignoreMap":116},[120,482,483],{"class":122,"line":123},[120,484,132],{},[120,486,487],{"class":122,"line":129},[120,488,489],{},"[main (root-commit) 1472a58] Initial commit\n",[120,491,492],{"class":122,"line":135},[120,493,145],{"emptyLinePlaceholder":144},[120,495,496],{"class":122,"line":141},[120,497,426],{},[120,499,500],{"class":122,"line":148},[120,501,431],{},[120,503,504],{"class":122,"line":154},[120,505,506],{},"├──0x000000000001-0x000000000002-eb87d12b.ref\n",[120,508,509],{"class":122,"line":160},[120,510,441],{},[120,512,513],{"class":122,"line":166},[120,514,145],{"emptyLinePlaceholder":144},[120,516,517],{"class":122,"line":171},[120,518,450],{},[120,520,521],{"class":122,"line":177},[120,522,523],{},"0x000000000001-0x000000000002-eb87d12b.ref\n",[12,525,526,527,529],{},"Wie du sehen kannst, wurde die vorherige Tabelle durch eine neue ersetzt. Darüber hinaus wurde die Datei ",[81,528,471],{}," aktualisiert und enthält nun die neue Tabelle.",[57,531,533],{"id":532},"die-struktur-einer-tabelle","Die Struktur einer Tabelle",[12,535,536],{},"Wie bereits erwähnt, sind die eigentlichen Daten der Referenzdatenbank in Tabellen enthalten. Grob gesagt ist eine Tabelle in mehrere Abschnitte unterteilt:",[23,538,539,542,545,548,551],{},[26,540,541],{},"Der „Header“ enthält Metadaten zur Tabelle. Dazu gehören unter anderem die Version des Formats, die Blockgröße und die vom Repository verwendete Hash-Funktion (z. B. SHA1 oder SHA256).",[26,543,544],{},"Der Abschnitt „Ref“ enthält deine Referenzen. Diese Datensätze haben einen Schlüssel, der dem Referenznamen entspricht und entweder auf eine Objekt-ID für reguläre Referenzen oder auf eine andere Referenz für symbolische Referenzen zeigt.",[26,546,547],{},"Der Abschnitt „Obj“ enthält die umgekehrte Zuordnung von Objekt-IDs zu den Referenzen, die auf diese Objekt-IDs zeigen. Diese ermöglichen es Git, effizient zu suchen, welche Referenzen auf eine bestimmte Objekt-ID zeigen.",[26,549,550],{},"Der Abschnitt „Log“ enthält deine Reflog-Einträge. Diese Datensätze haben einen Schlüssel, der dem Referenznamen entspricht, sowie einen Index, der die Nummer des Reflog-Eintrags darstellt. Außerdem enthalten sie die alten und neuen Objekt-IDs sowie die Nachricht für diesen Reflog-Eintrag.",[26,552,553],{},"Der „Footer“ enthält Zeiger zu den verschiedenen Abschnitten.",[12,555,556],{},[557,558],"img",{"alt":559,"src":560},"Lange Tabelle mit allen reftable-Abschnitten","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675179/Blog/Content%20Images/Frame_1_-_Reftable_overview.svg",[12,562,563,564,567,568,571,572,574,575,577],{},"Die Abschnittstypen sind alle ähnlich strukturiert. Abschnitte enthalten eine Reihe von Datensätzen, die nach den Schlüsseln der einzelnen Datensätze sortiert sind. Wenn du zum Beispiel zwei Ref-Datensätze ",[81,565,566],{},"refs/heads/aaaaa"," und ",[81,569,570],{},"refs/heads/bbb"," hast, hast du zwei Ref-Datensätze mit diesen Referenznamen als jeweiligen Schlüssel, weshalb ",[81,573,566],{}," vor ",[81,576,570],{}," kommt.",[12,579,580],{},"Darüber hinaus ist jeder Abschnitt in Blöcke mit einer festen Länge unterteilt. Diese Blocklänge ist im Header codiert und dient zwei Zwecken:",[23,582,583,586],{},[26,584,585],{},"Da sie den Anfang des Abschnitts markieren und die Blockgröße angeben, weiß der bzw. die Leser(in) implizit, wo jeder der Blöcke beginnt. Dadurch kann Git gleich in die Mitte des Abschnitts springen, ohne vorherige Blocks lesen zu müssen. So kann die binäre Suche in Blöcken das Durchsuchen von Datensätzen beschleunigen.",[26,587,588],{},"Sie stellt sicher, dass Git weiß, wie viele Daten gleichzeitig von der Festplatte gelesen werden sollen. Folglich ist die Blockgröße standardmäßig auf 4 KiB eingestellt, was die häufigste Sektorgröße für Festplatten ist. Die maximale Blockgröße beträgt 16 MB.",[12,590,591],{},"Wenn wir zum Beispiel in einen „ref“-Abschnitt schauen, sieht er ungefähr wie die folgende Grafik aus. Achte darauf, wie die Datensätze lexikografisch in den Blocks, aber auch blockübergreifend sortiert sind.",[12,593,594],{},[557,595],{"alt":596,"src":597},"Referenzblock, nicht komprimiert","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675179/Blog/Content%20Images/Frame_2_-_Ref_block_uncompressed.svg",[12,599,600],{},"Mit diesem Wissen können wir nun einen Datensatz finden, indem wir die folgenden Schritte befolgen:",[602,603,604,607],"ol",{},[26,605,606],{},"Führe eine Binärsuche über die Blocks durch, indem du dir die Schlüssel der jeweiligen ersten Datensätze ansiehst und den Block identifizierst, der unseren Datensatz enthalten muss.",[26,608,609],{},"Führe eine lineare Suche in den Datensätzen dieses Blocks durch.",[12,611,612],{},"Beide Schritte sind immer noch recht ineffizient. Wenn wir viele Blöcke haben, müssen wir logarithmisch viele davon in unserer Binärsuche lesen, um den gewünschten Block zu finden. Und wenn Blöcke viele Datensätze enthalten, müssen wir vielleicht bei der linearen Suche alle davon lesen.",[12,614,615],{},"Das „reftable“-Format verfügt über zusätzliche integrierte Mechanismen, um diese Leistungsbedenken auszuräumen. Wir gehen in den nächsten Abschnitten darauf ein.",[617,618,620],"h3",{"id":619},"präfix-komprimierung","Präfix-Komprimierung",[12,622,623,624,627],{},"Wie du vielleicht bemerkt hast, haben alle Datensatzschlüssel das gleiche Präfix ",[81,625,626],{},"refs/",". Dies ist häufig so in Git:",[23,629,630,636],{},[26,631,632,633,399],{},"Alle Branches beginnen mit ",[81,634,635],{},"refs/heads/",[26,637,638,639,399],{},"Alle Tags beginnen mit ",[81,640,641],{},"refs/tags/",[12,643,644],{},"Daher gehen wir davon aus, dass nachfolgende Datensätze höchstwahrscheinlich einen signifikanten Anteil ihres Schlüssels gemeinsam haben. Dies ist eine gute Gelegenheit, um wertvollen Speicherplatz zu sparen. Da wir wissen, dass die meisten Schlüssel ein gemeinsames Präfix haben, ist es sinnvoll, dies zu optimieren.",[12,646,647,648,567,651,654,655,658,659,661,662,664,665,667],{},"Die Optimierung verwendet Präfix-Komprimierung. Jeder Datensatz kodiert eine Präfixlänge, die den Leser(innen) mitteilt, wie viele Bytes des Schlüssels des vorhergehenden Datensatzes wiederverwendet werden sollen. Wenn wir zwei Datensätze haben, ",[81,649,650],{},"refs/heads/a",[81,652,653],{},"refs/heads/b",", kann letzterer kodiert werden, indem man eine Präfixlänge von 11 angibt und dann nur das Suffix ",[81,656,657],{},"b"," speichert. Die Leser(innen) nehmen dann die ersten 11 Bytes von ",[81,660,650],{},", was ",[81,663,635],{}," ist, und fügen das Suffix ",[81,666,657],{}," hinzu.",[12,669,670],{},[557,671],{"alt":620,"src":672},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675179/Blog/Content%20Images/Frame_3_-_Ref_block_prefix_compression.svg",[617,674,676],{"id":675},"neustart-punkte","Neustart-Punkte",[12,678,679],{},"Wie bereits erklärt, ist eine lineare Suche der beste Weg, mit unserem derzeitigen Wissen über das „reftable“-Format in einem Block nach einer Referenz zu suchen. Der Grund dafür ist, dass die Datensätze keine fixe Länge haben. Daher können wir nicht feststellen, wo Datensätze beginnen, ohne von Anfang an den Block zu durchsuchen. Auch wenn Datensätze eine fixe Länge hätten, könnten wir nicht in der Mitte eines Blocks suchen, da die Präfix-Kompression erfordert, dass wir auch die vorhergehenden Datensätze lesen.",[12,681,682],{},"Eine lineare Suche wäre ziemlich ineffizient, da Blöcke Hunderte oder sogar Tausende von Datensätzen enthalten können. Um dieses Problem zu beheben, codiert das „reftable“-Format sogenannte Neustart-Punkte in jeden Block. Neustart-Punkte sind unkomprimierte Datensätze, bei denen keine Präfix-Komprimierung verwendet wird. Folglich enthalten Datensätze an Neustart-Punkten immer ihren vollständigen Schlüssel, und es wird möglich, den Datensatz direkt zu suchen und zu lesen, ohne die vorhergehenden Datensätze lesen zu müssen. Diese Neustart-Punkte sind in der Fußzeile jedes Blocks aufgeführt.",[12,684,685,686,690],{},"Mit diesen Informationen können wir eine lineare Suche über den Block vermeiden. Stattdessen können wir jetzt eine Binärsuche über die Neustart-Punkte durchführen, bei der wir nach dem ersten Neustart-Punkt mit einem Schlüssel suchen, der lexikographisch größer ist als der gesuchte Schlüssel. Daraus folgt, dass sich der gewünschte Datensatz in dem Abschnitt befinden muss, der sich vom ",[687,688,689],"em",{},"vorhergehenden"," Neustart-Punkt bis zum identifizierten Neustart-Punkt erstreckt.",[12,692,693],{},"Daher ist unser erstes Vorgehen bei der Suche nach einem Datensatz (Binärsuche nach dem Block, Linearsuche nach dem Datensatz) nun wie folgt:",[602,695,696,699,702],{},[26,697,698],{},"Führe eine Binärsuche über die Blocks durch und finde den Block, der unseren Datensatz enthalten muss.",[26,700,701],{},"Führe eine Binärsuche über die Neustart-Punkte durch und identifiziere den Unterabschnitt des Blocks, der unseren Datensatz enthalten muss.",[26,703,704],{},"Führe eine lineare Suche in den Datensätzen dieses Unterabschnitts.",[12,706,707],{},[557,708],{"alt":709,"src":710},"Lineare Suche nach einem Datensatz","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675179/Blog/Content%20Images/Frame_4_-_Restart_points.svg",[617,712,714],{"id":713},"indizes","Indizes",[12,716,717],{},"Die Suche nach Datensätzen in einem Block wäre nun einigermaßen effizient. Es ist aber weiterhin ineffizient, den Block selbst zu finden. Eine Binärsuche kann bei ein paar Blöcken funktionieren, aber Repositories mit Millionen von Referenzen können Hunderte oder sogar Tausende von Blöcken haben. Ohne zusätzliche Datenstruktur würde dies durchschnittlich logarithmisch viele Festplattenzugriffe verursachen.\nUm dies zu vermeiden, kann auf jeden Abschnitt ein Indexabschnitt folgen, der eine effiziente Möglichkeit bietet, einen Block nachzuschlagen. Jeder Indexdatensatz enthält die folgenden Informationen:",[23,719,720,723],{},[26,721,722],{},"Die Position des Blocks, den er indiziert.",[26,724,725],{},"Der Schlüssel des letzten Datensatzes des Blocks, den er indiziert.",[12,727,728],{},"Bei drei oder weniger Blöcken erfordert eine Binärsuche immer höchstens zwei Festplattenlesevorgänge, um den gewünschten Zielblock zu finden. Dies ist die gleiche Anzahl von Lesevorgängen, die wir mit einem Index hätten: einen, um den Index selbst zu lesen, und einen, um den gewünschten Block zu lesen. Folglich werden Indizes nur geschrieben, wenn sie tatsächlich einige Lesevorgänge einsparen würden, was ab vier indizierten Blöcken der Fall ist.",[12,730,731],{},"Nun stellt sich die Frage: Was passiert, wenn der Index selbst so groß wird, dass er sich über mehrere Blöcke erstreckt? Du hast es vielleicht erraten: Wir schreiben einen weiteren Index, der den Index indiziert. Diese mehrstufigen Indizes werden erst dann wirklich notwendig, wenn du Repositories mit hunderttausenden von Referenzen hast.",[12,733,734],{},"Mit diesen Indizes können wir jetzt das Verfahren zum Nachschlagen von Datensätzen noch effizienter machen:",[602,736,737],{},[26,738,739],{},"Finde heraus, ob es einen Index gibt, indem du dir die Fußzeile der Tabelle ansiehst.",[23,741,742,745],{},[26,743,744],{},"Wenn es einen gibt, führe eine Binärsuche über den Index durch, um den gewünschten Block zu finden. Dieser Block kann selbst auf einen Indexblock verweisen. In diesem Fall müssen wir diesen Schritt wiederholen, bis wir einen Datensatz des gewünschten Typs finden.",[26,746,747],{},"Ansonsten führe eine Binärsuche über die Blöcke durch, wie wir es zuvor getan haben.",[602,749,750,752],{"start":129},[26,751,701],{},[26,753,754],{},"Führe eine lineare Suche in den Datensätzen dieses Unterabschnitts durch.",[57,756,758],{"id":757},"mehrere-tabellen","Mehrere Tabellen",[12,760,761,762,765,766,768],{},"Bis jetzt haben wir nur besprochen, wie man eine ",[687,763,764],{},"einzelne"," Tabelle liest. Aber wie der Name ",[81,767,471],{}," schon sagt, kannst du tatsächlich eine Liste von Tabellen in deiner „reftable“-Datenbank haben.",[12,770,771,772,774],{},"Jedes Mal, wenn du eine Referenz in deinem Repository aktualisierst, wird eine neue Tabelle geschrieben und an ",[81,773,471],{}," angehängt. So hast du schließlich mehrere Tabellen:",[111,776,778],{"className":113,"code":777,"language":115,"meta":116,"style":116},"$ tree .git/reftable/\n.git/reftable/\n├──0x0000000000000001-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",[81,779,780,785,789,794,799,803,807,811,816],{"__ignoreMap":116},[120,781,782],{"class":122,"line":123},[120,783,784],{},"$ tree .git/reftable/\n",[120,786,787],{"class":122,"line":129},[120,788,431],{},[120,790,791],{"class":122,"line":135},[120,792,793],{},"├──0x0000000000000001-0x000000000007-8dcd8a77.ref\n",[120,795,796],{"class":122,"line":141},[120,797,798],{},"├── 0x000000000008-0x000000000008-30e0f6f6.ref\n",[120,800,801],{"class":122,"line":148},[120,802,441],{},[120,804,805],{"class":122,"line":154},[120,806,145],{"emptyLinePlaceholder":144},[120,808,809],{"class":122,"line":160},[120,810,450],{},[120,812,813],{"class":122,"line":166},[120,814,815],{},"0x000000000001-0x000000000007-8dcd8a77.ref\n",[120,817,818],{"class":122,"line":171},[120,819,820],{},"0x000000000008-0x000000000008-30e0f6f6.ref\n",[12,822,823],{},"Um den tatsächlichen Status eines Repositorys zu lesen, müssen wir diese mehreren Tabellen zu einer einzigen virtuellen Tabelle zusammenführen.",[12,825,826],{},"Du fragst dich vielleicht: Wenn für jede Referenzaktualisierung eine Tabelle geschrieben wird und dieselbe Referenz mehrmals aktualisiert wird, woher kennt das „reftable“-Format den aktuellsten Wert einer bestimmten Referenz? Intuitiv könnte man davon ausgehen, dass der Wert derjenige aus der neuesten Tabelle ist, die die Referenz enthält.",[12,828,829],{},"Tatsächlich hat jeder einzelne Datensatz einen sogenannten Aktualisierungsindex, der die „Priorität“ eines Datensatzes kodiert. Wenn beispielsweise zwei Ref-Datensätze mit demselben Namen existieren, überschreibt derjenige mit dem höheren Aktualisierungsindex denjenigen mit dem niedrigeren Aktualisierungsindex.",[12,831,832,833,836],{},"Diese Aktualisierungsindizes sind in der obigen Dateistruktur sichtbar. Die langen Hex-Zeichenfolgen (z. B. ",[81,834,835],{},"0x000000000001",") sind die Aktualisierungsindizes, wobei die linke Seite des Tabellennamens der minimale Aktualisierungsindex ist, der in der Tabelle enthalten ist, und die rechte Seite der maximale Aktualisierungsindex ist.",[12,838,839,840,845],{},"Das Zusammenführen der Tabellen erfolgt dann über eine ",[16,841,844],{"href":842,"rel":843},"https://de.wikipedia.org/wiki/Vorrangwarteschlange",[],"Vorrangwarteschlange",", die nach dem Schlüssel des Ref-Datensatzes sowie dem Aktualisierungsindex geordnet ist. Angenommen, wir möchten alle Ref-Datensätze durchsuchen, würden wir wie folgt vorgehen:",[602,847,848],{},[26,849,850],{},"Füge für jede Tabelle ihren ersten Datensatz zur Vorrangwarteschlange hinzu.",[12,852,853],{},[557,854],{"alt":855,"src":856},"Ersten Datensatz zur Vorrangwarteschlange hinzufügen","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675179/Blog/Content%20Images/Frame_5_-_Priority_queue_1.svg",[602,858,859],{"start":129},[26,860,861],{},"Liefere den Kopf der Vorrangwarteschlange. Da die Warteschlange nach Aktualisierungsindex geordnet ist, muss sie die aktuellste Version sein. Füge das nächste Element aus dessen Tabelle zur Vorrangwarteschlange hinzu.",[12,863,864],{},[557,865],{"alt":866,"src":867},"Head der Vorrangwarteschlange angeben","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675179/Blog/Content%20Images/Frame_6_-_Priority_queue_2.svg",[602,869,870],{"start":135},[26,871,872],{},"Ziehe alle Datensätze aus der Warteschlange, die den gleichen Namen haben. Diese Datensätze werden verschattet, was bedeutet, dass sie nicht angezeigt werden. Füge für jede Tabelle, für die wir Datensätze ablegen, den nächsten Datensatz zur Vorrangwarteschlange hinzu.",[12,874,875],{},[557,876],{"alt":877,"src":878},"Alle Datensätze aus der Warteschlange ablegen, die den gleichen Namen haben","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675179/Blog/Content%20Images/Frame_7_-_Priority_queue_3.svg",[12,880,881],{},"Jetzt können wir bereinigen und den Vorgang wiederholen, um Datensätze für andere Schlüssel zu lesen.",[12,883,884],{},"Tabellen können spezielle „tombstone“-Datensätze enthalten, die einen Datensatz als gelöscht markieren. So können wir Datensätze löschen, ohne den jeweiligen Datensatz aus allen Tabellen löschen zu müssen.",[617,886,888],{"id":887},"autokomprimierung","Autokomprimierung",[12,890,891,892,894],{},"Während die Idee hinter der Vorrangwarteschlange zwar einfach ist, wäre es allerdings eher ineffizient, Hunderte oder sogar nur Dutzende von Tabellen auf diese Weise zusammenzuführen. Es stimmt, dass jede Aktualisierung an deinen Referenzen eine neue Tabelle an deine ",[81,893,471],{},"-Datei anhängt. Das ist jedoch nur ein Teil der Wahrheit.",[12,896,897,898,903,904,907,908,911],{},"Der andere Teil ist die Autokomprimierung: Nachdem eine neue Tabelle an die Liste der Tabellen angehängt wurde, überprüft das „reftable“-Backend, ob manche der Tabellen zusammengeführt werden sollen. Dies erfolgt durch eine einfache Heuristik. Wir überprüfen, ob die Liste der Tabellen eine ",[16,899,902],{"href":900,"rel":901},"https://de.wikipedia.org/wiki/Geometrische_Folge",[],"geometrische Folge"," der Dateigrößen bildet. Jede Tabelle ",[81,905,906],{},"n"," muss mindestens doppelt so groß sein wie die nächstletzte Tabelle ",[81,909,910],{},"n + 1",". Wenn gegen diese geometrische Folge verstoßen wird, komprimiert das Backend die Tabellen, sodass die geometrische Folge wiederhergestellt wird.",[12,913,914],{},"Im Laufe der Zeit führt dies zu Strukturen, die wie folgt aussehen:",[111,916,918],{"className":113,"code":917,"language":115,"meta":116,"style":116},"$ 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",[81,919,920,925,930,935,940,945,950,955],{"__ignoreMap":116},[120,921,922],{"class":122,"line":123},[120,923,924],{},"$ du --apparent-size .git/reftable/*\n",[120,926,927],{"class":122,"line":129},[120,928,929],{},"429    .git/reftable/0x000000000001-0x00000000bd7c-d9819000.ref\n",[120,931,932],{"class":122,"line":135},[120,933,934],{},"101    .git/reftable/0x00000000bd7d-0x00000000c5ac-c34b88a4.ref\n",[120,936,937],{"class":122,"line":141},[120,938,939],{},"32    .git/reftable/0x00000000c5ad-0x00000000cc6c-60391f53.ref\n",[120,941,942],{"class":122,"line":148},[120,943,944],{},"8    .git/reftable/0x00000000cc6d-0x00000000cdc1-61c30db1.ref\n",[120,946,947],{"class":122,"line":154},[120,948,949],{},"3    .git/reftable/0x00000000cdc2-0x00000000ce67-d9b55a96.ref\n",[120,951,952],{"class":122,"line":160},[120,953,954],{},"1    .git/reftable/0x00000000ce68-0x00000000ce6b-44721696.ref\n",[120,956,957],{"class":122,"line":166},[120,958,959],{},"1    .git/reftable/tables.list\n",[12,961,962,963,966],{},"Beachte, wie für jede einzelne Tabelle die Eigenschaft ",[81,964,965],{},"size(n) > size(n+1) * 2"," gilt.",[12,968,969,970,973],{},"Eine der Folgen der Autokomprimierung ist, dass sich das „reftable“-Backend selbst erhält. Wir müssen somit nicht mehr den Befehl ",[81,971,972],{},"git pack-refs"," zum Optimieren der Referenzen ausführen.",[57,975,977],{"id":976},"möchtest-du-mehr-erfahren","Möchtest du mehr erfahren?",[12,979,980,981,986],{},"Du solltest jetzt ein gutes Verständnis dafür haben, wie das neue „reftable“-Format im Detail funktioniert. Wenn du noch tiefer in das Format eintauchen möchtest, kannst du dir dessen ",[16,982,985],{"href":983,"rel":984},"https://git-scm.com/docs/reftable",[],"technische Dokumentation"," des Git-Projekts ansehen.",[42,988,989],{},[12,990,991,992,997],{},"Lies dir unsere ",[16,993,996],{"href":994,"rel":995},"https://about.gitlab.com/blog/whats-new-in-git-2-45-0/",[],"Zusammenfassung von Git 2.45.0"," durch, um herauszufinden, was sonst noch in dieser Version von Git auf dich wartet.",[999,1000,1001],"style",{},"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":116,"searchDepth":129,"depth":129,"links":1003},[1004,1005,1006,1011,1014],{"id":59,"depth":129,"text":60},{"id":224,"depth":129,"text":225},{"id":532,"depth":129,"text":533,"children":1007},[1008,1009,1010],{"id":619,"depth":135,"text":620},{"id":675,"depth":135,"text":676},{"id":713,"depth":135,"text":714},{"id":757,"depth":129,"text":758,"children":1012},[1013],{"id":887,"depth":135,"text":888},{"id":976,"depth":129,"text":977},"open-source","2024-05-30","In Git 2.45.0 hat GitLab das reftable Backend in Git eingeführt – dies verändert die Art und Weise, wie Referenzen gespeichert werden, von Grund auf. Erhalte detaillierte Einblicke, wie dieses neue Format funktioniert.","md",null,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664595/Blog/Hero%20Images/blog-image-template-1800x945__9_.png",{},"/de-de/blog/a-beginners-guide-to-the-git-reftable-format",{"ogTitle":5,"ogImage":1020,"ogDescription":1017,"ogSiteName":1024,"noIndex":1025,"ogType":1026,"ogUrl":1027,"title":5,"canonicalUrls":1027,"description":1017},"https://about.gitlab.com",false,"article","https://about.gitlab.com/blog/a-beginners-guide-to-the-git-reftable-format","a-beginners-guide-to-the-git-reftable-format","de-de/blog/a-beginners-guide-to-the-git-reftable-format",[1031,1032,1033,1034],"git","tutorial","open source","performance","BlogPost","2024-07-29","uzK6993F-iphL9aszTVmVFzwHLQzx1yuh0VS_98oaGs",{"logo":1039,"freeTrial":1044,"sales":1049,"login":1054,"items":1059,"search":1388,"minimal":1422,"duo":1440,"switchNav":1449,"pricingDeployment":1460},{"config":1040},{"href":1041,"dataGaName":1042,"dataGaLocation":1043},"/de-de/","gitlab logo","header",{"text":1045,"config":1046},"Kostenlose Testversion anfordern",{"href":1047,"dataGaName":1048,"dataGaLocation":1043},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/de-de&glm_content=default-saas-trial/","free trial",{"text":1050,"config":1051},"Demo anfordern",{"href":1052,"dataGaName":1053,"dataGaLocation":1043},"/de-de/sales/?contact-topic=request-demo","sales",{"text":1055,"config":1056},"Anmelden",{"href":1057,"dataGaName":1058,"dataGaLocation":1043},"https://gitlab.com/users/sign_in/","sign in",[1060,1089,1191,1196,1310,1366],{"text":1061,"config":1062,"menu":1064},"Plattform",{"dataNavLevelOne":1063},"platform",{"type":1065,"columns":1066},"cards",[1067,1073,1081],{"title":1061,"description":1068,"link":1069},"Die intelligente Orchestrierungsplattform für DevSecOps",{"text":1070,"config":1071},"Die Plattform erkunden",{"href":1072,"dataGaName":1063,"dataGaLocation":1043},"/de-de/platform/",{"title":1074,"description":1075,"link":1076},"GitLab Duo Agent Platform","Agentische KI für den gesamten Software-Lebenszyklus",{"text":1077,"config":1078},"Lerne GitLab Duo kennen",{"href":1079,"dataGaName":1080,"dataGaLocation":1043},"/de-de/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":1082,"description":1083,"link":1084},"Warum GitLab?","Erfahre, warum sich Unternehmen für GitLab entscheiden",{"text":1085,"config":1086},"Mehr erfahren",{"href":1087,"dataGaName":1088,"dataGaLocation":1043},"/de-de/why-gitlab/","why gitlab",{"text":1090,"left":144,"config":1091,"menu":1093},"Produkt",{"dataNavLevelOne":1092},"solutions",{"type":1094,"link":1095,"columns":1099,"feature":1170},"lists",{"text":1096,"config":1097},"Alle Lösungen anzeigen",{"href":1098,"dataGaName":1092,"dataGaLocation":1043},"/de-de/solutions/",[1100,1125,1148],{"title":1101,"description":1102,"link":1103,"items":1108},"Automatisierung","CI/CD und Automatisierung zur Beschleunigung der Bereitstellung",{"config":1104},{"icon":1105,"href":1106,"dataGaName":1107,"dataGaLocation":1043},"AutomatedCodeAlt","/de-de/solutions/delivery-automation/","automated software delivery",[1109,1113,1116,1121],{"text":1110,"config":1111},"CI/CD",{"href":1112,"dataGaLocation":1043,"dataGaName":1110},"/de-de/solutions/continuous-integration/",{"text":1074,"config":1114},{"href":1079,"dataGaLocation":1043,"dataGaName":1115},"gitlab duo agent platform - product menu",{"text":1117,"config":1118},"Quellcodeverwaltung",{"href":1119,"dataGaLocation":1043,"dataGaName":1120},"/de-de/solutions/source-code-management/","Source Code Management",{"text":1122,"config":1123},"Automatische Softwarebereitstellung",{"href":1106,"dataGaLocation":1043,"dataGaName":1124},"Automated software delivery",{"title":1126,"description":1127,"link":1128,"items":1133},"Sicherheit","Entwickle Code schneller ohne Abstriche bei der Sicherheit",{"config":1129},{"href":1130,"dataGaName":1131,"dataGaLocation":1043,"icon":1132},"/de-de/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[1134,1138,1143],{"text":1135,"config":1136},"Anwendungssicherheitstests",{"href":1130,"dataGaName":1137,"dataGaLocation":1043},"Application security testing",{"text":1139,"config":1140},"Schutz der Software-Lieferkette",{"href":1141,"dataGaLocation":1043,"dataGaName":1142},"/de-de/solutions/supply-chain/","Software supply chain security",{"text":1144,"config":1145},"Software-Compliance",{"href":1146,"dataGaName":1147,"dataGaLocation":1043},"/de-de/solutions/software-compliance/","software compliance",{"title":1149,"link":1150,"items":1155},"Messung",{"config":1151},{"icon":1152,"href":1153,"dataGaName":1154,"dataGaLocation":1043},"DigitalTransformation","/de-de/solutions/visibility-measurement/","visibility and measurement",[1156,1160,1165],{"text":1157,"config":1158},"Sichtbarkeit und Messung",{"href":1153,"dataGaLocation":1043,"dataGaName":1159},"Visibility and Measurement",{"text":1161,"config":1162},"Wertstrommanagement",{"href":1163,"dataGaLocation":1043,"dataGaName":1164},"/de-de/solutions/value-stream-management/","Value Stream Management",{"text":1166,"config":1167},"Analysen und Einblicke",{"href":1168,"dataGaLocation":1043,"dataGaName":1169},"/de-de/solutions/analytics-and-insights/","Analytics and insights",{"title":1171,"type":1094,"items":1172},"GitLab für",[1173,1179,1185],{"text":1174,"config":1175},"Enterprise",{"icon":1176,"href":1177,"dataGaLocation":1043,"dataGaName":1178},"Building","/de-de/enterprise/","enterprise",{"text":1180,"config":1181},"Kleinunternehmen",{"icon":1182,"href":1183,"dataGaLocation":1043,"dataGaName":1184},"Work","/de-de/small-business/","small business",{"text":1186,"config":1187},"Öffentlicher Sektor",{"icon":1188,"href":1189,"dataGaLocation":1043,"dataGaName":1190},"Organization","/de-de/solutions/public-sector/","public sector",{"text":1192,"config":1193},"Preise",{"href":1194,"dataGaName":1195,"dataGaLocation":1043,"dataNavLevelOne":1195},"/de-de/pricing/","pricing",{"text":1197,"config":1198,"menu":1200},"Ressourcen",{"dataNavLevelOne":1199},"resources",{"type":1094,"link":1201,"columns":1205,"feature":1299},{"text":1202,"config":1203},"Alle Ressourcen anzeigen",{"href":1204,"dataGaName":1199,"dataGaLocation":1043},"/de-de/resources/",[1206,1239,1266],{"title":1207,"items":1208},"Erste Schritte",[1209,1214,1219,1224,1229,1234],{"text":1210,"config":1211},"Installieren",{"href":1212,"dataGaName":1213,"dataGaLocation":1043},"/de-de/install/","install",{"text":1215,"config":1216},"Kurzanleitungen",{"href":1217,"dataGaName":1218,"dataGaLocation":1043},"/de-de/get-started/","quick setup checklists",{"text":1220,"config":1221},"Lernen",{"href":1222,"dataGaLocation":1043,"dataGaName":1223},"https://university.gitlab.com/","learn",{"text":1225,"config":1226},"Produktdokumentation",{"href":1227,"dataGaName":1228,"dataGaLocation":1043},"https://docs.gitlab.com/","product documentation",{"text":1230,"config":1231},"Best-Practice-Videos",{"href":1232,"dataGaName":1233,"dataGaLocation":1043},"/de-de/getting-started-videos/","best practice videos",{"text":1235,"config":1236},"Integrationen",{"href":1237,"dataGaName":1238,"dataGaLocation":1043},"/de-de/integrations/","integrations",{"title":1240,"items":1241},"Entdecken",[1242,1247,1252,1257,1261],{"text":1243,"config":1244},"Kundenerfolge",{"href":1245,"dataGaName":1246,"dataGaLocation":1043},"/de-de/customers/","customer success stories",{"text":1248,"config":1249},"Blog",{"href":1250,"dataGaName":1251,"dataGaLocation":1043},"/de-de/blog/","blog",{"text":1253,"config":1254},"Demo-Hub",{"href":1255,"dataGaName":1256,"dataGaLocation":1043},"/de-de/demo-hub/","demo hub",{"text":1258,"config":1259},"The Source",{"href":1260,"dataGaName":1251,"dataGaLocation":1043},"/de-de/the-source/",{"text":1262,"config":1263},"Remote",{"href":1264,"dataGaName":1265,"dataGaLocation":1043},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":1267,"items":1268},"Vernetzen",[1269,1274,1279,1284,1289,1294],{"text":1270,"config":1271},"GitLab-Services",{"href":1272,"dataGaName":1273,"dataGaLocation":1043},"/de-de/services/","services",{"text":1275,"config":1276},"Beitragen",{"href":1277,"dataGaName":1278,"dataGaLocation":1043},"https://contributors.gitlab.com","contribute",{"text":1280,"config":1281},"Community",{"href":1282,"dataGaName":1283,"dataGaLocation":1043},"/community/","community",{"text":1285,"config":1286},"Forum",{"href":1287,"dataGaName":1288,"dataGaLocation":1043},"https://forum.gitlab.com/","forum",{"text":1290,"config":1291},"Veranstaltungen",{"href":1292,"dataGaName":1293,"dataGaLocation":1043},"/events/","events",{"text":1295,"config":1296},"Partner",{"href":1297,"dataGaName":1298,"dataGaLocation":1043},"/de-de/partners/","partners",{"config":1300,"title":1303,"text":1304,"link":1305},{"background":1301,"textColor":1302},"url('https://res.cloudinary.com/about-gitlab-com/image/upload/v1777322348/qpq8yrgn8knii57omj0c.png')","#000","Neues bei GitLab","Über die neuesten Funktionen und Verbesserungen auf dem Laufenden bleiben.",{"text":1306,"config":1307},"Aktuelle Nachrichten",{"href":1308,"dataGaName":1309,"dataGaLocation":1043},"/de-de/whats-new/","whats new",{"text":1311,"config":1312,"menu":1314},"Unternehmen",{"dataNavLevelOne":1313},"company",{"type":1094,"columns":1315},[1316],{"items":1317},[1318,1323,1329,1331,1336,1341,1346,1351,1356,1361],{"text":1319,"config":1320},"Über",{"href":1321,"dataGaName":1322,"dataGaLocation":1043},"/de-de/company/","about",{"text":1324,"config":1325,"footerGa":1328},"Karriere",{"href":1326,"dataGaName":1327,"dataGaLocation":1043},"/jobs/","jobs",{"dataGaName":1327},{"text":1290,"config":1330},{"href":1292,"dataGaName":1293,"dataGaLocation":1043},{"text":1332,"config":1333},"Geschäftsführung",{"href":1334,"dataGaName":1335,"dataGaLocation":1043},"/company/team/e-group/","leadership",{"text":1337,"config":1338},"Handbuch",{"href":1339,"dataGaName":1340,"dataGaLocation":1043},"https://handbook.gitlab.com/","handbook",{"text":1342,"config":1343},"Investor Relations",{"href":1344,"dataGaName":1345,"dataGaLocation":1043},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":1347,"config":1348},"Trust Center",{"href":1349,"dataGaName":1350,"dataGaLocation":1043},"/de-de/security/","trust center",{"text":1352,"config":1353},"AI Transparency Center",{"href":1354,"dataGaName":1355,"dataGaLocation":1043},"/de-de/ai-transparency-center/","ai transparency center",{"text":1357,"config":1358},"Newsletter",{"href":1359,"dataGaName":1360,"dataGaLocation":1043},"/company/contact/#contact-forms","newsletter",{"text":1362,"config":1363},"Presse",{"href":1364,"dataGaName":1365,"dataGaLocation":1043},"/press/","press",{"text":1367,"config":1368,"menu":1369},"Kontakt",{"dataNavLevelOne":1313},{"type":1094,"columns":1370},[1371],{"items":1372},[1373,1378,1383],{"text":1374,"config":1375},"Vertrieb kontaktieren",{"href":1376,"dataGaName":1377,"dataGaLocation":1043},"/de-de/sales/","talk to sales",{"text":1379,"config":1380},"Support-Portal",{"href":1381,"dataGaName":1382,"dataGaLocation":1043},"https://support.gitlab.com/hc/en-us","support portal",{"text":1384,"config":1385},"Kundenportal",{"href":1386,"dataGaName":1387,"dataGaLocation":1043},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":1389,"login":1390,"suggestions":1397},"Schließen",{"text":1391,"link":1392},"Um Repositorys und Projekte zu durchsuchen, melde dich an bei",{"text":1393,"config":1394},"gitlab.com",{"href":1057,"dataGaName":1395,"dataGaLocation":1396},"search login","search",{"text":1398,"default":1399},"Vorschläge",[1400,1402,1407,1409,1414,1419],{"text":1074,"config":1401},{"href":1079,"dataGaName":1074,"dataGaLocation":1396},{"text":1403,"config":1404},"Codevorschläge (KI)",{"href":1405,"dataGaName":1406,"dataGaLocation":1396},"/de-de/solutions/code-suggestions/","Code Suggestions (AI)",{"text":1110,"config":1408},{"href":1112,"dataGaName":1110,"dataGaLocation":1396},{"text":1410,"config":1411},"GitLab auf AWS",{"href":1412,"dataGaName":1413,"dataGaLocation":1396},"/de-de/partners/technology-partners/aws/","GitLab on AWS",{"text":1415,"config":1416},"GitLab auf Google Cloud",{"href":1417,"dataGaName":1418,"dataGaLocation":1396},"/de-de/partners/technology-partners/google-cloud-platform/","GitLab on Google Cloud",{"text":1082,"config":1420},{"href":1087,"dataGaName":1421,"dataGaLocation":1396},"Why GitLab?",{"freeTrial":1423,"mobileIcon":1428,"desktopIcon":1433,"secondaryButton":1436},{"text":1424,"config":1425},"Kostenlos testen",{"href":1426,"dataGaName":1048,"dataGaLocation":1427},"https://gitlab.com/-/trials/new/","nav",{"altText":1429,"config":1430},"GitLab-Symbol",{"src":1431,"dataGaName":1432,"dataGaLocation":1427},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":1429,"config":1434},{"src":1435,"dataGaName":1432,"dataGaLocation":1427},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":1207,"config":1437},{"href":1438,"dataGaName":1439,"dataGaLocation":1427},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/de-de/get-started/","get started",{"freeTrial":1441,"mobileIcon":1445,"desktopIcon":1447},{"text":1442,"config":1443},"Mehr über GitLab Duo erfahren",{"href":1079,"dataGaName":1444,"dataGaLocation":1427},"gitlab duo",{"altText":1429,"config":1446},{"src":1431,"dataGaName":1432,"dataGaLocation":1427},{"altText":1429,"config":1448},{"src":1435,"dataGaName":1432,"dataGaLocation":1427},{"button":1450,"mobileIcon":1455,"desktopIcon":1457},{"text":1451,"config":1452},"/Option",{"href":1453,"dataGaName":1454,"dataGaLocation":1427},"#contact","switch",{"altText":1429,"config":1456},{"src":1431,"dataGaName":1432,"dataGaLocation":1427},{"altText":1429,"config":1458},{"src":1459,"dataGaName":1432,"dataGaLocation":1427},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":1461,"mobileIcon":1466,"desktopIcon":1468},{"text":1462,"config":1463},"Zurück zur Preisübersicht",{"href":1194,"dataGaName":1464,"dataGaLocation":1427,"icon":1465},"back to pricing","GoBack",{"altText":1429,"config":1467},{"src":1431,"dataGaName":1432,"dataGaLocation":1427},{"altText":1429,"config":1469},{"src":1435,"dataGaName":1432,"dataGaLocation":1427},{"title":1471,"button":1472,"config":1476},"GitLab Orbit ist da: die Kontextebene für KI-Agenten",{"text":1085,"config":1473},{"href":1474,"dataGaName":1475,"dataGaLocation":1043},"/de-de/gitlab-orbit/","orbit",{"layout":1477,"disabled":1025},"release",{"data":1479},{"text":1480,"source":1481,"edit":1487,"contribute":1492,"config":1497,"items":1502,"minimal":1708},"Git ist eine Marke von Software Freedom Conservancy und unsere Verwendung von „GitLab“ erfolgt unter Lizenz.",{"text":1482,"config":1483},"Quelltext der Seite anzeigen",{"href":1484,"dataGaName":1485,"dataGaLocation":1486},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":1488,"config":1489},"Diese Seite bearbeiten",{"href":1490,"dataGaName":1491,"dataGaLocation":1486},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":1493,"config":1494},"Beteilige dich",{"href":1495,"dataGaName":1496,"dataGaLocation":1486},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":1498,"facebook":1499,"youtube":1500,"linkedin":1501},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[1503,1548,1601,1643,1675],{"title":1192,"links":1504,"subMenu":1519},[1505,1509,1514],{"text":1506,"config":1507},"Tarife anzeigen",{"href":1194,"dataGaName":1508,"dataGaLocation":1486},"view plans",{"text":1510,"config":1511},"Vorteile von Premium",{"href":1512,"dataGaName":1513,"dataGaLocation":1486},"/de-de/pricing/premium/","why premium",{"text":1515,"config":1516},"Vorteile von Ultimate",{"href":1517,"dataGaName":1518,"dataGaLocation":1486},"/de-de/pricing/ultimate/","why ultimate",[1520],{"title":1367,"links":1521},[1522,1524,1526,1528,1533,1538,1543],{"text":1374,"config":1523},{"href":1376,"dataGaName":1053,"dataGaLocation":1486},{"text":1379,"config":1525},{"href":1381,"dataGaName":1382,"dataGaLocation":1486},{"text":1384,"config":1527},{"href":1386,"dataGaName":1387,"dataGaLocation":1486},{"text":1529,"config":1530},"Status",{"href":1531,"dataGaName":1532,"dataGaLocation":1486},"https://status.gitlab.com/","status",{"text":1534,"config":1535},"Nutzungsbedingungen",{"href":1536,"dataGaName":1537,"dataGaLocation":1486},"/terms/","terms of use",{"text":1539,"config":1540},"Datenschutzerklärung",{"href":1541,"dataGaName":1542,"dataGaLocation":1486},"/de-de/privacy/","privacy statement",{"text":1544,"config":1545},"Cookie-Einstellungen",{"dataGaName":1546,"dataGaLocation":1486,"id":1547,"isOneTrustButton":144},"cookie preferences","ot-sdk-btn",{"title":1090,"links":1549,"subMenu":1558},[1550,1554],{"text":1551,"config":1552},"DevSecOps-Plattform",{"href":1072,"dataGaName":1553,"dataGaLocation":1486},"devsecops platform",{"text":1555,"config":1556},"KI-unterstützte Entwicklung",{"href":1079,"dataGaName":1557,"dataGaLocation":1486},"ai-assisted development",[1559],{"title":1560,"links":1561},"Themen",[1562,1566,1571,1576,1581,1586,1591,1596],{"text":1110,"config":1563},{"href":1564,"dataGaName":1565,"dataGaLocation":1486},"/de-de/topics/ci-cd/","cicd",{"text":1567,"config":1568},"GitOps",{"href":1569,"dataGaName":1570,"dataGaLocation":1486},"/de-de/topics/gitops/","gitops",{"text":1572,"config":1573},"DevOps",{"href":1574,"dataGaName":1575,"dataGaLocation":1486},"/de-de/topics/devops/","devops",{"text":1577,"config":1578},"Versionskontrolle",{"href":1579,"dataGaName":1580,"dataGaLocation":1486},"/de-de/topics/version-control/","version control",{"text":1582,"config":1583},"DevSecOps",{"href":1584,"dataGaName":1585,"dataGaLocation":1486},"/de-de/topics/devsecops/","devsecops",{"text":1587,"config":1588},"Cloud-nativ",{"href":1589,"dataGaName":1590,"dataGaLocation":1486},"/de-de/topics/cloud-native/","cloud native",{"text":1592,"config":1593},"KI für das Programmieren",{"href":1594,"dataGaName":1595,"dataGaLocation":1486},"/de-de/topics/devops/ai-for-coding/","ai for coding",{"text":1597,"config":1598},"Agentische KI",{"href":1599,"dataGaName":1600,"dataGaLocation":1486},"/de-de/topics/agentic-ai/","agentic ai",{"title":1602,"links":1603},"Lösungen",[1604,1607,1609,1614,1618,1621,1624,1627,1629,1631,1633,1638],{"text":1135,"config":1605},{"href":1130,"dataGaName":1606,"dataGaLocation":1486},"Application Security Testing",{"text":1122,"config":1608},{"href":1106,"dataGaName":1107,"dataGaLocation":1486},{"text":1610,"config":1611},"Agile Entwicklung",{"href":1612,"dataGaName":1613,"dataGaLocation":1486},"/de-de/solutions/agile-delivery/","agile delivery",{"text":1615,"config":1616},"SCM",{"href":1119,"dataGaName":1617,"dataGaLocation":1486},"source code management",{"text":1110,"config":1619},{"href":1112,"dataGaName":1620,"dataGaLocation":1486},"continuous integration & delivery",{"text":1161,"config":1622},{"href":1163,"dataGaName":1623,"dataGaLocation":1486},"value stream management",{"text":1567,"config":1625},{"href":1626,"dataGaName":1570,"dataGaLocation":1486},"/de-de/solutions/gitops/",{"text":1174,"config":1628},{"href":1177,"dataGaName":1178,"dataGaLocation":1486},{"text":1180,"config":1630},{"href":1183,"dataGaName":1184,"dataGaLocation":1486},{"text":1186,"config":1632},{"href":1189,"dataGaName":1190,"dataGaLocation":1486},{"text":1634,"config":1635},"Bildungswesen",{"href":1636,"dataGaName":1637,"dataGaLocation":1486},"/de-de/solutions/education/","education",{"text":1639,"config":1640},"Finanzdienstleistungen",{"href":1641,"dataGaName":1642,"dataGaLocation":1486},"/de-de/solutions/finance/","financial services",{"title":1197,"links":1644},[1645,1647,1649,1651,1654,1656,1659,1661,1663,1665,1667,1669,1671,1673],{"text":1210,"config":1646},{"href":1212,"dataGaName":1213,"dataGaLocation":1486},{"text":1215,"config":1648},{"href":1217,"dataGaName":1218,"dataGaLocation":1486},{"text":1220,"config":1650},{"href":1222,"dataGaName":1223,"dataGaLocation":1486},{"text":1225,"config":1652},{"href":1227,"dataGaName":1653,"dataGaLocation":1486},"docs",{"text":1248,"config":1655},{"href":1250,"dataGaName":1251,"dataGaLocation":1486},{"text":1657,"config":1658},"Neuerungen",{"href":1308,"dataGaName":1309,"dataGaLocation":1486},{"text":1243,"config":1660},{"href":1245,"dataGaName":1246,"dataGaLocation":1486},{"text":1262,"config":1662},{"href":1264,"dataGaName":1265,"dataGaLocation":1486},{"text":1270,"config":1664},{"href":1272,"dataGaName":1273,"dataGaLocation":1486},{"text":1275,"config":1666},{"href":1277,"dataGaName":1278,"dataGaLocation":1486},{"text":1280,"config":1668},{"href":1282,"dataGaName":1283,"dataGaLocation":1486},{"text":1285,"config":1670},{"href":1287,"dataGaName":1288,"dataGaLocation":1486},{"text":1290,"config":1672},{"href":1292,"dataGaName":1293,"dataGaLocation":1486},{"text":1295,"config":1674},{"href":1297,"dataGaName":1298,"dataGaLocation":1486},{"title":1311,"links":1676},[1677,1679,1681,1683,1685,1687,1692,1697,1699,1701,1703],{"text":1319,"config":1678},{"href":1321,"dataGaName":1313,"dataGaLocation":1486},{"text":1324,"config":1680},{"href":1326,"dataGaName":1327,"dataGaLocation":1486},{"text":1332,"config":1682},{"href":1334,"dataGaName":1335,"dataGaLocation":1486},{"text":1337,"config":1684},{"href":1339,"dataGaName":1340,"dataGaLocation":1486},{"text":1342,"config":1686},{"href":1344,"dataGaName":1345,"dataGaLocation":1486},{"text":1688,"config":1689},"Nachhaltigkeit",{"href":1690,"dataGaName":1691,"dataGaLocation":1486},"/sustainability/","Sustainability",{"text":1693,"config":1694},"Vielfalt, Inklusion und Zugehörigkeit",{"href":1695,"dataGaName":1696,"dataGaLocation":1486},"/de-de/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":1347,"config":1698},{"href":1349,"dataGaName":1350,"dataGaLocation":1486},{"text":1357,"config":1700},{"href":1359,"dataGaName":1360,"dataGaLocation":1486},{"text":1362,"config":1702},{"href":1364,"dataGaName":1365,"dataGaLocation":1486},{"text":1704,"config":1705},"Transparenzerklärung zu moderner Sklaverei",{"href":1706,"dataGaName":1707,"dataGaLocation":1486},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":1709},[1710,1713,1716],{"text":1711,"config":1712},"Terms",{"href":1536,"dataGaName":1537,"dataGaLocation":1486},{"text":1714,"config":1715},"Cookies",{"dataGaName":1546,"dataGaLocation":1486,"id":1547,"isOneTrustButton":144},{"text":1717,"config":1718},"Datenschutz",{"href":1541,"dataGaName":1542,"dataGaLocation":1486},[1720],{"id":1721,"title":7,"body":1019,"config":1722,"content":1724,"description":1019,"extension":1728,"meta":1729,"navigation":144,"path":1730,"seo":1731,"stem":1732,"__hash__":1733},"blogAuthors/en-us/blog/authors/patrick-steinhardt.yml",{"template":1723},"BlogAuthor",{"name":7,"config":1725},{"headshot":1726,"ctfId":1727},"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",[1735,1743,1751],{"title":1736,"description":1737,"heroImage":1738,"category":1015,"date":1739,"authors":1740,"slug":1742,"externalUrl":1019},"Was ist neu in Git 2.55.0?","Neue Funktionen in Git 2.55: git-history(1) fixup, fsmonitor-Daemon für Linux, Push zu Remote-Gruppen und mehr.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782732487/ztwgrvlolpifo01vj8qc.png","2026-06-29",[1741],"Toon Claes","whats-new-in-git-2-55-0",{"title":1744,"description":1745,"heroImage":1746,"category":1015,"date":1747,"authors":1748,"slug":1750,"externalUrl":1019},"GitLab AI Hackathon 2026: Hier sind die Gewinner und ihre Projekte","Fast 7.000 Entwickler(innen) haben über 600 KI-Agenten und Flows auf GitLab Duo Agent Platform gebaut. Erfahre, wer gewonnen hat und was sie entwickelt haben.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1776457632/llddiylsgwuze0u1rjks.png","2026-04-22",[1749],"Nick Veenhof","gitlab-ai-hackathon-2026-meet-the-winners",{"title":1752,"description":1753,"heroImage":1754,"category":1015,"date":1755,"authors":1756,"slug":1757,"externalUrl":1019},"Was ist neu in Git 2.54.0?","Erfahre mehr über die Beiträge zu diesem Release, darunter neue Repository-Wartung, ein neuer Befehl zur Bearbeitung der Commit-Historie, ein Ersatz für git-sizer(1) und mehr.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1776711651/sj7xxyyuimlarswbyft5.png","2026-04-20",[7],"whats-new-in-git-2-54-0",{"promotions":1759},[1760,1774,1786,1798],{"id":1761,"categories":1762,"header":1764,"text":1765,"button":1766,"image":1771},"ai-modernization",[1763],"ai","Hält KI, was uns versprochen wurde?","Das Quiz dauert maximal 5 Minuten.",{"text":1767,"config":1768},"Ermittle deinen KI-Reifegrad",{"href":1769,"dataGaName":1770,"dataGaLocation":1251},"/de-de/assessments/ai-modernization-assessment/","modernization assessment",{"config":1772},{"src":1773},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":1775,"categories":1776,"header":1778,"text":1765,"button":1779,"image":1783},"devops-modernization",[1777,1585],"product","Verwaltest du Tool-Chaos oder stellst du Innovationen bereit?",{"text":1780,"config":1781},"Ermittle deinen DevOps-Reifegrad",{"href":1782,"dataGaName":1770,"dataGaLocation":1251},"/de-de/assessments/devops-modernization-assessment/",{"config":1784},{"src":1785},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":1787,"categories":1788,"header":1790,"text":1765,"button":1791,"image":1795},"security-modernization",[1789],"security","Tauschst du Schnelligkeit gegen Sicherheit ein?",{"text":1792,"config":1793},"Ermittle deinen Sicherheitsreifegrad",{"href":1794,"dataGaName":1770,"dataGaLocation":1251},"/de-de/assessments/security-modernization-assessment/",{"config":1796},{"src":1797},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":1799,"paths":1800,"header":1803,"text":1804,"button":1805,"image":1810},"github-azure-migration",[1801,1802],"migration-from-azure-devops-to-gitlab","integrating-azure-devops-scm-and-gitlab","Ist dein Team bereit für den Umzug von GitHub nach Azure?","GitHub stellt bereits auf Azure um. Finde heraus, was das für dich bedeutet.",{"text":1806,"config":1807},"Erfahre, wie GitLab im Vergleich zu GitHub abschneidet",{"href":1808,"dataGaName":1809,"dataGaLocation":1251},"/de-de/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":1811},{"src":1785},{"header":1813,"blurb":1814,"button":1815,"secondaryButton":1820},"Beginne noch heute, schneller zu entwickeln","Entdecke, was dein Team mit der intelligenten Orchestrierungsplattform für DevSecOps erreichen kann.\n",{"text":1816,"config":1817},"Kostenlosen Test starten",{"href":1818,"dataGaName":1048,"dataGaLocation":1819},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/de-de/","feature",{"text":1374,"config":1821},{"href":1376,"dataGaName":1053,"dataGaLocation":1819},1786803748286]