[{"data":1,"prerenderedAt":704},["ShallowReactive",2],{"/ja-jp/blog/a-beginners-guide-to-the-git-reftable-format/":3,"navigation-ja-jp":39,"banner-ja-jp":454,"footer-ja-jp":466,"Patrick Steinhardt":676,"next-steps-ja-jp":689},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"seo":8,"content":16,"config":28,"_id":32,"_type":33,"title":34,"_source":35,"_file":36,"_stem":37,"_extension":38},"/ja-jp/blog/a-beginners-guide-to-the-git-reftable-format","blog",false,"",{"title":9,"description":10,"ogTitle":9,"ogDescription":10,"noIndex":6,"ogImage":11,"ogUrl":12,"ogSiteName":13,"ogType":14,"canonicalUrls":12,"schema":15},"初心者向けGit reftableフォーマットガイド","Git 2.45.0では、GitLabがreftableバックエンドをGitに取り込んだことで、参照の保存方法が完全に変更されました。この新しいフォーマットの内部の仕組みを詳しく見てみましょう。","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664595/Blog/Hero%20Images/blog-image-template-1800x945__9_.png","https://about.gitlab.com/blog/a-beginners-guide-to-the-git-reftable-format","https://about.gitlab.com","article","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"初心者向けGit reftableフォーマットガイド\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Patrick Steinhardt\"}],\n        \"datePublished\": \"2024-05-30\",\n      }",{"title":9,"description":10,"authors":17,"heroImage":11,"date":19,"body":20,"category":21,"tags":22,"updatedDate":27},[18],"Patrick Steinhardt","2024-05-30","最近まで、Gitでの参照の保存方法は、「files」フォーマットだけに限られていましたが、[Git 2.45.0の新機能](https://about.gitlab.com/ja-jp/blog/whats-new-in-git-2-45-0/)により、Gitでは参照を「reftable」フォーマットで保存できるようになりました。この新しいフォーマットは、バイナリフォーマットで非常に複雑ですが、その複雑さが「files」フォーマットのいくつかの欠点を解決します。「reftable」フォーマットは、次のような目的で設計されました。\n\n- 単一の参照の検索と参照範囲のイテレーションを、可能な限り効率的かつ迅速に行えるようにする。\n- 複数の参照が部分的にしか更新されていない中途半端な状態をGitが読み取らないように、一貫した参照の読み取りをサポートする。\n- 複数の参照の更新がオールオアナッシング型のオペレーションとして実行される、アトミック書き込みをサポートする。\n- 参照および参照ログの効率的な保存。\n\nこの記事では、「reftable」フォーマットの仕組みを詳しく見ていきます。\n\n## Gitでの参照の保存方法\n\n「reftable」フォーマットについて詳しく掘り下げる前に、まずはGitがこれまで参照をどのように保存してきたのかを簡単に振り返ってみましょう。すでにご存知の方は、このセクションを読み飛ばして構いません。\n\nGitリポジトリは、次の重要な2つのデータ構造を追跡します。\n\n- [オブジェクト](https://git-scm.com/book/en/v2/Git-Internals-Git-Objects)：リポジトリの実際のデータ（コミット、ディレクトリツリー構造、ソースコードを含むblobなど）を格納しています。オブジェクトは互いに参照し合い、オブジェクトグラフを形成します。さらに、各オブジェクトにはオブジェクトIDがあり、そのオブジェクトを一意に識別します。\n\n- 参照：ブランチやタグなどがあります。これらはオブジェクトグラフへのポインタであり、オブジェクトに覚えやすい名前を付けたり、開発履歴の異なるトラックを追跡するのに使われます。たとえば、リポジトリには`main`ブランチが含まれている場合があり、これは特定のコミットを指し示す`refs/heads/main`という名前の参照です。\n\n参照は、参照データベースに保存されます。Git 2.45.0までは、「files」データベースフォーマットのみが存在していました。このフォーマットでは、各参照が通常のファイルとして保存され、そのファイルには次のいずれかが含まれます。\n\n- 通常の参照：指し示すコミットのオブジェクトIDが保存されています。\n- シンボリック参照：別の参照の名前が保存されています。これは、シンボリックリンクが別のファイルを指し示すのと似ています。\n\n定期的に、これらの参照は検索を効率化するために1つのpacked-refsファイルにまとめられます。\n\n次の例は、「files」フォーマットがどのように動作するかを示しています。\n\n```shell\n$ git init .\n$ git commit --allow-empty --message \"Initial commit\"\n[main (root-commit) 6917c17] Initial commit\n\n# HEADはrefs/heads/mainを指すシンボリック参照です。\n$ cat .git/HEAD\nref: refs/heads/main\n\n# refs/heads/mainはコミットを指す通常の参照です。\n$ cat .git/refs/heads/main\n6917c178cfc3c50215a82cf959204e9934af24c8\n\n# git-pack-refs(1)はこれらの参照をpacked-refsファイルにパック化します。\n$ git pack-refs --all\n$ cat .git/packed-refs\n# pack-refs with: peeled fully-peeled sorted\n```\n\n## reftableフォーマットの構造概要\n\nGit 2.45.0以降がインストールされている場合、`--ref-format=reftable`スイッチを使用して「reftable」フォーマットでリポジトリを作成できます。\n\n```shell\n$ git init --ref-format=reftable .\nInitialized empty Git repository in /tmp/repo/.git/\n$ git rev-parse --show-ref-format\nreftable\n\n# わかりやすくするために不要なファイルを削除しています。\n$ tree .git\n.git\n├── config\n├── HEAD\n├── index\n├── objects\n├── refs\n│   └── heads\n└── reftable\n\t├── 0x000000000001-0x000000000002-40a482a9.ref\n\t└── tables.list\n\n4 directories, 6 files\n```\n\nまず、リポジトリの設定を見ると、それには`extension.refstorage`キーがあります。\n\n```shell\n$ cat .git/config\n[core]\n    repositoryformatversion = 1\n    filemode = true\n    bare = false\n    logallrefupdates = true\n[extensions]\n    refstorage = reftable\n```\n\nこの設定は、リポジトリが「reftable」フォーマットで初期化されており、「reftable」バックエンドを使用してアクセスするようGitに指示するものです。\n\n不思議なことに、このリポジトリにはまだ「files」バックエンドが使われているかのように見えるいくつかのファイルがあります。\n\n- `HEAD`は通常、現在チェックアウト済みのブランチを指すシンボリック参照です。「reftable」バックエンドでは使用されませんが、GitクライアントがディレクトリをGitリポジトリとして検出するために必要です。したがって、「reftable」フォーマットを使用する場合、`HEAD`は`ref: refs/heads/.invalid`という内容のスタブになります。\n\n- `refs/heads`は、`this repository uses the reftable format`という内容が書かれているファイルです。「reftable」フォーマットを認識できないGitクライアントは、このパスがディレクトリであると想定します。したがって、このパスをファイルとして作成することで、古いGitクライアントが「files」バックエンドでリポジトリにアクセスしようとすると、意図的に失敗するようになります。\n\n実際の参照は、次のように`reftable/`ディレクトリに保存されます。\n\n```shell\n$ 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```\n\nここには、次の2つのファイルがあります。\n\n- `0x000000000001-0x000000000001-794bd722.ref`は、参照と参照ログデータをバイナリフォーマットで含むテーブルです。\n\n- `tables.list`は、テーブルのリストです。リポジトリの現在の状態では、このファイルにはテーブルの名前の1行だけが含まれています。このファイルは「reftable」データベースにある現在有効なテーブルをまとめて追跡し、新しいテーブルがリポジトリに追加されるたびに更新されます。\n\n次のように、参照を更新すると、新しいテーブルが作成されます。\n\n```shell\n$ 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```\n\nご覧のとおり、以前のテーブルは新しいテーブルに置き換えられました。さらに、`tables.list`ファイルが更新され、新しいテーブルが取り込まれました。\n\n## テーブルの構造\n\n前述のとおり、参照データベースの実際のデータはテーブルに含まれています。テーブルは大まかに次のような複数のセクションに分かれています。\n\n- header：テーブルに関するメタデータが含まれています。これには、フォーマットのバージョン、ブロックサイズ、およびリポジトリで使用されるハッシュ関数（SHA1、SHA256など）が、他の情報と一緒に含まれています。\n- ref：参照が含まれています。これらのレコードは参照名と等しいキーを有し、通常の参照の場合はオブジェクトIDを、シンボリック参照の場合は他の参照を指します。\n- obj：オブジェクトIDからそれらのオブジェクトIDを指す参照への逆マッピングが含まれています。これにより、Gitは特定のオブジェクトIDを指す参照を効率的に検索できます。\n- log：参照ログエントリが含まれています。これらのレコードは、参照名にログエントリの番号を表すインデックスを付け足したものと等しいキーを有し、 さらに、古いオブジェクトIDと新しいオブジェクトID、およびその参照ログエントリのメッセージを含みます。\n- footer：各セクションへのオフセットが含まれます。\n\n![すべてのreftableセクションを含んだ縦長の表](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675179/Blog/Content%20Images/Frame_1_-_Reftable_overview.svg)\n\n各セクションのタイプは、似たような構造を持っています。セクションには一連のレコードが含まれており、各レコードのキーでソートされています。たとえば、 `refs/heads/aaaaa`と `refs/heads/bbb`という2つの参照レコードがある場合、これらの参照名がそれぞれのキーとなり、`refs/heads/aaaaa`が`refs/heads/bbb`よりも前に来ます。\n\nさらに、各セクションは固定長のブロックに分割されています。このブロックの長さはヘッダー（header）にエンコードされており、次の2つの目的を果たします。\n\n- セクションの開始位置とブロックサイズに基づき、リーダー（reader）は各ブロックの開始位置を暗に認識します。これにより、Gitは先行するブロックを読み込むことなくセクションの途中に簡単に移動できるため、ブロック上でのバイナリ検索が可能になり、レコードの検索を高速化します。\n- 一度に読み込むディスクデータの量をリーダーが認識できるようにします。このために、ブロックサイズはデフォルトで4KiBに設定されており、これはハードディスクのセクターサイズとしては最も一般的です。最大ブロックサイズは16MBです。\n\nたとえば、「ref」セクションを覗いてみると、おおよそ次の図のようになります。ここで留意すべき点は、レコードがブロック内で、そしてブロック間の両方で辞書順に並んでいることです。\n\n![未圧縮参照ブロック](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675179/Blog/Content%20Images/Frame_2_-_Ref_block_uncompressed.svg)\n\n現在の情報を基に、次の手順でレコードを検索できます。\n\n1. 各ブロックの最初のレコードのキーを確認してバイナリ検索を行い、目的のレコードが含まれているブロックを特定します。\n\n2. 特定したブロック内で線形検索を行い、目的のレコードを特定します。\n\nこの手順はまだ少し非効率です。多くのブロックがある場合、目的のブロックを特定するためにバイナリ検索で対数的に多くのブロックを読み込むことが必要になる場合があります。また、ブロックに多数のレコードが含まれている場合、線形検索中にすべてのレコードの読み込みが必要になる可能性もあります。\n\n「reftable」フォーマットには、これらのパフォーマンス問題に対処する追加のメカニズムが組み込まれています。後のセクションでこれらについて詳しく説明します。\n\n### プレフィックス圧縮\n\nお気づきかもしれませんが、すべてのレコードキーには`refs/`という共通のプレフィックスがあります。これはGitでは一般的です。\n\n- すべてのブランチは`refs/heads/`で始まります。\n- すべてのタグは`refs/tags /`で始まります。\n\nしたがって、後続のレコードもキーの大部分で共通のプレフィックスを持つことが予想されます。これを利用して、貴重なディスク容量を節約できます。ほとんどのキーが共通のプレフィックスを持つことがわかっているため、これを最適化するのは理にかなっています。\n\nこの最適化にはプレフィックス圧縮を使用します。各レコードは、前のレコードのキーから何バイトを再利用するかを示すプレフィックスの長さがエンコードされています。たとえば、`refs/heads/a`と`refs/heads/b`という2つのレコードがある場合、後者はプレフィックスの長さを11バイトとしてエンコードし、サフィックスとして`b`だけを保存します。その後、リーダーは`refs/heads/a`の最初の11バイト（`refs/heads/`）を取得し、サフィックス`b`を追加します。\n\n![プレフィックス圧縮](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675179/Blog/Content%20Images/Frame_3_-_Ref_block_prefix_compression.svg)\n\n### 再起点\n\n前述のように、現在の「reftable」フォーマットの理解に基づいてブロック内の参照を検索する最適な方法は、線形検索です。これは、レコードが固定長ではないため、ブロックの先頭からスキャンしないとレコードの開始位置を特定できないためです。また、レコードが固定長であったとしても、レフィックス圧縮があるため、先行するレコードを読み込む必要があり、ブロックの途中に直接移動はできません。 \n\nしかし、ブロックには数百から数千のレコードが含まれる可能性があり、線形検索は非常に非効率です。この問題に対処するために、「reftable」フォーマットは各ブロックに「再起点」と呼ばれるポイントをエンコードします。再起点は圧縮されていないレコードであり、ここではプレフィックス圧縮がリセットされます。したがって、再起点のレコードは常に完全なキーを含んでおり、先行するレコードをスキップしながら直接移動してレコードを読み込むことが可能になります。これらの再起点は各ブロックのフッターにリストされています。\n\nこの情報を用いることで、ブロック全体を線形検索する必要がなくなります。代わりに、再起点のバイナリ検索を行い、目的のキーより大きい最初の再起点を探します。そこから、目的のレコードが_前の_再起点から特定された再起点までのセクションに存在することがわかります。\n\nしたがって、レコードを検索する最初の手順（ブロックのバイナリ検索、レコードの線形検索）は次のようになります。\n\n1. ブロックのバイナリ検索を行い、目的のレコードが含まれるブロックを特定します。\n\n2. 再起点のバイナリ検索を行い、目的のレコードが含まれるブロックのサブセクションを特定します。\n\n3. 特定したサブセクション内でレコードの線形検索を行います。\n\n![レコードの線形検索](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675179/Blog/Content%20Images/Frame_4_-_Restart_points.svg)\n\n### インデックス\n\nブロック内のレコードの検索はかなり効率化されましたが、ブロック自体の位置を特定するのはまだ効率的とはいえません。数個のブロックであればバイナリ検索でも十分に効率的です。しかし、数百万もの参照を含むリポジトリには数百から数千のブロックが存在します。この場合、追加のデータ構造がなければ、平均して対数的に多くのディスクアクセスが必要になります。\n\nこの問題を避けるために、各セクションの後にブロックを効率的に検索するためのインデックスセクションを追加できます。各インデックスレコードには次の情報が含まれます。\n\n- インデックス化されているブロックの位置。\n- インデックス化されているブロックの最後のレコードのキー。\n\n3つ以下のブロックであれば、バイナリ検索は最大2回のディスク読み取りで目的のブロックを特定できます。この読み取り回数は、インデックスを使用する場合も同じです。具体的には、インデックス自体を読み取るための1回と、目的のブロックを読む取るための1回です。したがって、インデックスは実際に読み取り回数を減らす場合、つまりインデックス化されたブロックが4つ以上ある場合にのみ作成されます。\n\n次の疑問は、インデックス自体が複数のブロックにまたがるほど大きくなった場合はどうすべきかという点です。その答えは、そのインデックスをインデックス化するために別のインデックスを作成するというものです。この複数階層のインデックスは、数十万もの参照があるリポジトリでのみ必要となります。\n\n次のインデックスを使用することで、レコードの検索手順をさらに効率化できます。\n1. テーブルのフッターを見てインデックスがあるかどうかを確認します。\n\t- インデックスがあれば、バイナリ検索を行い、目的のブロックを特定します。このブロックがインデックスブロック自体を指している場合は、目的のレコードタイプに到達するまでこの手順を繰り返します。\n\t- インデックスがなければ、先ほどのようにブロックのバイナリ検索を行います。\n2. 再起点のバイナリ検索を行い、目的のレコードが含まれているブロックのサブセクションを特定します。\n3. 特定したサブセクション内でレコードの線形検索を行います。\n\n## 複数のテーブル\n\nここまでは、単一のテーブルを読み取る方法について説明してきましたが、`tables.list`という名前が示すように、「reftable」データベースには複数のテーブルを格納できます。\n\nリポジトリ内の参照を更新するたびに、新しいテーブルが作成され、`tables.list`に追加されます。したがって、最終的には次のように複数のテーブルが存在することになります。\n\n```shell\n$ 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```\n\nリポジトリの実際の状態を読み取るためには、これらの複数のテーブルを単一の仮想テーブルにマージする必要があります。\n\nここで疑問が生じます。それは、参照が更新されるたびにテーブルが作成され、同じ参照が複数回更新される場合、「reftable」フォーマットは特定の参照の最新の値をどのように把握するのか、ということです。直感的には、最新のテーブルに含まれる参照の値が最新であると仮定できます。\n\n実際には、各レコードには「更新インデックス」と呼ばれるものがあり、これがレコードの「優先度」をエンコードしています。たとえば、同じ名前の2つの参照レコードが存在する場合、更新インデックスが高い方が低い方を上書きします。\n\nこれらの更新インデックスは、上のファイル構造で確認できます。長い16進文字列（例：`0x000000000001`）が更新インデックスであり、テーブル名の左側がテーブルに含まれる最小の更新インデックス、そして右側が最大の更新インデックスを示しています。\n\nテーブルのマージは、参照レコードのキーと更新インデックスによって順序付けられた[優先キュー](https://en.wikipedia.org/wiki/Priority_queue)を介して行われます。すべての参照レコードをスキャンする場合、次の手順で行います。\n\n1. 各テーブルの最初のレコードを優先キューに追加します。\n\n![優先キューに最初のレコードを追加する](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675179/Blog/Content%20Images/Frame_5_-_Priority_queue_1.svg)\n\n2. 優先キューの先頭を取り出します。このキューは更新インデックス順に並んでいるため、先頭にあるレコードは最新のバージョンでなければなりません。そのテーブルの次の項目を優先キューに追加します。\n\n![優先キューの先頭を取り出す](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675179/Blog/Content%20Images/Frame_6_-_Priority_queue_2.svg)\n\n3. 同じ名前を持つすべてのレコードをキューから削除します。これらのレコードは上書きされているため表示されません。レコードを削除した各テーブルについては、その次のレコードを優先キューに追加します。\n\n![同じ名前を持つすべてのレコードをキューから削除する](https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675179/Blog/Content%20Images/Frame_7_-_Priority_queue_3.svg)\n\nこれを繰り返して、他のキーのレコードを読み取ります。\n\nテーブルには、レコードが削除されたことを示す特殊な「トゥームストーン」レコードが含まれている場合があります。このように、すべてのテーブルを書き換えることなく、レコードを削除できます。\n\n### 自動圧縮\n\n優先キューの考え方はシンプルですが、このアプローチでは、マージするテーブルの数が数百個、あるいは数十個であっても、非常に非効率になります。参照を更新するたびに新しいテーブルが`tables.list`ファイルに付加されるのは事実ですが、他にも重要な特徴があります。\n\nそれが、自動圧縮です。新しいテーブルがテーブルリストに付加された後、「reftable」バックエンドは一部のテーブルをマージする必要があるかどうかを確認します。これは、シンプルなルールを使って行われます。具体的には、テーブルのリストがファイルサイズの[幾何数列](https://en.wikipedia.org/wiki/Geometric_progression)を形成しているかどうかをチェックします。すべてのテーブル`n`は、その次に新しいテーブル`n+1`の2倍以上のサイズでなければなりません。この幾何数列が維持されなかった場合、バックエンドはテーブルを圧縮して幾何数列を復元します。\n\n時間が経つにつれて、次のような構造になります。\n\n```shell\n$ 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```\n\nすべてのテーブルにおいて、`size(n) > size(n+1) * 2`という性質が維持されていることに注目してください。\n\n自動圧縮がもたらすメリットのひとつは、「reftable」バックエンドのメンテナンスが自動化されることです。これにより、リポジトリで`git pack-refs`を実行する必要がなくなります。\n\n## さらに詳しく知りたい方へ\n\nこの記事では、新しい「reftable」フォーマットの仕組みについて解説しました。さらに詳しく知りたい場合は、Gitプロジェクトで提供される[テクニカルドキュメント](https://git-scm.com/docs/reftable)をご参照ください。\n\n> [Git 2.45.0の新機能](https://about.gitlab.com/ja-jp/blog/whats-new-in-git-2-45-0/)では、このバージョンにおけるその他の変更点をご確認いただけます。\n\n*監修：川瀬 洋平 [@ykawase](https://gitlab.com/ykawase)\u003Cbr>\n（GitLab合同会社 カスタマーサクセス本部 シニアカスタマーサクセスマネージャー）*\n","open-source",[23,24,25,26],"git","tutorial","open source","performance","2025-02-04",{"slug":29,"featured":30,"template":31},"a-beginners-guide-to-the-git-reftable-format",true,"BlogPost","content:ja-jp:blog:a-beginners-guide-to-the-git-reftable-format.yml","yaml","A Beginners Guide To The Git Reftable Format","content","ja-jp/blog/a-beginners-guide-to-the-git-reftable-format.yml","ja-jp/blog/a-beginners-guide-to-the-git-reftable-format","yml",{"_path":40,"_dir":41,"_draft":6,"_partial":6,"_locale":7,"data":42,"_id":450,"_type":33,"title":451,"_source":35,"_file":452,"_stem":453,"_extension":38},"/shared/ja-jp/main-navigation","ja-jp",{"logo":43,"freeTrial":48,"sales":53,"login":58,"items":63,"search":394,"minimal":428,"duo":441},{"config":44},{"href":45,"dataGaName":46,"dataGaLocation":47},"/ja-jp/","gitlab logo","header",{"text":49,"config":50},"無料トライアルを開始",{"href":51,"dataGaName":52,"dataGaLocation":47},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":54,"config":55},"お問い合わせ",{"href":56,"dataGaName":57,"dataGaLocation":47},"/ja-jp/sales/","sales",{"text":59,"config":60},"サインイン",{"href":61,"dataGaName":62,"dataGaLocation":47},"https://gitlab.com/users/sign_in/","sign in",[64,108,206,211,316,376],{"text":65,"config":66,"cards":68,"footer":91},"プラットフォーム",{"dataNavLevelOne":67},"platform",[69,75,83],{"title":65,"description":70,"link":71},"最も包括的かつAIで強化されたDevSecOpsプラットフォーム",{"text":72,"config":73},"プラットフォームを詳しく見る",{"href":74,"dataGaName":67,"dataGaLocation":47},"/ja-jp/platform/",{"title":76,"description":77,"link":78},"GitLab Duo（AI）","開発のすべてのステージでAIを活用し、ソフトウェアをより迅速にビルド",{"text":79,"config":80},"GitLab Duoのご紹介",{"href":81,"dataGaName":82,"dataGaLocation":47},"/ja-jp/gitlab-duo/","gitlab duo ai",{"title":84,"description":85,"link":86},"GitLabが選ばれる理由","GitLabが大企業に選ばれる理由10選",{"text":87,"config":88},"詳細はこちら",{"href":89,"dataGaName":90,"dataGaLocation":47},"/ja-jp/why-gitlab/","why gitlab",{"title":92,"items":93},"利用を開始：",[94,99,104],{"text":95,"config":96},"プラットフォームエンジニアリング",{"href":97,"dataGaName":98,"dataGaLocation":47},"/ja-jp/solutions/platform-engineering/","platform engineering",{"text":100,"config":101},"開発者の経験",{"href":102,"dataGaName":103,"dataGaLocation":47},"/ja-jp/developer-experience/","Developer experience",{"text":105,"config":106},"MLOps",{"href":107,"dataGaName":105,"dataGaLocation":47},"/ja-jp/topics/devops/the-role-of-ai-in-devops/",{"text":109,"left":30,"config":110,"link":112,"lists":116,"footer":188},"製品",{"dataNavLevelOne":111},"solutions",{"text":113,"config":114},"すべてのソリューションを表示",{"href":115,"dataGaName":111,"dataGaLocation":47},"/ja-jp/solutions/",[117,143,166],{"title":118,"description":119,"link":120,"items":125},"自動化","CI/CDと自動化でデプロイを加速",{"config":121},{"icon":122,"href":123,"dataGaName":124,"dataGaLocation":47},"AutomatedCodeAlt","/ja-jp/solutions/delivery-automation/","automated software delivery",[126,130,134,139],{"text":127,"config":128},"CI/CD",{"href":129,"dataGaLocation":47,"dataGaName":127},"/ja-jp/solutions/continuous-integration/",{"text":131,"config":132},"AIアシストによる開発",{"href":81,"dataGaLocation":47,"dataGaName":133},"AI assisted development",{"text":135,"config":136},"ソースコード管理",{"href":137,"dataGaLocation":47,"dataGaName":138},"/ja-jp/solutions/source-code-management/","Source Code Management",{"text":140,"config":141},"自動化されたソフトウェアデリバリー",{"href":123,"dataGaLocation":47,"dataGaName":142},"Automated software delivery",{"title":144,"description":145,"link":146,"items":151},"セキュリティ","セキュリティを損なうことなくコードをより迅速に完成",{"config":147},{"href":148,"dataGaName":149,"dataGaLocation":47,"icon":150},"/ja-jp/solutions/security-compliance/","security and compliance","ShieldCheckLight",[152,156,161],{"text":153,"config":154},"セキュリティとコンプライアンス",{"href":148,"dataGaLocation":47,"dataGaName":155},"Security & Compliance",{"text":157,"config":158},"ソフトウェアサプライチェーンの安全性",{"href":159,"dataGaLocation":47,"dataGaName":160},"/ja-jp/solutions/supply-chain/","Software supply chain security",{"text":162,"config":163},"コンプライアンスとガバナンス",{"href":164,"dataGaLocation":47,"dataGaName":165},"/ja-jp/solutions/continuous-software-compliance/","Compliance and governance",{"title":167,"link":168,"items":173},"測定",{"config":169},{"icon":170,"href":171,"dataGaName":172,"dataGaLocation":47},"DigitalTransformation","/ja-jp/solutions/visibility-measurement/","visibility and measurement",[174,178,183],{"text":175,"config":176},"可視性と測定",{"href":171,"dataGaLocation":47,"dataGaName":177},"Visibility and Measurement",{"text":179,"config":180},"バリューストリーム管理",{"href":181,"dataGaLocation":47,"dataGaName":182},"/ja-jp/solutions/value-stream-management/","Value Stream Management",{"text":184,"config":185},"分析とインサイト",{"href":186,"dataGaLocation":47,"dataGaName":187},"/ja-jp/solutions/analytics-and-insights/","Analytics and insights",{"title":189,"items":190},"GitLabが活躍する場所",[191,196,201],{"text":192,"config":193},"Enterprise",{"href":194,"dataGaLocation":47,"dataGaName":195},"/ja-jp/enterprise/","enterprise",{"text":197,"config":198},"スモールビジネス",{"href":199,"dataGaLocation":47,"dataGaName":200},"/ja-jp/small-business/","small business",{"text":202,"config":203},"公共機関",{"href":204,"dataGaLocation":47,"dataGaName":205},"/ja-jp/solutions/public-sector/","public sector",{"text":207,"config":208},"価格",{"href":209,"dataGaName":210,"dataGaLocation":47,"dataNavLevelOne":210},"/ja-jp/pricing/","pricing",{"text":212,"config":213,"link":215,"lists":219,"feature":303},"関連リソース",{"dataNavLevelOne":214},"resources",{"text":216,"config":217},"すべてのリソースを表示",{"href":218,"dataGaName":214,"dataGaLocation":47},"/ja-jp/resources/",[220,253,275],{"title":221,"items":222},"はじめに",[223,228,233,238,243,248],{"text":224,"config":225},"インストール",{"href":226,"dataGaName":227,"dataGaLocation":47},"/ja-jp/install/","install",{"text":229,"config":230},"クイックスタートガイド",{"href":231,"dataGaName":232,"dataGaLocation":47},"/ja-jp/get-started/","quick setup checklists",{"text":234,"config":235},"学ぶ",{"href":236,"dataGaLocation":47,"dataGaName":237},"https://university.gitlab.com/","learn",{"text":239,"config":240},"製品ドキュメント",{"href":241,"dataGaName":242,"dataGaLocation":47},"https://docs.gitlab.com/","product documentation",{"text":244,"config":245},"ベストプラクティスビデオ",{"href":246,"dataGaName":247,"dataGaLocation":47},"/ja-jp/getting-started-videos/","best practice videos",{"text":249,"config":250},"インテグレーション",{"href":251,"dataGaName":252,"dataGaLocation":47},"/ja-jp/integrations/","integrations",{"title":254,"items":255},"検索する",[256,261,265,270],{"text":257,"config":258},"お客様成功事例",{"href":259,"dataGaName":260,"dataGaLocation":47},"/ja-jp/customers/","customer success stories",{"text":262,"config":263},"ブログ",{"href":264,"dataGaName":5,"dataGaLocation":47},"/ja-jp/blog/",{"text":266,"config":267},"リモート",{"href":268,"dataGaName":269,"dataGaLocation":47},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"text":271,"config":272},"TeamOps",{"href":273,"dataGaName":274,"dataGaLocation":47},"/ja-jp/teamops/","teamops",{"title":276,"items":277},"つなげる",[278,283,288,293,298],{"text":279,"config":280},"GitLabサービス",{"href":281,"dataGaName":282,"dataGaLocation":47},"/ja-jp/services/","services",{"text":284,"config":285},"コミュニティ",{"href":286,"dataGaName":287,"dataGaLocation":47},"/community/","community",{"text":289,"config":290},"フォーラム",{"href":291,"dataGaName":292,"dataGaLocation":47},"https://forum.gitlab.com/","forum",{"text":294,"config":295},"イベント",{"href":296,"dataGaName":297,"dataGaLocation":47},"/events/","events",{"text":299,"config":300},"パートナー",{"href":301,"dataGaName":302,"dataGaLocation":47},"/ja-jp/partners/","partners",{"backgroundColor":304,"textColor":305,"text":306,"image":307,"link":311},"#2f2a6b","#fff","ソフトウェア開発の未来への洞察",{"altText":308,"config":309},"ソースプロモカード",{"src":310},"/images/navigation/the-source-promo-card.svg",{"text":312,"config":313},"最新情報を読む",{"href":314,"dataGaName":315,"dataGaLocation":47},"/ja-jp/the-source/","the source",{"text":317,"config":318,"lists":320},"Company",{"dataNavLevelOne":319},"company",[321],{"items":322},[323,328,334,336,341,346,351,356,361,366,371],{"text":324,"config":325},"GitLabについて",{"href":326,"dataGaName":327,"dataGaLocation":47},"/ja-jp/company/","about",{"text":329,"config":330,"footerGa":333},"採用情報",{"href":331,"dataGaName":332,"dataGaLocation":47},"/jobs/","jobs",{"dataGaName":332},{"text":294,"config":335},{"href":296,"dataGaName":297,"dataGaLocation":47},{"text":337,"config":338},"経営陣",{"href":339,"dataGaName":340,"dataGaLocation":47},"/company/team/e-group/","leadership",{"text":342,"config":343},"チーム",{"href":344,"dataGaName":345,"dataGaLocation":47},"/company/team/","team",{"text":347,"config":348},"ハンドブック",{"href":349,"dataGaName":350,"dataGaLocation":47},"https://handbook.gitlab.com/","handbook",{"text":352,"config":353},"投資家向け情報",{"href":354,"dataGaName":355,"dataGaLocation":47},"https://ir.gitlab.com/","investor relations",{"text":357,"config":358},"トラストセンター",{"href":359,"dataGaName":360,"dataGaLocation":47},"/ja-jp/security/","trust center",{"text":362,"config":363},"AI Transparency Center",{"href":364,"dataGaName":365,"dataGaLocation":47},"/ja-jp/ai-transparency-center/","ai transparency center",{"text":367,"config":368},"ニュースレター",{"href":369,"dataGaName":370,"dataGaLocation":47},"/company/contact/","newsletter",{"text":372,"config":373},"プレス",{"href":374,"dataGaName":375,"dataGaLocation":47},"/press/","press",{"text":54,"config":377,"lists":378},{"dataNavLevelOne":319},[379],{"items":380},[381,384,389],{"text":54,"config":382},{"href":56,"dataGaName":383,"dataGaLocation":47},"talk to sales",{"text":385,"config":386},"サポートを受ける",{"href":387,"dataGaName":388,"dataGaLocation":47},"/support/","get help",{"text":390,"config":391},"カスタマーポータル",{"href":392,"dataGaName":393,"dataGaLocation":47},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":395,"login":396,"suggestions":403},"閉じる",{"text":397,"link":398},"リポジトリとプロジェクトを検索するには、次にログインします",{"text":399,"config":400},"GitLab.com",{"href":61,"dataGaName":401,"dataGaLocation":402},"search login","search",{"text":404,"default":405},"提案",[406,409,414,416,420,424],{"text":76,"config":407},{"href":81,"dataGaName":408,"dataGaLocation":402},"GitLab Duo (AI)",{"text":410,"config":411},"コード提案（AI）",{"href":412,"dataGaName":413,"dataGaLocation":402},"/ja-jp/solutions/code-suggestions/","Code Suggestions (AI)",{"text":127,"config":415},{"href":129,"dataGaName":127,"dataGaLocation":402},{"text":417,"config":418},"GitLab on AWS",{"href":419,"dataGaName":417,"dataGaLocation":402},"/ja-jp/partners/technology-partners/aws/",{"text":421,"config":422},"GitLab on Google Cloud",{"href":423,"dataGaName":421,"dataGaLocation":402},"/ja-jp/partners/technology-partners/google-cloud-platform/",{"text":425,"config":426},"GitLabを選ぶ理由",{"href":89,"dataGaName":427,"dataGaLocation":402},"Why GitLab?",{"freeTrial":429,"mobileIcon":433,"desktopIcon":438},{"text":49,"config":430},{"href":431,"dataGaName":52,"dataGaLocation":432},"https://gitlab.com/-/trials/new/","nav",{"altText":434,"config":435},"GitLabアイコン",{"src":436,"dataGaName":437,"dataGaLocation":432},"/images/brand/gitlab-logo-tanuki.svg","gitlab icon",{"altText":434,"config":439},{"src":440,"dataGaName":437,"dataGaLocation":432},"/images/brand/gitlab-logo-type.svg",{"freeTrial":442,"mobileIcon":446,"desktopIcon":448},{"text":443,"config":444},"GitLab Duoの詳細について",{"href":81,"dataGaName":445,"dataGaLocation":432},"gitlab duo",{"altText":434,"config":447},{"src":436,"dataGaName":437,"dataGaLocation":432},{"altText":434,"config":449},{"src":440,"dataGaName":437,"dataGaLocation":432},"content:shared:ja-jp:main-navigation.yml","Main Navigation","shared/ja-jp/main-navigation.yml","shared/ja-jp/main-navigation",{"_path":455,"_dir":41,"_draft":6,"_partial":6,"_locale":7,"title":456,"button":457,"config":461,"_id":463,"_type":33,"_source":35,"_file":464,"_stem":465,"_extension":38},"/shared/ja-jp/banner","GitLab Duo Agent Platformがパブリックベータ版で利用可能になりました！",{"text":87,"config":458},{"href":459,"dataGaName":460,"dataGaLocation":47},"/ja-jp/gitlab-duo/agent-platform/","duo banner",{"layout":462},"release","content:shared:ja-jp:banner.yml","shared/ja-jp/banner.yml","shared/ja-jp/banner",{"_path":467,"_dir":41,"_draft":6,"_partial":6,"_locale":7,"data":468,"_id":672,"_type":33,"title":673,"_source":35,"_file":674,"_stem":675,"_extension":38},"/shared/ja-jp/main-footer",{"text":469,"source":470,"edit":476,"contribute":481,"config":486,"items":491,"minimal":664},"GitはSoftware Freedom Conservancyの商標です。当社は「GitLab」をライセンスに基づいて使用しています",{"text":471,"config":472},"ページのソースを表示",{"href":473,"dataGaName":474,"dataGaLocation":475},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":477,"config":478},"このページを編集",{"href":479,"dataGaName":480,"dataGaLocation":475},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":482,"config":483},"ご協力をお願いします",{"href":484,"dataGaName":485,"dataGaLocation":475},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":487,"facebook":488,"youtube":489,"linkedin":490},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[492,515,569,602,636],{"title":65,"links":493,"subMenu":498},[494],{"text":495,"config":496},"DevSecOpsプラットフォーム",{"href":74,"dataGaName":497,"dataGaLocation":475},"devsecops platform",[499],{"title":207,"links":500},[501,505,510],{"text":502,"config":503},"プランの表示",{"href":209,"dataGaName":504,"dataGaLocation":475},"view plans",{"text":506,"config":507},"Premiumを選ぶ理由",{"href":508,"dataGaName":509,"dataGaLocation":475},"/ja-jp/pricing/premium/","why premium",{"text":511,"config":512},"Ultimateを選ぶ理由",{"href":513,"dataGaName":514,"dataGaLocation":475},"/ja-jp/pricing/ultimate/","why ultimate",{"title":516,"links":517},"ソリューション",[518,523,526,528,533,538,542,545,548,553,555,557,559,564],{"text":519,"config":520},"デジタルトランスフォーメーション",{"href":521,"dataGaName":522,"dataGaLocation":475},"/ja-jp/topics/digital-transformation/","digital transformation",{"text":153,"config":524},{"href":148,"dataGaName":525,"dataGaLocation":475},"security & compliance",{"text":140,"config":527},{"href":123,"dataGaName":124,"dataGaLocation":475},{"text":529,"config":530},"アジャイル開発",{"href":531,"dataGaName":532,"dataGaLocation":475},"/ja-jp/solutions/agile-delivery/","agile delivery",{"text":534,"config":535},"クラウドトランスフォーメーション",{"href":536,"dataGaName":537,"dataGaLocation":475},"/ja-jp/topics/cloud-native/","cloud transformation",{"text":539,"config":540},"SCM",{"href":137,"dataGaName":541,"dataGaLocation":475},"source code management",{"text":127,"config":543},{"href":129,"dataGaName":544,"dataGaLocation":475},"continuous integration & delivery",{"text":179,"config":546},{"href":181,"dataGaName":547,"dataGaLocation":475},"value stream management",{"text":549,"config":550},"GitOps",{"href":551,"dataGaName":552,"dataGaLocation":475},"/ja-jp/solutions/gitops/","gitops",{"text":192,"config":554},{"href":194,"dataGaName":195,"dataGaLocation":475},{"text":197,"config":556},{"href":199,"dataGaName":200,"dataGaLocation":475},{"text":202,"config":558},{"href":204,"dataGaName":205,"dataGaLocation":475},{"text":560,"config":561},"教育",{"href":562,"dataGaName":563,"dataGaLocation":475},"/ja-jp/solutions/education/","education",{"text":565,"config":566},"金融サービス",{"href":567,"dataGaName":568,"dataGaLocation":475},"/ja-jp/solutions/finance/","financial services",{"title":212,"links":570},[571,573,575,577,580,582,586,588,590,592,594,596,598,600],{"text":224,"config":572},{"href":226,"dataGaName":227,"dataGaLocation":475},{"text":229,"config":574},{"href":231,"dataGaName":232,"dataGaLocation":475},{"text":234,"config":576},{"href":236,"dataGaName":237,"dataGaLocation":475},{"text":239,"config":578},{"href":241,"dataGaName":579,"dataGaLocation":475},"docs",{"text":262,"config":581},{"href":264,"dataGaName":5},{"text":583,"config":584},"お客様の成功事例",{"href":585,"dataGaLocation":475},"/customers/",{"text":257,"config":587},{"href":259,"dataGaName":260,"dataGaLocation":475},{"text":266,"config":589},{"href":268,"dataGaName":269,"dataGaLocation":475},{"text":279,"config":591},{"href":281,"dataGaName":282,"dataGaLocation":475},{"text":271,"config":593},{"href":273,"dataGaName":274,"dataGaLocation":475},{"text":284,"config":595},{"href":286,"dataGaName":287,"dataGaLocation":475},{"text":289,"config":597},{"href":291,"dataGaName":292,"dataGaLocation":475},{"text":294,"config":599},{"href":296,"dataGaName":297,"dataGaLocation":475},{"text":299,"config":601},{"href":301,"dataGaName":302,"dataGaLocation":475},{"title":317,"links":603},[604,606,608,610,612,614,616,620,625,627,629,631],{"text":324,"config":605},{"href":326,"dataGaName":319,"dataGaLocation":475},{"text":329,"config":607},{"href":331,"dataGaName":332,"dataGaLocation":475},{"text":337,"config":609},{"href":339,"dataGaName":340,"dataGaLocation":475},{"text":342,"config":611},{"href":344,"dataGaName":345,"dataGaLocation":475},{"text":347,"config":613},{"href":349,"dataGaName":350,"dataGaLocation":475},{"text":352,"config":615},{"href":354,"dataGaName":355,"dataGaLocation":475},{"text":617,"config":618},"Sustainability",{"href":619,"dataGaName":617,"dataGaLocation":475},"/sustainability/",{"text":621,"config":622},"ダイバーシティ、インクルージョン、ビロンギング（DIB）",{"href":623,"dataGaName":624,"dataGaLocation":475},"/ja-jp/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":357,"config":626},{"href":359,"dataGaName":360,"dataGaLocation":475},{"text":367,"config":628},{"href":369,"dataGaName":370,"dataGaLocation":475},{"text":372,"config":630},{"href":374,"dataGaName":375,"dataGaLocation":475},{"text":632,"config":633},"現代奴隷制の透明性に関する声明",{"href":634,"dataGaName":635,"dataGaLocation":475},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"title":54,"links":637},[638,640,642,644,649,654,659],{"text":54,"config":639},{"href":56,"dataGaName":57,"dataGaLocation":475},{"text":385,"config":641},{"href":387,"dataGaName":388,"dataGaLocation":475},{"text":390,"config":643},{"href":392,"dataGaName":393,"dataGaLocation":475},{"text":645,"config":646},"ステータス",{"href":647,"dataGaName":648,"dataGaLocation":475},"https://status.gitlab.com/","status",{"text":650,"config":651},"利用規約",{"href":652,"dataGaName":653,"dataGaLocation":475},"/terms/","terms of use",{"text":655,"config":656},"プライバシーに関する声明",{"href":657,"dataGaName":658,"dataGaLocation":475},"/ja-jp/privacy/","privacy statement",{"text":660,"config":661},"Cookieの設定",{"dataGaName":662,"dataGaLocation":475,"id":663,"isOneTrustButton":30},"cookie preferences","ot-sdk-btn",{"items":665},[666,668,670],{"text":650,"config":667},{"href":652,"dataGaName":653,"dataGaLocation":475},{"text":655,"config":669},{"href":657,"dataGaName":658,"dataGaLocation":475},{"text":660,"config":671},{"dataGaName":662,"dataGaLocation":475,"id":663,"isOneTrustButton":30},"content:shared:ja-jp:main-footer.yml","Main Footer","shared/ja-jp/main-footer.yml","shared/ja-jp/main-footer",[677],{"_path":678,"_dir":679,"_draft":6,"_partial":6,"_locale":7,"content":680,"config":684,"_id":686,"_type":33,"title":18,"_source":35,"_file":687,"_stem":688,"_extension":38},"/en-us/blog/authors/patrick-steinhardt","authors",{"name":18,"config":681},{"headshot":682,"ctfId":683},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749661952/Blog/Author%20Headshots/pks-gitlab-headshot.png","pksgitlab",{"template":685},"BlogAuthor","content:en-us:blog:authors:patrick-steinhardt.yml","en-us/blog/authors/patrick-steinhardt.yml","en-us/blog/authors/patrick-steinhardt",{"_path":690,"_dir":41,"_draft":6,"_partial":6,"_locale":7,"header":691,"eyebrow":692,"blurb":693,"button":694,"secondaryButton":698,"_id":700,"_type":33,"title":701,"_source":35,"_file":702,"_stem":703,"_extension":38},"/shared/ja-jp/next-steps","より優れたソフトウェアをより速く提供","フォーチュン100企業の50%以上がGitLabを信頼","インテリジェントなDevSecOpsプラットフォームで\n\n\nチームの可能性を広げましょう。\n",{"text":49,"config":695},{"href":696,"dataGaName":52,"dataGaLocation":697},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":54,"config":699},{"href":56,"dataGaName":57,"dataGaLocation":697},"content:shared:ja-jp:next-steps.yml","Next Steps","shared/ja-jp/next-steps.yml","shared/ja-jp/next-steps",1753475388422]