- 技術 💻
リポジトリとは?Gitの.gitの中身を実物で|apt・npm・Dockerとの違い
結論
リポジトリ(repository)とは「ファイルや部品を、履歴や版といっしょにまとめて保管しておく場所」のことです。Git では「ファイルの中身と変更履歴を丸ごと持つ .git フォルダ」、apt・npm・Maven では「パッケージの配布元」、Docker では「同じイメージの版(タグ)を集めた置き場」、設計では「データの出し入れを受け持つ部品(Repository パターン)」を指します。
この記事でわかること
- Git のリポジトリの中身(.git の HEAD・refs・objects)を git cat-file で開いた実物と、ローカル・リモート・ベアリポジトリの違い
- apt・npm・pip・Maven・Docker の「リポジトリ」が何を指すかを、この環境で動かした出力で見比べた表
- not a git repository・repository not found・dubious ownership などのエラー原文と直し方、どのリポジトリの話かを見分ける判断表
「リポジトリ」は英語の repository(貯蔵庫・倉庫)をカタカナにした言葉です。IT ではどの文脈でも「あとで取り出せるように、きちんと整理して保管しておく場所」という意味で使われます。ただし、何を保管するかで中身がまったく違うので、まず「どのリポジトリの話か」を見分けるのが近道です。
flowchart LR
R["リポジトリ<br>保管する場所"] --> G["Git<br>ファイルと履歴・.git"]
R --> P["パッケージ<br>apt・npm・Maven"]
R --> C["コンテナ<br>イメージとタグ"]
R --> D["設計パターン<br>データの出し入れ係"]
よく調べられることの答えを先にまとめます。
| 知りたいこと | 答え | 詳しい節 |
|---|---|---|
| リポジトリとは | ファイルや部品を履歴・版つきでまとめて保管する場所 | リポジトリとは(意味と語源) |
| リポジトリ 意味(文脈別) | Git・パッケージ・コンテナ・設計パターンの4つが主 | 文脈で変わるリポジトリの意味 |
| git リポジトリとは | 作業フォルダの中の .git。中身と履歴をすべて持つ | Gitのリポジトリとは(.gitの中身) |
| ローカルとリモートの違い | 自分の PC にあるか、共有の場所にあるか。中身の仕組みは同じ | ローカルリポジトリとリモートリポジトリの違い |
| リポジトリと GitHub の違い | GitHub はリポジトリを預かって共有するサービス | フォルダ・データベース・GitHubとの違い |
| clone と fork の違い | clone は手元への複製、fork は GitHub 上に自分のリポジトリとして複製 | clone・fork・branchの違い |
| apt や npm のリポジトリとは | パッケージの配布元。npm は「レジストリ」と呼ぶ | パッケージのリポジトリ |
| Docker のリポジトリとは | レジストリの中の、同じイメージの版(タグ)の集まり | Dockerのリポジトリとレジストリ・タグ |
| Repository パターンとは | データの保存・取得をまとめて受け持つクラス | 設計パターンのRepository |
確認環境:Ubuntu 24.04.5 LTS の上で、Git 2.43.0 を使い、作業用ディレクトリ(共有の設定に触れないよう GIT_CONFIG_GLOBAL を作業用のファイルに向けた状態)で git init・commit・cat-file・init --bare・clone・push・fetch・gc を実行し、エラーの原文を集めました。GitHub への push やリポジトリ作成は行っていません(GitHub の画面・fork・可視性は GitHub Docs で確かめた範囲です)。apt は apt 2.8.3 で apt-cache policy を、npm は npm 10.9.9(Node.js 22.23.4)で npm view を、pip は pip 26.2.1 で pip index versions を読み取りだけ実行しました。Maven 3.9.11 はこの環境から Maven Central に届かなかったため、その失敗の出力をそのまま載せています。Docker Hub にも届かなかったため、コンテナのリポジトリの API は OCI Distribution 仕様の読み取り部分を真似た自作のモック(127.0.0.1)で形を確かめ、名前の読み方は Docker の公式ドキュメントで確かめました。Repository パターンは Python 3.13.18 と OpenJDK 21.0.12 で実行しました。図は mermaid で描画を確かめています(確認日 2026年10月29日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「リポジトリとは?Gitの.gitの中身を実物で|apt・npm・Dockerとの違い」
リポジトリとは(意味と語源)
この節では、リポジトリという言葉のもとの意味と、IT で共通している考え方が分かります。
repository は「物をしまっておく場所・貯蔵庫」を表す英語です。IT では、プログラムのソースコード、設計書、ライブラリ、コンテナイメージなどを「あとで同じものを取り出せるように」保管する場所を指します。単なる置き場と違うのは、多くの場合「いつの・どの版か」を区別して取り出せる点です。
身近なものにたとえると、図書館の書庫に近い存在です。本(ファイル)がただ積んであるのではなく、版ごとに番号が振られ、貸出の記録(履歴)が残り、目録(索引)から目的の1冊を探せます。
1まとめて保管する
ばらばらのファイルや部品を、1つの単位として置いておく。Git なら1つのプロジェクト、apt なら配布元1か所。
2版や履歴を区別する
Git はコミット、パッケージは版番号、Docker はタグとダイジェストで「どの時点のものか」を区別する。
3共有して取り出せる
チームや利用者が、同じ場所から同じものを取り出せる。取り出す操作が clone・install・pull と呼ばれる。
「リポジトリ」と「レポジトリ」はどちらが正しいか
どちらも同じ repository のカタカナ表記で、意味は変わりません。英語の発音は「リ」に近く、GitHub Docs の日本語版や多くの技術文書は「リポジトリ」と書いています。検索するときは両方の表記で探すと、取りこぼしが減ります。
IT 以外・開発以外での「リポジトリ」
大学や研究機関の「機関リポジトリ」は、論文や研究データを保存して公開する電子の書庫を指します。また、システム開発の文脈で「設計情報のリポジトリ」と言うときは、要件・設計書・データ定義などを一元管理する置き場を指すことがあります。どちらも「まとめて保管して取り出せる場所」という考え方は同じです。この記事では、開発者がよく出会う4つの意味を中心に扱います。
文脈で変わるリポジトリの意味(Git・パッケージ・コンテナ・設計パターン)
この節では、同じ「リポジトリ」という言葉が、使われる場面によって何を指すのかが分かります。
「リポジトリ」と聞いたら、まず「何を保管している場所か」を確かめます。この環境で実際に触れたものを、保管している中身・取り出す操作・置き場所で並べました。
| 文脈 | 保管している中身 | 取り出す操作 | 手元で見た置き場所 |
|---|---|---|---|
| Git | ファイルの中身と変更履歴(コミット) | git clone・git pull |
作業フォルダの .git |
| apt(Ubuntu) | .deb パッケージと一覧 | apt install |
/etc/apt/sources.list.d/ に配布元を登録 |
| npm | JavaScript のパッケージ | npm install |
npm config get registry の URL |
| pip | Python のパッケージ | pip install |
PyPI(設定で変更可) |
| Maven | Java のライブラリ(jar・pom) | ビルド時に自動で取得 | ローカルリポジトリと Maven Central |
| Docker | 同じ名前のイメージの版(タグ) | docker pull |
レジストリ(Docker Hub・ECR 等)の中 |
| 設計パターン | データの保存・取得の処理 | find_by_id などのメソッド |
ソースコードのクラス |
Git・パッケージ・コンテナの3つは「ファイルの置き場」ですが、設計パターンの Repository だけはプログラムの部品の名前です。「リポジトリを作る」と言われたとき、Git なら git init、Spring などのアプリなら Repository クラスを書くことを意味するので、会話の相手と前提をそろえます。
Gitのリポジトリとは(.gitフォルダの中身)
この節では、Git のリポジトリが実際にはどんなファイルでできているのかが、実行結果で分かります。
Git のリポジトリの正体は、作業フォルダの中にできる .git という隠しフォルダです。Git の用語集(gitglossary)は、リポジトリを「refs(ブランチなどの名札)と、そこからたどれるすべてのオブジェクトを持つオブジェクトデータベースの集まり」と定義しています。まず、空のフォルダで git init を実行しました。
$ mkdir demo && cd demo
$ git status
fatal: not a git repository (or any parent up to mount point /dev)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
$ git init
Initialized empty Git repository in /dev/shm/t122/demo/.git/
$ ls -A
.git
$ find .git -maxdepth 1 | sort
.git
.git/HEAD
.git/branches
.git/config
.git/description
.git/hooks
.git/info
.git/objects
.git/refs
$ cat .git/HEAD
ref: refs/heads/main
git init の前は「リポジトリではない」と言われ、後は .git ができました。フォルダの中身(作業ツリー)はそのままで、.git を足した瞬間にそのフォルダが Git のリポジトリになります。
| .git の中 | 役割 | 手元で見た中身 |
|---|---|---|
| HEAD | 今いるブランチを指す | ref: refs/heads/main |
| refs/heads/ | ブランチごとの最新コミットの番号 | main に 40 桁のハッシュが1行 |
| objects/ | ファイルの中身・フォルダ構成・コミットの本体 | 最初のコミットで4ファイル |
| config | このリポジトリだけの設定(リモートの URL 等) | [remote "origin"] の url |
| hooks/ | コミット前などに動かすスクリプトの置き場 | サンプルのみ |
リモートを登録したあとの .git/config は、次のような普通のテキストでした。
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = /dev/shm/t122/server.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
remote = origin
merge = refs/heads/main
リポジトリを最初に作る手順(既存フォルダでの git init から最初の push まで)は、関連記事「git initの使い方|既存フォルダを最初のpushまで進める手順」で扱っています。
コミットで何が保存されるか(git cat-fileで中身を見る)
この節では、コミットしたときに .git の objects に何が増えるのかと、Git が履歴を持てる仕組みが分かります。
コミットすると、ファイルの中身(blob)、フォルダの構成(tree)、コミットの情報(commit)の3種類のオブジェクトが objects に保存されます。README.md と app.py の2ファイルを最初にコミットしました。
$ git add README.md app.py
$ git commit -m "最初のコミット"
[main (root-commit) 9b80671] 最初のコミット
2 files changed, 3 insertions(+)
create mode 100644 README.md
create mode 100644 app.py
$ find .git/objects -type f | sort
.git/objects/96/8c43a3f352e3c4b57df86ca8143f425c847950
.git/objects/9b/806711460bfb9d2df612297dfe3c29b842d958
.git/objects/e2/376e8938d549f346fcc60ef7b9181c96b21edd
.git/objects/f2/877257ff70c74139ae317498280eb7e5dc829a
4つのファイルが増えました。それぞれを git cat-file で開くと、コミット→ツリー→ファイルの順につながっているのが見えます。
$ git cat-file -t HEAD
commit
$ git cat-file -p HEAD
tree e2376e8938d549f346fcc60ef7b9181c96b21edd
author Taro Yamada <taro@example.com> 1793235600 +0900
committer Taro Yamada <taro@example.com> 1793235600 +0900
最初のコミット
$ git cat-file -p e2376e8938d549f346fcc60ef7b9181c96b21edd
100644 blob f2877257ff70c74139ae317498280eb7e5dc829a README.md
100644 blob 968c43a3f352e3c4b57df86ca8143f425c847950 app.py
$ git cat-file -p 968c43a3f352e3c4b57df86ca8143f425c847950
def discount(price):
return int(price * 0.9)
$ cat .git/refs/heads/main
9b806711460bfb9d2df612297dfe3c29b842d958
名前が中身から決まることを確かめる
オブジェクトの名前は、中身から計算したハッシュ値です。git hash-object と、「blob 長さ\0」の後ろに中身をつないで sha1sum にかけた値が一致しました。
$ git hash-object app.py
968c43a3f352e3c4b57df86ca8143f425c847950
$ printf 'blob %d\0' $(wc -c <app.py) | cat - app.py | sha1sum
968c43a3f352e3c4b57df86ca8143f425c847950 -
中身が1文字でも変われば名前も変わるので、同じ名前のオブジェクトは必ず同じ中身です。Git の用語集も、オブジェクトは中身のハッシュで識別され、そのため変更できないと説明しています。過去のコミットが書き換わらずに残るのは、この仕組みのおかげです。
消したファイルを戻せる理由
作業フォルダで app.py を消しても、中身は .git の objects に残っています。git restore で戻せました。
$ rm app.py
$ git status -s
D app.py
$ git restore app.py
$ ls
README.md app.py
逆に、.git フォルダを消すと履歴はすべて失われます。コピーしたフォルダで .git だけを消すと、ファイルは残ったまま、Git からは「リポジトリではない」と扱われました。
$ rm -rf .git
$ git log
fatal: not a git repository (or any parent up to mount point /dev)
$ ls -A
README.md app.py src
オブジェクトが増えると、git gc が pack ファイルにまとめます。実行すると、個別のファイルが消えて objects/pack/pack-…pack と索引(.idx)に置き換わりました。中身は同じで、置き方だけが変わります。
ローカルリポジトリとリモートリポジトリの違い
この節では、ローカルとリモートの違いと、両者の間でやり取りする push・fetch・pull の関係が分かります。
ローカルリポジトリは自分の PC にあるリポジトリ、リモートリポジトリは GitHub や社内サーバーなど共有の場所にあるリポジトリです。中身の仕組み(objects と refs)は同じで、違うのは置き場所と使い方です。
ローカルリポジトリ
自分の PC の作業フォルダの .git
コミット・ブランチ作成・履歴の確認はネットなしでできる
自分だけが見られる。消せば履歴も消える
リモートリポジトリ
GitHub・GitLab・社内サーバー上
push で送り、fetch・pull で受け取る
チームの共有場所。権限で見られる人を決める
手元にベアリポジトリ(次の節)を作ってリモートの代わりにし、2つのローカルリポジトリから push と fetch をしました。
$ git remote add origin /dev/shm/t122/server.git
$ git push -u origin main
To /dev/shm/t122/server.git
* [new branch] main -> main
branch 'main' set up to track 'origin/main'.
# 別の場所に clone して、そちらで変更を push
$ git clone server.git work2
Cloning into 'work2'...
done.
$ cd work2 && git commit -qam "割引率を引数に" && git push
To /dev/shm/t122/server.git
9b80671..7eb32a5 main -> main
# 元のリポジトリでは、fetch するまで変更を知らない
$ cd ../demo && git status -sb
## main...origin/main
$ git fetch
From /dev/shm/t122/server
9b80671..7eb32a5 main -> origin/main
$ git status -sb
## main...origin/main [behind 1]
fetch する前の demo は「origin と同じ」と表示していました。ローカルリポジトリはリモートの最新を自動では知らず、fetch した時点の情報で比べています。fetch は受け取るだけ、pull は受け取って自分のブランチに取り込むまで行います。
集中型と分散型
Subversion(SVN)のような集中型のバージョン管理では、履歴を持つリポジトリはサーバーに1つだけで、手元には作業用のファイルだけがあります。Git は分散型で、clone した全員のローカルリポジトリが履歴をまるごと持ちます。そのため、手元でコミットや履歴の確認ができ、サーバーが止まっても履歴が失われにくい作りです。
リモートの登録・変更・削除の操作と push を断られたときの直し方は、関連記事「git remoteの変更・追加・削除とpush rejectedの対処法」で扱っています。
ベアリポジトリとは(サーバー側のリポジトリ)
この節では、作業フォルダを持たない「ベアリポジトリ」が何のためにあり、普通のリポジトリと何が違うのかが分かります。
ベアリポジトリは、作業ファイルを持たず .git の中身だけでできたリポジトリです。GitHub などのサーバー側が持っているのはこの形で、push を受け取る専用の置き場として使います。git init --bare で作ると、.git の中にあったものがフォルダの直下に並びました。
$ git init --bare server.git
Initialized empty Git repository in /dev/shm/t122/server.git/
$ find server.git -maxdepth 1 | sort
server.git
server.git/HEAD
server.git/branches
server.git/config
server.git/description
server.git/hooks
server.git/info
server.git/objects
server.git/refs
$ git -C server.git rev-parse --is-bare-repository
true
普通のリポジトリ(作業フォルダあり)に push すると、どうなるかも試しました。チェックアウト中のブランチへの push は、既定で断られます。
remote: error: refusing to update checked out branch: refs/heads/main
remote: error: By default, updating the current branch in a non-bare repository
remote: is denied, because it will make the index and work tree inconsistent
remote: with what you pushed, and will require 'git reset --hard' to match
remote: the work tree to HEAD.
...
To /dev/shm/t122/demo
! [remote rejected] main -> main (branch is currently checked out)
error: failed to push some refs to '/dev/shm/t122/demo'
作業中のファイルと、送られてきた履歴が食い違うのを防ぐための決まりです。共有用のリポジトリはベアで作るのが基本で、名前の末尾を .git にするのが慣習です(Git の用語集にも、ベアリポジトリは通常 .git で終わる名前のディレクトリだと書かれています)。
| 比べる点 | 普通のリポジトリ | ベアリポジトリ |
|---|---|---|
| 作り方 | git init・git clone |
git init --bare・git clone --bare |
| 作業ファイル | ある(編集できる) | ない |
| Git の管理情報 | .git フォルダの中 | フォルダの直下 |
| 用途 | 開発者が手元で編集・コミット | サーバーで push を受ける・バックアップ |
| 大きさ(手元の例) | .git が 152KB | 112KB |
リポジトリとフォルダ・データベース・GitHubの違い(clone・fork・branchも)
この節では、リポジトリと混同しやすい言葉との違いと、clone・fork・branch の使い分けが分かります。
リポジトリとフォルダの違い
見分ける問い:「3日前の状態に戻せるか」
| 比べる相手 | リポジトリとの違い |
|---|---|
| フォルダ | フォルダに .git を足すとリポジトリになる。履歴を持つかどうかが違い |
| データベース | データベースは表の行を検索・更新する仕組み。Git のリポジトリはファイルの版を残す仕組みで、得意なことが違う |
| Git | Git はリポジトリを作って操作する道具(ソフトウェア) |
| GitHub | リポジトリを預かり、共有・レビュー(プルリクエスト)・Issue などの機能を足したサービス |
| プロジェクト | 1プロジェクト=1リポジトリが多いが、複数に分けることも、1つにまとめる(モノレポ)こともある |
GitHub Docs は、リポジトリには「すべてのコード、ファイル、および各ファイルのリビジョン履歴」が含まれると説明しています。また、公開範囲はパブリック(誰でも見られる)とプライベート(自分と共有した相手、組織の特定メンバーだけ)があり、GitHub Enterprise Cloud の組織では内部(internal)も選べます。GitHub Free でもプライベートリポジトリは数の制限なく作れますが、一部の機能はプライベートでは有料プランが必要です(2026年10月29日時点の GitHub Docs の記載)。
clone・fork・branch の違い
clone(クローン)
リモートのリポジトリを、履歴ごと自分の PC に複製する。git clone URL。
Git の操作・手元にできる
fork(フォーク)
他人のリポジトリを、GitHub 上に自分のリポジトリとして複製する。元とのつながりは残る。
GitHub の機能・サーバー上にできる
branch(ブランチ)
1つのリポジトリの中で、作業の流れを分ける。リポジトリは増えない。
Git の操作・同じリポジトリの中
mirror(ミラー)
git clone --bare や --mirror で、作業ファイルなしの写しを作る。バックアップや移行に使う。
ベアリポジトリができる
GitHub Docs は、フォークを「アップストリーム リポジトリと呼ばれる別のリポジトリのコピーとして開始されるリポジトリ」、ブランチを「1 つのリポジトリの一部」と説明しています。書き込み権限が無いリポジトリに変更を提案するときは fork、権限があるチームの中では branchを使うのが一般的です。clone のブランチ指定や、履歴を浅く取る shallow clone は、関連記事「git cloneの使い方|ブランチ指定とshallow clone」で扱っています。
リポジトリの作り方と基本の流れ(init・clone・add・commit・push・pull)
この節では、リポジトリを用意してから、変更を記録して共有するまでの基本の流れが分かります。
リポジトリを手に入れる方法は2つです。新しく作るなら git init、すでにあるものを使うなら git clone です。その後は「変更する→add で記録する候補に入れる→commit で記録する→push で共有する」をくり返します。
リポジトリを用意する
新規なら作業フォルダで git init。既存なら git clone URL。どちらも .git ができる。
変更を記録の候補に入れる
git add ファイル名。記録したい変更だけを選んで「ステージ」に載せる。
コミットで記録する
git commit -m "説明"。この時点で objects に commit・tree・blob が増える。
リモートに送る
git push。初回は git push -u origin main で追跡先を設定する。
他の人の変更を取り込む
git pull(fetch+取り込み)。まず git fetch で差を見てから取り込むと安全。
| 用語 | 意味 | リポジトリで起きること |
|---|---|---|
| commit | 変更をひとまとまりで記録する | ローカルの objects と refs が更新される |
| clone | リモートを手元に複製する | ローカルリポジトリが1つできる |
| push | 手元のコミットをリモートへ送る | リモートの objects と refs が更新される |
| fetch | リモートの更新を受け取るだけ | origin/main などの参照だけが進む |
| pull | 受け取って自分のブランチに取り込む | 作業ファイルも新しくなる |
| branch | 作業の流れを分ける | refs/heads/ に名札が1つ増える |
どのフォルダがリポジトリの一番上かは、git rev-parse で確かめられます。サブフォルダの中で実行しても、リポジトリの位置が分かりました。
$ cd src/sub
$ git rev-parse --show-toplevel --git-dir
/dev/shm/t122/demo
/dev/shm/t122/demo/.git
パッケージのリポジトリ(apt・npm・pip・Maven)
この節では、Linux やプログラミング言語の「パッケージのリポジトリ」が何を指し、手元でどう確かめられるかが分かります。
パッケージのリポジトリは、ソフトやライブラリを版ごとに配布している配布元のサーバーです。Git のリポジトリと違い、利用者は履歴を持たず、必要な版を取ってくるだけです。npm や Docker では、同じ役割の場所を「レジストリ」と呼びます。
apt(Ubuntu)のリポジトリ
Ubuntu 24.04 では、配布元の設定は /etc/apt/sources.list.d/ の中にあります。この環境の設定は次のとおりでした。
$ cat /etc/apt/sources.list.d/ubuntu.sources
Types: deb
URIs: http://archive.ubuntu.com/ubuntu/
Suites: noble noble-updates noble-backports
Components: main universe restricted multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
...
$ cat /etc/apt/sources.list.d/docker.list
deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu noble stable
あるパッケージを、どのリポジトリのどの版から入れるのかは apt-cache policy で見られます。
$ apt-cache policy git
git:
Installed: 1:2.43.0-1ubuntu7.4
Candidate: 1:2.43.0-1ubuntu7.4
Version table:
*** 1:2.43.0-1ubuntu7.4 500
500 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 Packages
500 http://security.ubuntu.com/ubuntu noble-security/main amd64 Packages
100 /var/lib/dpkg/status
1:2.43.0-1ubuntu7 500
500 http://archive.ubuntu.com/ubuntu noble/main amd64 Packages
同じ git でも、最初の版(noble)と更新版(noble-updates・noble-security)が別のリポジトリに置かれ、数字(優先度 500)が同じなら新しい版が選ばれています。Docker の公式リポジトリのように、Ubuntu 以外の配布元を足すこともできます。この環境では、登録されている配布元の区画が 15 個ありました。update と upgrade の違いなど apt の操作は、関連記事「aptコマンド一覧|updateとupgradeの違い・apt-getとの違い」で扱っています。
npm・pip のレジストリ
$ npm config get registry
https://registry.npmjs.org/
$ npm view yup version dist.tarball repository.url
version = '1.7.1'
dist.tarball = 'https://registry.npmjs.org/yup/-/yup-1.7.1.tgz'
repository.url = 'git+https://github.com/jquense/yup.git'
$ pip index versions requests
requests (2.34.2)
Available versions: 2.34.2, 2.34.1, 2.34.0, 2.33.1, ...
npm の出力には、2種類のリポジトリが同時に出ています。dist.tarball はパッケージを配るレジストリ(npm のリポジトリ)、repository.url はそのパッケージのソースコードがある Git のリポジトリです。「ライブラリのリポジトリを見て」と言われたら、多くの場合は後者(GitHub のソース)を指します。
Maven のリポジトリ
Maven の公式ドキュメントは、リポジトリを「さまざまな種類のビルド成果物を保持するもの」とし、種類はローカルとリモートの2つだけだと説明しています。ローカルは Maven を動かす PC のフォルダ(通常は ~/.m2/repository)で、リモートから取ったものをためておきます。この環境は Maven Central に届かないため、取得に失敗したときの出力がそのまま「どこから取ろうとしたか」を示していました。
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-clean-plugin/3.2.0/maven-clean-plugin-3.2.0.pom
[WARNING] Failed to retrieve plugin descriptor for org.apache.maven.plugins:maven-clean-plugin:3.2.0: ...
The following artifacts could not be resolved: org.apache.maven.plugins:maven-clean-plugin:pom:3.2.0 (absent): Could not transfer artifact org.apache.maven.plugins:maven-clean-plugin:pom:3.2.0 from/to central (https://repo.maven.apache.org/maven2): repo.maven.apache.org: Name or service not known
「central」というリモートリポジトリから取ろうとし、名前が引けずに失敗しています。社内のリポジトリ(Nexus・Artifactory など)を使う会社では、settings.xml でこの取得先を社内に向けます。
| 道具 | 呼び名 | 既定の取得先 | 手元の確かめ方 |
|---|---|---|---|
| apt | リポジトリ | archive.ubuntu.com など | apt-cache policy |
| npm | レジストリ | registry.npmjs.org | npm config get registry |
| pip | インデックス | PyPI | pip config list |
| Maven | リポジトリ | Maven Central(central) | ビルドの Downloading 行 |
Dockerのリポジトリとレジストリ・タグ
この節では、コンテナイメージの世界での「レジストリ」「リポジトリ」「タグ」の関係と、イメージ名の読み方が分かります。
Docker では、レジストリ(置き場のサービス)の中にリポジトリ(同じイメージの集まり)があり、その中にタグ(版の名前)が並びます。Docker の公式ドキュメントは、レジストリを「コンテナイメージを保存・共有する中央の場所」、リポジトリを「レジストリ内の関連するコンテナイメージの集まり」と説明しています。
flowchart TD
A["レジストリ<br>Docker Hub・ECR・ghcr.io"] --> B["リポジトリ<br>team/my-api"]
B --> C["タグ 1.0.0"]
B --> D["タグ 1.1.0"]
B --> E["タグ latest"]
イメージ名を「レジストリ/リポジトリ/タグ」に分けて読む練習として、Docker の省略の規則(レジストリを省くと docker.io、公式イメージは library/、タグを省くと latest)を短い Python で再現しました。
nginx -> docker.io | library/nginx | latest | -
nginx:1.27 -> docker.io | library/nginx | 1.27 | -
bitnami/redis:7.4 -> docker.io | bitnami/redis | 7.4 | -
ghcr.io/octo-org/app:v1.2.0 -> ghcr.io | octo-org/app | v1.2.0 | -
123456789012.dkr.ecr.ap-nort -> 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com | my-api | 2026-10-29 | -
localhost:5000/demo -> localhost:5000 | demo | latest | -
alpine@sha256:beefdbd8a1da6d -> docker.io | library/alpine | - | sha256:beefdbd8a1da
nginx とだけ書いても、実際には「docker.io の library/nginx リポジトリの latest タグ」を指しています。latest は「最新」の保証ではなく、ただのタグの名前です。本番では版のタグか、中身で決まるダイジェスト(sha256:…)で指定すると、取り出すものが変わりません。
レジストリの API で見るリポジトリ
この環境から Docker Hub には届かなかったため、OCI Distribution 仕様の読み取り API(タグ一覧・マニフェスト取得)だけを真似た学習用のモックを 127.0.0.1 に立て、リポジトリとタグの関係を API の形で確かめました。応答の形とエラーコード(NAME_UNKNOWN・MANIFEST_UNKNOWN)は仕様に合わせています。
$ curl -sS --noproxy '*' http://127.0.0.1:50122/v2/team/my-api/tags/list
{"name": "team/my-api", "tags": ["1.0.0", "1.1.0", "latest"]}
$ curl -sS --noproxy '*' http://127.0.0.1:50122/v2/team/my-api/manifests/9.9.9
{"errors": [{"code": "MANIFEST_UNKNOWN", "message": "manifest unknown"}]}
$ curl -sS --noproxy '*' http://127.0.0.1:50122/v2/team/no-such-api/tags/list
{"errors": [{"code": "NAME_UNKNOWN", "message": "repository name not known to registry"}]}
「リポジトリが無い(NAME_UNKNOWN)」と「リポジトリはあるがタグが無い(MANIFEST_UNKNOWN)」は別のエラーです。pull に失敗したときは、どちらなのかで直す場所が変わります。AWS のレジストリ(ECR)でリポジトリを作る手順と、不要になったイメージを自動で消す設定は、関連記事「Amazon ECR の使い方 リポジトリ作成とライフサイクルポリシー」で扱っています。
設計パターンのRepository(Python・Javaの最小例)
この節では、プログラムの設計で使う Repository パターンの意味と、最小のコードで何がうれしいのかが分かります。
Repository パターンは、データの保存・取得をまとめて受け持つ部品を作り、業務の処理からデータベースの細かい書き方を切り離す設計です。Martin Fowler の『Patterns of Enterprise Application Architecture』では、「コレクションのようなインターフェースでドメインオブジェクトにアクセスし、ドメインとデータマッピング層の間を取り持つ」ものとされています。Git のリポジトリとは関係なく、「データの倉庫係」という意味で同じ言葉が使われています。
Python で、同じ「会員の名前を変える」処理を、SQLite に保存する Repository とメモリに置く Repository の2つで動かしました。
import sqlite3
from dataclasses import dataclass
from typing import Protocol
@dataclass
class Member:
id: int
name: str
class MemberRepository(Protocol):
def find_by_id(self, id: int) -> Member | None: ...
def save(self, m: Member) -> None: ...
class SqliteMemberRepository:
def __init__(self, path: str):
self.db = sqlite3.connect(path)
self.db.execute("CREATE TABLE IF NOT EXISTS member(id INTEGER PRIMARY KEY, name TEXT)")
def find_by_id(self, id):
row = self.db.execute("SELECT id, name FROM member WHERE id = ?", (id,)).fetchone()
return Member(*row) if row else None
def save(self, m):
self.db.execute("INSERT OR REPLACE INTO member VALUES (?, ?)", (m.id, m.name))
self.db.commit()
class InMemoryMemberRepository:
def __init__(self):
self.rows = {}
def find_by_id(self, id):
return self.rows.get(id)
def save(self, m):
self.rows[m.id] = m
def rename(repo: MemberRepository, id: int, new_name: str) -> str:
m = repo.find_by_id(id)
if m is None:
return f"id={id} は見つかりません"
repo.save(Member(id, new_name))
return f"id={id}: {m.name} -> {new_name}"
for repo in (SqliteMemberRepository(":memory:"), InMemoryMemberRepository()):
repo.save(Member(1, "山田"))
print(type(repo).__name__, "|", rename(repo, 1, "山田太郎"), "|", rename(repo, 2, "佐藤"))
$ python3 repo_pattern.py
SqliteMemberRepository | id=1: 山田 -> 山田太郎 | id=2 は見つかりません
InMemoryMemberRepository | id=1: 山田 -> 山田太郎 | id=2 は見つかりません
rename は SQL を1行も知らないまま、どちらの保存先でも同じ結果を返しました。テストではメモリ版、本番では DB 版というように差し替えられるのが、このパターンの主な利点です。Java ではインターフェースで同じ形を書きます。
import java.util.*;
public class RepoDemo {
record Member(int id, String name) {}
interface MemberRepository {
Optional<Member> findById(int id);
void save(Member m);
}
static class InMemoryMemberRepository implements MemberRepository {
private final Map<Integer, Member> rows = new HashMap<>();
public Optional<Member> findById(int id) { return Optional.ofNullable(rows.get(id)); }
public void save(Member m) { rows.put(m.id(), m); }
}
static String rename(MemberRepository repo, int id, String newName) {
return repo.findById(id).map(m -> {
repo.save(new Member(id, newName));
return "id=" + id + ": " + m.name() + " -> " + newName;
}).orElse("id=" + id + " は見つかりません");
}
public static void main(String[] args) {
MemberRepository repo = new InMemoryMemberRepository();
repo.save(new Member(1, "山田"));
System.out.println(rename(repo, 1, "山田太郎"));
System.out.println(rename(repo, 2, "佐藤"));
}
}
$ java -Dstdout.encoding=UTF-8 RepoDemo.java
id=1: 山田 -> 山田太郎
id=2 は見つかりません
Java 21 で -Dstdout.encoding=UTF-8 を付けずに実行したこの環境では、日本語が ?? と表示されました。端末の文字コードが UTF-8 でない環境で起きるので、出力が化けたら指定を足します。Spring Boot では、インターフェースを書くだけで実装を自動で作る Spring Data JPA の Repository がよく使われ、関連記事「Spring Data JPA使い方|クエリメソッド命名一覧と@Query実例」で扱っています。
リポジトリでよくあるエラーと直し方(not a git repository・repository not found)
この節では、リポジトリまわりで出るエラーの原文と、原因・直し方の対応が分かります。
エラーの多くは「今いる場所がリポジトリではない」「指定したリポジトリが見つからない・権限が無い」のどちらかです。この環境で実際に出した原文を並べます。
| エラー原文(先頭) | 起きた状況 | 直し方 |
|---|---|---|
fatal: not a git repository (or any of the parent directories): .git |
.git の無いフォルダで git status | cd でリポジトリの中へ移る。新規なら git init |
fatal: repository '…/nothing.git' does not exist |
存在しないパスを clone | URL・パスの綴りを見直す |
fatal: 'upstream' does not appear to be a git repository |
登録していないリモート名へ push | git remote -v で名前を確かめる |
fatal: could not read Username for 'https://github.com' |
見られないか存在しない GitHub の URL を、入力を禁止して clone | URL と権限を確かめ、トークンか SSH で認証 |
remote: Repository not found. |
認証したうえで、見る権限の無い・存在しないリポジトリ(GitHub Docs) | 綴り・権限・どのアカウントで認証したかを確かめる |
fatal: detected dubious ownership in repository |
別のユーザーが持ち主のフォルダで git を実行 | 持ち主をそろえる。信頼できる場所だけ safe.directory に足す |
! [remote rejected] main -> main (branch is currently checked out) |
作業フォルダのあるリポジトリへ push | 共有用はベアリポジトリで作る |
error: 'inner/' does not have a commit checked out |
リポジトリの中に別のリポジトリを作って add | 内側の .git を消すか、サブモジュールにする |
not a git repository は、置き場所によって2行目が変わります。マウントの境目(この環境の /dev/shm)では次のように出ました。
fatal: not a git repository (or any parent up to mount point /dev)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
持ち主の違うフォルダでは、Git が自分で直し方を示しました。中身を確かめていないフォルダを safe.directory に足すと、そのフォルダの設定が実行されうるので、まず持ち主をそろえる方を選びます。
fatal: detected dubious ownership in repository at '/srv/s4/r17/t122/own'
To add an exception for this directory, call:
git config --global --add safe.directory /srv/s4/r17/t122/own
GitHub の「リポジトリが見つかりません」について、GitHub Docs は綴りの確認(ページから URL をコピーする)、アクセス権の確認、SSH なら ssh -T git@github.com での認証の確認、最後にリポジトリが実在するかの確認を挙げています。プライベートリポジトリは、権限が無い人には「無い」と同じ応答になるため、存在するはずなのに見つからないときは権限を疑います。apt で配布元にないパッケージを指定したときは E: Unable to locate package、npm では npm error 404 'パッケージ名@*' is not in this registry. と出ました。
- 1今いる場所を確かめる
git rev-parse --show-toplevelでリポジトリの一番上が出るか - 2リモートの名前と URL を確かめる
git remote -vで origin の URL を見る - 3どのアカウントで認証しているか個人と会社のアカウントを使い分けていると、権限の無い側で接続していることがある
- 4どの種類のリポジトリのエラーかgit・apt・npm・docker のどれのエラーかで、見る設定ファイルが変わる
判断表:どの「リポジトリ」の話か・どこに置くか
この節では、会話や文書に出てきた「リポジトリ」がどれを指すかの見分け方と、Git のリポジトリをどう分けて置くかの判断が分かります。
周りに出てくる言葉で、どのリポジトリかはほぼ決まります。
| 一緒に出てくる言葉 | 指しているもの | 最初に見る場所 |
|---|---|---|
| clone・push・ブランチ・GitHub | Git のリポジトリ | git remote -v |
| apt・PPA・sources.list・追加する | apt のリポジトリ(配布元) | /etc/apt/sources.list.d/ |
| npm・registry・.npmrc・スコープ | npm のレジストリ | npm config get registry |
| pom.xml・Nexus・Artifactory・.m2 | Maven のリポジトリ | settings.xml・pom.xml |
| イメージ・タグ・pull・ECR | コンテナのリポジトリ | イメージ名のスラッシュの前後 |
| クラス・DAO・Spring Data・テスト | Repository パターン | ソースコードのインターフェース |
| 論文・図書館・機関 | 機関リポジトリ | 大学・研究機関のサイト |
Git のリポジトリを分けるか、まとめるか
- 1一緒に版を出すもの → 1つのリポジトリ画面と API を同時に変えて同時に出すなら、まとめた方が変更を追いやすい
- 2見られる人を分けたいもの → 別のリポジトリ権限はリポジトリ単位で決まる。公開するものと社外秘を混ぜない
- 3別々の速さで版を出す部品 → 別のリポジトリ共通ライブラリはパッケージとして配布し、版で取り込む
- 4大きなファイル・生成物 → リポジトリに入れないビルド結果や依存ライブラリは .gitignore へ。中身は配布元のリポジトリから取る
- 5パスワード・API キー → 入れない一度コミットすると履歴に残る。消すには履歴の書き換えと鍵の交換が要る
履歴が中身のハッシュでつながっているため、一度コミットしたものは、後のコミットで消しても過去のコミットから取り出せます。機密情報は最初から入れないのが一番の対策です。
よくある質問
この節では、リポジトリについてよく聞かれる疑問への短い答えが分かります。
Q. リポジトリはどこにありますか。
Git のローカルリポジトリは、作業フォルダの中の隠しフォルダ .git です。リモートリポジトリは GitHub などのサーバー上にあり、git remote -v で URL が分かります。
Q. リポジトリとプロジェクトは同じものですか。
同じとは限りません。1つのプロジェクトを1つのリポジトリで管理することが多いですが、画面と API で分けたり、複数のプロジェクトを1つにまとめたりもします。
Q. Git を使わなくてもリポジトリと呼びますか。
呼びます。apt・npm・Maven の配布元、コンテナイメージの置き場、Subversion のリポジトリ、機関リポジトリなど、Git 以外でも「まとめて保管する場所」をリポジトリと呼びます。
Q. GitHub のリポジトリは何のために使いますか。
コードと履歴をチームで共有し、プルリクエストでレビューし、Issue で課題を管理するためです。Actions で自動テスト、Pages で Web ページの公開にも使えます。
Q. .git フォルダを消すとどうなりますか。
今のファイルは残りますが、履歴・ブランチ・リモートの設定がすべて消え、普通のフォルダに戻ります。リモートに push 済みなら、clone し直せば履歴を取り戻せます。
Q. リポジトリをコピーすると何が起きますか。
フォルダごとコピーすると .git も一緒に写り、履歴を持った別のリポジトリになります。共有するならコピーではなく clone を使うと、元とのつながり(origin)が設定されます。
Q. 空のリポジトリでも clone できますか。
できます。コミットがまだないと伝える警告が出て、空の作業フォルダと .git ができます。
Q. パブリックとプライベートはどちらにすべきですか。
社外に見せない前提のコードはプライベートにします。パブリックは誰でも見られるため、公開してよいものだけにし、鍵や個人情報が履歴に無いことを確かめてから切り替えます。
Q. npm の「レジストリ」と「リポジトリ」は違いますか。
npm では、パッケージの配布元をレジストリと呼び、package.json の repository 欄はソースコードの Git リポジトリを指します。手元の npm view でも別々の URL が表示されました。
Q. Repository パターンと DAO の違いは何ですか。
DAO は表ごとの読み書きを包む部品、Repository は業務で使うオブジェクトの集まりとしてふるまう部品、という違いで説明されることが多いです。小さなアプリでは中身がほぼ同じになり、名前だけの違いになることもあります。
まとめ
- リポジトリとは、ファイルや部品を履歴・版つきでまとめて保管する場所です。何を保管するかで、Git・パッケージ・コンテナ・設計パターンの意味に分かれます。
- Git のリポジトリの正体は .git フォルダです。コミットすると commit・tree・blob のオブジェクトが増え、名前は中身のハッシュで決まります。
- ローカルとリモートは仕組みが同じで、置き場所が違います。共有用はベアリポジトリで作り、fetch するまで手元はリモートの更新を知りません。
- apt・npm・pip・Maven は配布元、Docker はレジストリの中のタグの集まりをリポジトリと呼びます。npm view では配布元とソースの2つの URL が並びました。
- エラーは「場所がリポジトリでない」か「見つからない・権限が無い」がほとんどです。
git rev-parseとgit remote -vから確かめます。
参考・出典
確認日はいずれも 2026年10月29日です。
- Git「gitglossary(repository・bare repository・object)」:https://git-scm.com/docs/gitglossary
- Git「git-init Documentation」:https://git-scm.com/docs/git-init
- Git「git-cat-file Documentation」:https://git-scm.com/docs/git-cat-file
- GitHub Docs「リポジトリについて」:https://docs.github.com/ja/repositories/creating-and-managing-repositories/about-repositories
- GitHub Docs「フォークについて」:https://docs.github.com/ja/pull-requests/collaborating-with-pull-requests/working-with-forks/about-forks
- GitHub Docs「クローンエラーのトラブルシューティング」:https://docs.github.com/ja/repositories/creating-and-managing-repositories/troubleshooting-cloning-errors
- Ubuntu Manpage「sources.list」:https://manpages.ubuntu.com/manpages/noble/man5/sources.list.5.html
- npm Docs「registry」:https://docs.npmjs.com/cli/v10/using-npm/registry
- Apache Maven「Introduction to Repositories」:https://maven.apache.org/guides/introduction/introduction-to-repositories.html
- Docker Docs「What is a registry?」:https://docs.docker.com/get-started/docker-concepts/the-basics/what-is-a-registry/
- Open Container Initiative「Distribution Specification」:https://github.com/opencontainers/distribution-spec/blob/main/spec.md
- Martin Fowler「Repository(Catalog of Patterns of Enterprise Application Architecture)」:https://martinfowler.com/eaaCatalog/repository.html
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「リポジトリとは?Gitの.gitの中身を実物で|apt・npm・Dockerとの違い」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。