nano-git 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +407 -0
- package/dist/backend/file-backend.d.mts +26 -0
- package/dist/backend/file-backend.mjs +83 -0
- package/dist/backend/file.d.mts +2 -0
- package/dist/backend/file.mjs +2 -0
- package/dist/backend/index.d.mts +2 -0
- package/dist/backend/index.mjs +1 -0
- package/dist/backend/memory-backend.d.mts +25 -0
- package/dist/backend/memory-backend.mjs +33 -0
- package/dist/backend/memory.d.mts +2 -0
- package/dist/backend/memory.mjs +2 -0
- package/dist/backend/types.d.mts +90 -0
- package/dist/core/errors.d.mts +124 -0
- package/dist/core/errors.mjs +168 -0
- package/dist/core/hash-digest.d.mts +35 -0
- package/dist/core/hash-digest.mjs +50 -0
- package/dist/core/hash-file.d.mts +20 -0
- package/dist/core/hash-file.mjs +27 -0
- package/dist/core/hash-path.d.mts +17 -0
- package/dist/core/hash-path.mjs +35 -0
- package/dist/core/types/odb.d.mts +63 -0
- package/dist/core/types/refs.d.mts +140 -0
- package/dist/core/types/refs.mjs +19 -0
- package/dist/core/types/shallow.d.mts +52 -0
- package/dist/core/types.d.mts +154 -0
- package/dist/core/types.mjs +43 -0
- package/dist/errors.d.mts +2 -0
- package/dist/errors.mjs +2 -0
- package/dist/hash-file.d.mts +2 -0
- package/dist/hash-file.mjs +2 -0
- package/dist/index.d.mts +16 -0
- package/dist/index.mjs +14 -0
- package/dist/objects/author.d.mts +25 -0
- package/dist/objects/author.mjs +45 -0
- package/dist/objects/blob.d.mts +15 -0
- package/dist/objects/blob.mjs +20 -0
- package/dist/objects/codec.d.mts +46 -0
- package/dist/objects/codec.mjs +84 -0
- package/dist/objects/commit.d.mts +26 -0
- package/dist/objects/commit.mjs +160 -0
- package/dist/objects/index.d.mts +8 -0
- package/dist/objects/index.mjs +8 -0
- package/dist/objects/raw.d.mts +85 -0
- package/dist/objects/raw.mjs +111 -0
- package/dist/objects/tag.d.mts +26 -0
- package/dist/objects/tag.mjs +148 -0
- package/dist/objects/tree.d.mts +22 -0
- package/dist/objects/tree.mjs +66 -0
- package/dist/odb/file-utils.mjs +136 -0
- package/dist/odb/file.d.mts +22 -0
- package/dist/odb/file.mjs +66 -0
- package/dist/odb/memory.d.mts +22 -0
- package/dist/odb/memory.mjs +54 -0
- package/dist/pack/composite-store.d.mts +76 -0
- package/dist/pack/composite-store.mjs +133 -0
- package/dist/pack/constants.mjs +48 -0
- package/dist/pack/crc32.mjs +38 -0
- package/dist/pack/delta-apply.d.mts +21 -0
- package/dist/pack/delta-apply.mjs +71 -0
- package/dist/pack/delta-create.d.mts +28 -0
- package/dist/pack/delta-create.mjs +151 -0
- package/dist/pack/index.d.mts +16 -0
- package/dist/pack/index.mjs +13 -0
- package/dist/pack/object-header.d.mts +36 -0
- package/dist/pack/object-header.mjs +72 -0
- package/dist/pack/ofs-delta-offset.d.mts +35 -0
- package/dist/pack/ofs-delta-offset.mjs +59 -0
- package/dist/pack/pack-builder-types.d.mts +19 -0
- package/dist/pack/pack-builder.d.mts +52 -0
- package/dist/pack/pack-builder.mjs +80 -0
- package/dist/pack/pack-encoding.mjs +76 -0
- package/dist/pack/pack-index-reader.d.mts +57 -0
- package/dist/pack/pack-index-reader.mjs +90 -0
- package/dist/pack/pack-index-types.d.mts +16 -0
- package/dist/pack/pack-index-writer.d.mts +45 -0
- package/dist/pack/pack-index-writer.mjs +106 -0
- package/dist/pack/pack-reader-resolver.mjs +104 -0
- package/dist/pack/pack-reader-types.d.mts +31 -0
- package/dist/pack/pack-reader-types.mjs +22 -0
- package/dist/pack/pack-reader-utils.mjs +61 -0
- package/dist/pack/pack-reader.d.mts +81 -0
- package/dist/pack/pack-reader.mjs +171 -0
- package/dist/pack/pack-store-loader.mjs +79 -0
- package/dist/pack/pack-store-types.d.mts +16 -0
- package/dist/pack/pack-store.d.mts +55 -0
- package/dist/pack/pack-store.mjs +114 -0
- package/dist/pack/pack-writer.mjs +96 -0
- package/dist/pack/varint.d.mts +34 -0
- package/dist/pack/varint.mjs +57 -0
- package/dist/refs/file.d.mts +6 -0
- package/dist/refs/file.mjs +222 -0
- package/dist/refs/fs-utils.mjs +30 -0
- package/dist/refs/memory.d.mts +14 -0
- package/dist/refs/memory.mjs +104 -0
- package/dist/refs/names.d.mts +57 -0
- package/dist/refs/names.mjs +80 -0
- package/dist/refs/resolve.d.mts +33 -0
- package/dist/refs/resolve.mjs +55 -0
- package/dist/refs/shallow/file.d.mts +17 -0
- package/dist/refs/shallow/file.mjs +61 -0
- package/dist/refs/shallow/memory.d.mts +18 -0
- package/dist/refs/shallow/memory.mjs +33 -0
- package/dist/repository/core.d.mts +3 -0
- package/dist/repository/core.mjs +2 -0
- package/dist/repository/create.d.mts +22 -0
- package/dist/repository/create.mjs +43 -0
- package/dist/repository/file.d.mts +43 -0
- package/dist/repository/file.mjs +82 -0
- package/dist/repository/import/import-glob.mjs +44 -0
- package/dist/repository/import/import-plan-builder.mjs +625 -0
- package/dist/repository/import/import-session-types.d.mts +280 -0
- package/dist/repository/import/import-session.mjs +96 -0
- package/dist/repository/import/import-view.mjs +133 -0
- package/dist/repository/memory.d.mts +17 -0
- package/dist/repository/memory.mjs +33 -0
- package/dist/repository/ops/fetch-operations.mjs +20 -0
- package/dist/repository/ops/fetch-types.d.mts +82 -0
- package/dist/repository/ops/fetch-url.mjs +82 -0
- package/dist/repository/ops/fs-object-operations.mjs +31 -0
- package/dist/repository/ops/maintenance-operations.mjs +62 -0
- package/dist/repository/ops/maintenance-types.d.mts +42 -0
- package/dist/repository/ops/object-operations.mjs +65 -0
- package/dist/repository/ops/object-types.d.mts +109 -0
- package/dist/repository/ops/push-operations.mjs +16 -0
- package/dist/repository/ops/push-resolution.mjs +17 -0
- package/dist/repository/ops/push-types.d.mts +72 -0
- package/dist/repository/ops/push-url.mjs +45 -0
- package/dist/repository/ops/reachability.mjs +60 -0
- package/dist/repository/ops/ref-operations.mjs +86 -0
- package/dist/repository/ops/ref-types.d.mts +70 -0
- package/dist/repository/tree/tree-patch.d.mts +64 -0
- package/dist/repository/tree/tree-patch.mjs +268 -0
- package/dist/repository/tree/tree-walk.d.mts +46 -0
- package/dist/repository/tree/tree-walk.mjs +65 -0
- package/dist/repository/tree/tree-writer.mjs +68 -0
- package/dist/repository/types.d.mts +36 -0
- package/dist/sha1.d.mts +4 -0
- package/dist/sha1.mjs +4 -0
- package/dist/transport/client/receive-pack/http.d.mts +33 -0
- package/dist/transport/client/receive-pack/http.mjs +99 -0
- package/dist/transport/client/receive-pack/push-error.d.mts +23 -0
- package/dist/transport/client/receive-pack/push-error.mjs +32 -0
- package/dist/transport/client/receive-pack/push-pack-plan.d.mts +28 -0
- package/dist/transport/client/receive-pack/push-pack-plan.mjs +60 -0
- package/dist/transport/client/receive-pack/push-policy.d.mts +19 -0
- package/dist/transport/client/receive-pack/push-policy.mjs +64 -0
- package/dist/transport/client/receive-pack/push-ref-plan.d.mts +45 -0
- package/dist/transport/client/receive-pack/push-ref-plan.mjs +108 -0
- package/dist/transport/client/receive-pack/push-report.d.mts +28 -0
- package/dist/transport/client/receive-pack/push-report.mjs +84 -0
- package/dist/transport/client/receive-pack/push-request-plan.mjs +52 -0
- package/dist/transport/client/receive-pack/push.d.mts +32 -0
- package/dist/transport/client/receive-pack/push.mjs +97 -0
- package/dist/transport/client/receive-pack/request.d.mts +39 -0
- package/dist/transport/client/receive-pack/request.mjs +46 -0
- package/dist/transport/client/receive-pack/response.d.mts +26 -0
- package/dist/transport/client/receive-pack/response.mjs +52 -0
- package/dist/transport/client/receive-pack/result.d.mts +34 -0
- package/dist/transport/client/receive-pack/result.mjs +100 -0
- package/dist/transport/client/upload-pack/capability-advertisement.d.mts +56 -0
- package/dist/transport/client/upload-pack/capability-advertisement.mjs +130 -0
- package/dist/transport/client/upload-pack/fetch.d.mts +109 -0
- package/dist/transport/client/upload-pack/fetch.mjs +392 -0
- package/dist/transport/client/upload-pack/http.d.mts +29 -0
- package/dist/transport/client/upload-pack/http.mjs +79 -0
- package/dist/transport/client/upload-pack/ls-refs.d.mts +75 -0
- package/dist/transport/client/upload-pack/ls-refs.mjs +150 -0
- package/dist/transport/client/upload-pack/object-info.d.mts +65 -0
- package/dist/transport/client/upload-pack/object-info.mjs +111 -0
- package/dist/transport/client/upload-pack/types.d.mts +153 -0
- package/dist/transport/http/index.d.mts +3 -0
- package/dist/transport/http/index.mjs +2 -0
- package/dist/transport/http/smart-http.d.mts +46 -0
- package/dist/transport/http/smart-http.mjs +176 -0
- package/dist/transport/http/types.d.mts +27 -0
- package/dist/transport/index.d.mts +9 -0
- package/dist/transport/index.mjs +8 -0
- package/dist/transport/protocol/object-graph.d.mts +63 -0
- package/dist/transport/protocol/object-graph.mjs +149 -0
- package/dist/transport/protocol/pkt-line.d.mts +109 -0
- package/dist/transport/protocol/pkt-line.mjs +195 -0
- package/dist/transport/protocol/ref-advertisement.mjs +185 -0
- package/dist/transport/protocol/ref-collection.d.mts +38 -0
- package/dist/transport/protocol/ref-collection.mjs +63 -0
- package/dist/transport/protocol/ref-match.d.mts +39 -0
- package/dist/transport/protocol/ref-match.mjs +42 -0
- package/dist/transport/protocol/refspec.d.mts +44 -0
- package/dist/transport/protocol/refspec.mjs +79 -0
- package/dist/transport/protocol/side-band.d.mts +65 -0
- package/dist/transport/protocol/side-band.mjs +142 -0
- package/dist/transport/protocol/transport-capabilities.mjs +46 -0
- package/dist/transport/protocol/types.d.mts +148 -0
- package/dist/transport/protocol/update-refs.d.mts +68 -0
- package/dist/transport/protocol/update-refs.mjs +126 -0
- package/dist/transport/receive-pack.d.mts +11 -0
- package/dist/transport/receive-pack.mjs +11 -0
- package/dist/transport/server/receive-pack/advertise.d.mts +28 -0
- package/dist/transport/server/receive-pack/advertise.mjs +88 -0
- package/dist/transport/server/receive-pack/handler.d.mts +30 -0
- package/dist/transport/server/receive-pack/handler.mjs +156 -0
- package/dist/transport/server/receive-pack/index.d.mts +6 -0
- package/dist/transport/server/receive-pack/index.mjs +6 -0
- package/dist/transport/server/receive-pack/parse.d.mts +17 -0
- package/dist/transport/server/receive-pack/parse.mjs +80 -0
- package/dist/transport/server/receive-pack/report-status.mjs +64 -0
- package/dist/transport/server/receive-pack/service.d.mts +41 -0
- package/dist/transport/server/receive-pack/service.mjs +39 -0
- package/dist/transport/server/receive-pack/types.d.mts +56 -0
- package/dist/transport/server/receive-pack/types.mjs +25 -0
- package/dist/transport/server/receive-pack/unpack.mjs +119 -0
- package/dist/transport/server/upload-pack/advertise.d.mts +20 -0
- package/dist/transport/server/upload-pack/advertise.mjs +30 -0
- package/dist/transport/server/upload-pack/command.d.mts +43 -0
- package/dist/transport/server/upload-pack/command.mjs +56 -0
- package/dist/transport/server/upload-pack/fetch.d.mts +43 -0
- package/dist/transport/server/upload-pack/fetch.mjs +217 -0
- package/dist/transport/server/upload-pack/index.d.mts +7 -0
- package/dist/transport/server/upload-pack/index.mjs +7 -0
- package/dist/transport/server/upload-pack/ls-refs.d.mts +38 -0
- package/dist/transport/server/upload-pack/ls-refs.mjs +113 -0
- package/dist/transport/server/upload-pack/service.d.mts +40 -0
- package/dist/transport/server/upload-pack/service.mjs +51 -0
- package/dist/transport/server/upload-pack/types.d.mts +11 -0
- package/dist/transport/server/upload-pack/types.mjs +21 -0
- package/dist/transport/upload-pack.d.mts +7 -0
- package/dist/transport/upload-pack.mjs +6 -0
- package/package.json +98 -0
package/README.md
ADDED
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
# nano-git
|
|
2
|
+
|
|
3
|
+
使用 TypeScript 实现的 Git 核心功能,专注于**裸仓库(bare repository)** 操作与服务端场景,
|
|
4
|
+
不涉及暂存区(index)和工作目录管理。
|
|
5
|
+
|
|
6
|
+
## 特性
|
|
7
|
+
|
|
8
|
+
- ✅ **SHA-1 哈希计算** — 与 Git 完全兼容的对象哈希
|
|
9
|
+
- ✅ **Git 对象模型** — 支持 blob、tree、commit、tag 四种对象类型
|
|
10
|
+
- ✅ **对象序列化/反序列化** — 完整的二进制格式支持
|
|
11
|
+
- ✅ **对象存储** — 文件系统存储和内存存储两种模式
|
|
12
|
+
- ✅ **Packfile 支持** — 读取、写入、索引生成、delta 编解码
|
|
13
|
+
- ✅ **引用管理** — refs 验证、解析、存储(文件系统 + 内存)
|
|
14
|
+
- ✅ **仓库 API** — 类似 Git plumbing 命令的高层接口(init、hash-object、cat-file、commit-tree、update-ref 等)
|
|
15
|
+
- ✅ **增量 Tree Patch** — 不经暂存区直接修改目录结构(`patchTree`、`readTree`、`walkTree`)
|
|
16
|
+
- ✅ **可达性遍历与 GC** — 基于 refs 的可达对象收集、repack、gc
|
|
17
|
+
- ✅ **Smart HTTP 传输** — 基于 Bun fetch 的 Git 协议客户端,支持 `fetch()`/`push()` 与完整的 Import Session 物化流程
|
|
18
|
+
- ✅ **类型安全** — 完整的 TypeScript 类型定义
|
|
19
|
+
- ✅ **Reference Transaction** — 批量 ref 更新的原子性保障,支持 Hooks 回调与自动回滚
|
|
20
|
+
|
|
21
|
+
## 安装
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
bun install
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## 快速开始
|
|
28
|
+
|
|
29
|
+
### 5 行完成"创建 → 写入 → 提交"
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { createMemoryRepository } from "nano-git/repository/memory";
|
|
33
|
+
|
|
34
|
+
const repo = createMemoryRepository();
|
|
35
|
+
const treeHash = repo.createTree([
|
|
36
|
+
{ mode: "100644", name: "hello.txt", hash: repo.writeBlob(Buffer.from("Hello!")) },
|
|
37
|
+
]);
|
|
38
|
+
const commitHash = repo.createCommit(treeHash, [], "Initial commit", {
|
|
39
|
+
name: "You",
|
|
40
|
+
email: "you@example.com",
|
|
41
|
+
timestamp: Math.floor(Date.now() / 1000),
|
|
42
|
+
timezone: "+0800",
|
|
43
|
+
});
|
|
44
|
+
console.log(`Created commit: ${commitHash}`);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 从远端仓库拉取
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { initRepository } from "nano-git/repository/file";
|
|
51
|
+
|
|
52
|
+
const repo = initRepository("/tmp/project");
|
|
53
|
+
await repo.fetch("https://github.com/user/repo.git");
|
|
54
|
+
// 所有分支和标签已就绪
|
|
55
|
+
console.log(repo.listBranches());
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 内存仓库完整工作流
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
import { createMemoryRepository } from "nano-git/repository/memory";
|
|
62
|
+
import type { GitAuthor } from "nano-git";
|
|
63
|
+
|
|
64
|
+
const repo = createMemoryRepository();
|
|
65
|
+
|
|
66
|
+
// 写入文件内容
|
|
67
|
+
const fileHash = repo.writeBlob(Buffer.from("Hello, nano-git!"));
|
|
68
|
+
|
|
69
|
+
// 创建目录结构
|
|
70
|
+
const treeHash = repo.createTree([{ mode: "100644", name: "README.md", hash: fileHash }]);
|
|
71
|
+
|
|
72
|
+
// 创建提交
|
|
73
|
+
const author: GitAuthor = {
|
|
74
|
+
name: "Your Name",
|
|
75
|
+
email: "you@example.com",
|
|
76
|
+
timestamp: Math.floor(Date.now() / 1000),
|
|
77
|
+
timezone: "+0800",
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const commitHash = repo.createCommit(
|
|
81
|
+
treeHash,
|
|
82
|
+
[], // 初始提交
|
|
83
|
+
"Initial commit",
|
|
84
|
+
author,
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
console.log(`Created commit: ${commitHash}`);
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 启动 Smart HTTP 服务器
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
import { openRepository } from "nano-git/repository/file";
|
|
94
|
+
import { createSmartHttpHandler } from "nano-git/transport/http";
|
|
95
|
+
|
|
96
|
+
// 创建 Git HTTP 后端处理函数(框架无关,标准 Request/Response)
|
|
97
|
+
const handler = createSmartHttpHandler(openRepository("/path/to/repo"));
|
|
98
|
+
|
|
99
|
+
// 接入 Bun.serve — 直接作为 fetch 处理器
|
|
100
|
+
Bun.serve({ port: 8080, fetch: handler });
|
|
101
|
+
|
|
102
|
+
console.log("Git server running on http://localhost:8080");
|
|
103
|
+
// 客户端可用 `git clone http://localhost:8080/` 拉取
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 使用显式仓库后端
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
import { createMemoryRepositoryBackend } from "nano-git/backend/memory";
|
|
110
|
+
import { createRepository } from "nano-git/repository/core";
|
|
111
|
+
|
|
112
|
+
const backend = createMemoryRepositoryBackend();
|
|
113
|
+
const repo = createRepository(backend);
|
|
114
|
+
|
|
115
|
+
repo.createBranch("main", repo.createTree([]));
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 使用文件系统仓库
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
import { initRepository, openRepository } from "nano-git/repository/file";
|
|
122
|
+
|
|
123
|
+
// 初始化新仓库
|
|
124
|
+
const repo = initRepository("/path/to/project");
|
|
125
|
+
|
|
126
|
+
// 或打开已有仓库
|
|
127
|
+
const existingRepo = openRepository("/path/to/existing/project");
|
|
128
|
+
|
|
129
|
+
// 写入文件
|
|
130
|
+
const hash = repo.writeBlobFile("/path/to/file.txt");
|
|
131
|
+
|
|
132
|
+
// 将整个目录写入 tree
|
|
133
|
+
const treeHash = repo.writeTree("/path/to/directory");
|
|
134
|
+
|
|
135
|
+
// 更新引用
|
|
136
|
+
repo.updateRef("refs/heads/main", commitHash);
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
`openRepository()` 默认会同时读取 `.git/objects/` 下的 loose objects 和 `.git/objects/pack/` 下的 packed objects,因此可以直接打开经过 `git gc` 或 `git repack` 的真实仓库(包括裸仓库)。搭配 `initRepository()` 的第二个参数可初始化为裸仓库布局。
|
|
140
|
+
|
|
141
|
+
### 生成 Packfile
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
import { openRepository } from "nano-git/repository/file";
|
|
145
|
+
|
|
146
|
+
const repo = openRepository("/path/to/repo");
|
|
147
|
+
|
|
148
|
+
// 打包当前仓库中所有可见对象
|
|
149
|
+
const result = repo.writePack();
|
|
150
|
+
console.log(result.packPath);
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Repack 仓库
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
import { openRepository } from "nano-git/repository/file";
|
|
157
|
+
|
|
158
|
+
const repo = openRepository("/path/to/repo");
|
|
159
|
+
|
|
160
|
+
// 重新生成 pack,并删除旧 pack 文件
|
|
161
|
+
repo.repack();
|
|
162
|
+
|
|
163
|
+
// 如需同时移除已打包的 loose objects:
|
|
164
|
+
repo.repack({ pruneLoose: true });
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### 基于可达对象执行 GC
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import { openRepository } from "nano-git/repository/file";
|
|
171
|
+
|
|
172
|
+
const repo = openRepository("/path/to/repo");
|
|
173
|
+
|
|
174
|
+
// 仅保留从 HEAD、分支、标签可达的对象
|
|
175
|
+
const result = repo.gc();
|
|
176
|
+
console.log(result.objectCount);
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### 从远程仓库导入(Import Session)
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
import { initRepository } from "nano-git/repository/file";
|
|
183
|
+
|
|
184
|
+
const repo = initRepository("/tmp/my-clone");
|
|
185
|
+
|
|
186
|
+
const session = await repo.openImportSession({
|
|
187
|
+
url: "https://github.com/user/repo",
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
const branches = session.select("refs/heads/*");
|
|
191
|
+
const defaultBranch = session.defaultBranch();
|
|
192
|
+
|
|
193
|
+
const plan = session
|
|
194
|
+
.plan()
|
|
195
|
+
.materialize(branches)
|
|
196
|
+
.toNamespace("refs/mirrors/upstream/*", {
|
|
197
|
+
policy: { mode: "mirror" },
|
|
198
|
+
prune: true,
|
|
199
|
+
})
|
|
200
|
+
.materialize(defaultBranch)
|
|
201
|
+
.toBranch("main")
|
|
202
|
+
.materialize(defaultBranch)
|
|
203
|
+
.setHead();
|
|
204
|
+
|
|
205
|
+
const preview = await plan.preview();
|
|
206
|
+
console.log(preview.refOperations.map((op) => op.localRef));
|
|
207
|
+
console.log(preview.prefetchedObjects);
|
|
208
|
+
|
|
209
|
+
const result = await plan.apply();
|
|
210
|
+
console.log(`Imported ${result.importedObjects} objects`);
|
|
211
|
+
console.log(`Updated ${result.updatedRefs.size} refs`);
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
`preview()` 可能会为严格校验预取缺失对象,但不会写入 refs 或 `HEAD`。`apply()` 只会消费同一计划的冻结 preview 结果。
|
|
215
|
+
|
|
216
|
+
带认证的导入(私有仓库):
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
const session = await repo.openImportSession({
|
|
220
|
+
url: "https://github.com/org/private-repo",
|
|
221
|
+
token: "ghp_xxxxxxxxxxxx",
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
const session2 = await repo.openImportSession({
|
|
225
|
+
url: "https://gitlab.com/org/private-repo",
|
|
226
|
+
headers: { "Job-Token": "xxxxxxxx" },
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
await session.plan().materialize(session.defaultBranch()).toBranch("main").apply();
|
|
230
|
+
await session2
|
|
231
|
+
.plan()
|
|
232
|
+
.materialize(session2.allRefs())
|
|
233
|
+
.toNamespace("refs/mirrors/upstream/*", {
|
|
234
|
+
policy: { mode: "mirror" },
|
|
235
|
+
prune: true,
|
|
236
|
+
})
|
|
237
|
+
.apply();
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
如果你需要更底层的控制,也可以直接使用 transport 层的独立函数:
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
import {
|
|
244
|
+
buildUploadPackRequest,
|
|
245
|
+
createUploadPackHttpClient,
|
|
246
|
+
decodeUploadPackResponse,
|
|
247
|
+
} from "nano-git/transport";
|
|
248
|
+
import { sha1 } from "nano-git";
|
|
249
|
+
|
|
250
|
+
// 仅获取引用广告
|
|
251
|
+
const client = createUploadPackHttpClient("https://github.com/user/repo");
|
|
252
|
+
const adv = await client.advertise();
|
|
253
|
+
console.log(adv.refs);
|
|
254
|
+
|
|
255
|
+
// 带认证的底层传输控制
|
|
256
|
+
const authedClient = createUploadPackHttpClient("https://github.com/user/repo", {
|
|
257
|
+
token: "ghp_xxxxxxxx",
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
const body = buildUploadPackRequest(
|
|
261
|
+
[sha1("95d09f2b10159347eece71399a7e2e907ea3df4f")],
|
|
262
|
+
[],
|
|
263
|
+
["multi_ack", "side-band-64k", "ofs-delta"],
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
const raw = await authedClient.request(body);
|
|
267
|
+
const { packfile } = decodeUploadPackResponse(raw);
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### 对象序列化
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
import { serialize, deserialize } from "nano-git/objects";
|
|
274
|
+
import type { GitBlob } from "nano-git";
|
|
275
|
+
|
|
276
|
+
const blob: GitBlob = {
|
|
277
|
+
type: "blob",
|
|
278
|
+
content: Buffer.from("file content"),
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
// 序列化为 Git 存储格式
|
|
282
|
+
const data = serialize(blob);
|
|
283
|
+
// => Buffer("blob 12\0file content")
|
|
284
|
+
|
|
285
|
+
// 反序列化
|
|
286
|
+
const obj = deserialize(data);
|
|
287
|
+
console.log(obj.type); // => "blob"
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## 运行演示
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
bun run examples/demo.ts
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
演示脚本展示了:
|
|
297
|
+
|
|
298
|
+
- SHA-1 哈希计算
|
|
299
|
+
- 对象序列化/反序列化
|
|
300
|
+
- 内存仓库操作
|
|
301
|
+
- 创建 blob、tree、commit 对象
|
|
302
|
+
- 对象存储和读取
|
|
303
|
+
|
|
304
|
+
## 导出结构
|
|
305
|
+
|
|
306
|
+
本库默认入口 `"nano-git"` 直接提供高频的纯计算能力:类型、错误、对象编解码、refs 工具和 SHA-1 工具。
|
|
307
|
+
带 `node:fs` / `node:zlib` 的运行时能力通过子路径显式导入,例如 `nano-git/repository/file`、`nano-git/pack`、`nano-git/transport/http`。
|
|
308
|
+
tree-shaking 主要依赖模块本身的无副作用结构,而不是把所有 API 都拆成叶子级子路径。完整入口表见 `package.json` 的 `exports` 与 `src/index.ts` 的 JSDoc。
|
|
309
|
+
|
|
310
|
+
## Git 对象模型
|
|
311
|
+
|
|
312
|
+
Git 使用内容寻址文件系统,所有对象通过 SHA-1 哈希寻址:
|
|
313
|
+
|
|
314
|
+
### Blob(文件内容)
|
|
315
|
+
|
|
316
|
+
存储文件的原始内容,不包含文件名或权限信息。
|
|
317
|
+
|
|
318
|
+
### Tree(目录结构)
|
|
319
|
+
|
|
320
|
+
存储目录内容,每个条目包含:
|
|
321
|
+
|
|
322
|
+
- 文件模式(如 `100644` 普通文件,`100755` 可执行文件,`040000` 目录)
|
|
323
|
+
- 文件名
|
|
324
|
+
- 指向 blob 或子 tree 的哈希
|
|
325
|
+
|
|
326
|
+
### Commit(快照)
|
|
327
|
+
|
|
328
|
+
存储一次提交的完整信息:
|
|
329
|
+
|
|
330
|
+
- 指向 tree 的哈希(项目快照)
|
|
331
|
+
- 父 commit 哈希列表(merge commit 有多个父节点)
|
|
332
|
+
- 作者和提交者信息
|
|
333
|
+
- 提交信息
|
|
334
|
+
|
|
335
|
+
### Tag(标签)
|
|
336
|
+
|
|
337
|
+
带注释的标签,指向特定对象(通常是 commit)。
|
|
338
|
+
|
|
339
|
+
## 对象存储格式
|
|
340
|
+
|
|
341
|
+
所有 Git 对象以以下格式存储:
|
|
342
|
+
|
|
343
|
+
```
|
|
344
|
+
<type> <size>\0<content>
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
例如,一个包含 "hello world" 的 blob:
|
|
348
|
+
|
|
349
|
+
```
|
|
350
|
+
blob 11\0hello world
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
对象在 `.git/objects/` 目录下以 zlib 压缩格式存储,路径为:
|
|
354
|
+
|
|
355
|
+
```
|
|
356
|
+
.git/objects/<前2字符>/<剩余38字符>
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
例如:`.git/objects/95/d09f2b10159347eece71399a7e2e907ea3df4f`
|
|
360
|
+
|
|
361
|
+
## 开发
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
# 类型检查
|
|
365
|
+
bun tsc --noEmit
|
|
366
|
+
|
|
367
|
+
# 运行测试
|
|
368
|
+
bun test
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
## 路线图
|
|
372
|
+
|
|
373
|
+
### 已实现
|
|
374
|
+
|
|
375
|
+
- [x] 基础数据结构和哈希算法
|
|
376
|
+
- [x] 对象序列化/反序列化
|
|
377
|
+
- [x] 对象存储(文件系统和内存)
|
|
378
|
+
- [x] Packfile 支持(读取、写入、索引、delta 编解码、打包构建器)
|
|
379
|
+
- [x] 引用管理(refs、HEAD、符号引用解析)
|
|
380
|
+
- [x] 仓库 API(init、open、hash-object、cat-file、write-tree、commit-tree、update-ref、branch、tag)
|
|
381
|
+
- [x] 可达性遍历与 GC(repack、gc)
|
|
382
|
+
- [x] **Smart HTTP 传输** — pkt-line 编解码、ref 广告解析、side-band 解复用、Fetch / Push 协议、Import Session 集成
|
|
383
|
+
- [x] **Reference Transaction** — 批量 ref 更新原子性、lock-then-rename 文件事务、生命周期 Hooks
|
|
384
|
+
|
|
385
|
+
- [x] **Smart HTTP 服务端(upload-pack)** — 类 git-http-backend、框架无关的 HTTP handler,支持 ls-refs 和 fetch 命令,协议实现与编排器解耦
|
|
386
|
+
- [x] **Smart HTTP 服务端(v1 receive-pack)** — 服务端 push 支持,基于 v1 协议,含 ref 广告、packfile 解包、ref 校验与 report-status
|
|
387
|
+
|
|
388
|
+
### 规划中(聚焦裸仓库/服务端场景)
|
|
389
|
+
|
|
390
|
+
- [ ] **Partial Clone / Filter 支持** — 按需对象过滤传输
|
|
391
|
+
|
|
392
|
+
### 非目标(明确不实现)
|
|
393
|
+
|
|
394
|
+
- ~~暂存区(index)操作~~ — 如 `git add`、`git status`
|
|
395
|
+
- ~~工作目录管理~~ — 如 `git checkout`、`git restore`
|
|
396
|
+
- ~~文件级别的差异计算(diff)~~ — 如 `git diff`
|
|
397
|
+
- ~~多格式哈希支持~~ — SHA-256 兼容准备(当前仅 SHA-1)
|
|
398
|
+
|
|
399
|
+
## 参考资料
|
|
400
|
+
|
|
401
|
+
- [Git Internals - Git Objects](https://git-scm.com/book/en/v2/Git-Internals-Git-Objects)
|
|
402
|
+
- [Git Internals - Git References](https://git-scm.com/book/en/v2/Git-Internals-Git-References)
|
|
403
|
+
- [Git Repository Layout](https://git-scm.com/docs/gitrepository-layout)
|
|
404
|
+
|
|
405
|
+
## 许可证
|
|
406
|
+
|
|
407
|
+
MIT
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { RepositoryBackend } from "./types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/backend/file-backend.d.ts
|
|
4
|
+
/** 创建文件系统仓库后端的可选参数 */
|
|
5
|
+
interface CreateFileRepositoryBackendOptions {
|
|
6
|
+
/**
|
|
7
|
+
* 是否将 .git/objects/pack 下的 packfile 纳入读取路径
|
|
8
|
+
*
|
|
9
|
+
* 默认启用,使 openRepository() 能读取真实 Git 仓库中的 packed objects。
|
|
10
|
+
*/
|
|
11
|
+
readonly includePack?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 创建基于文件系统的仓库后端
|
|
15
|
+
*
|
|
16
|
+
* @param gitDir - .git 目录的路径
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* const backend = createFileRepositoryBackend("/path/to/repo/.git");
|
|
21
|
+
* const repo = createRepository(backend);
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
declare function createFileRepositoryBackend(gitDir: string, options?: CreateFileRepositoryBackendOptions): RepositoryBackend;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { CreateFileRepositoryBackendOptions, createFileRepositoryBackend };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { createPackBuilder } from "../pack/pack-builder.mjs";
|
|
2
|
+
import { createPackObjectStore } from "../pack/pack-store.mjs";
|
|
3
|
+
import { createCompositeObjectDatabase } from "../pack/composite-store.mjs";
|
|
4
|
+
import { createFileObjectStore } from "../odb/file.mjs";
|
|
5
|
+
import { createFileRefStore } from "../refs/file.mjs";
|
|
6
|
+
import { createFileShallowStore } from "../refs/shallow/file.mjs";
|
|
7
|
+
import { existsSync, unlinkSync } from "node:fs";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
//#region src/backend/file-backend.ts
|
|
10
|
+
/**
|
|
11
|
+
* 基于文件系统的仓库后端
|
|
12
|
+
*
|
|
13
|
+
* 将 .git 目录下的 loose objects、packfile 和引用存储
|
|
14
|
+
* 组合为统一的 RepositoryBackend。
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* 创建基于文件系统的仓库后端
|
|
18
|
+
*
|
|
19
|
+
* @param gitDir - .git 目录的路径
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* const backend = createFileRepositoryBackend("/path/to/repo/.git");
|
|
24
|
+
* const repo = createRepository(backend);
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
function createFileRepositoryBackend(gitDir, options = {}) {
|
|
28
|
+
const looseObjects = createFileObjectStore(gitDir);
|
|
29
|
+
const packSource = createPackObjectStore(gitDir);
|
|
30
|
+
const objects = options.includePack === false ? looseObjects : createCompositeObjectDatabase(looseObjects, packSource);
|
|
31
|
+
function refreshPackView() {
|
|
32
|
+
packSource.refresh();
|
|
33
|
+
}
|
|
34
|
+
function writeFromSource(source, hashes) {
|
|
35
|
+
const builder = createPackBuilder(gitDir);
|
|
36
|
+
for (const hash of hashes) builder.addRaw(source.read(hash));
|
|
37
|
+
const result = builder.build();
|
|
38
|
+
refreshPackView();
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
function deletePackFiles(checksums, keepChecksum) {
|
|
42
|
+
for (const checksum of checksums) {
|
|
43
|
+
if (checksum === keepChecksum) continue;
|
|
44
|
+
const packPath = join(gitDir, "objects", "pack", `pack-${checksum}.pack`);
|
|
45
|
+
const idxPath = join(gitDir, "objects", "pack", `pack-${checksum}.idx`);
|
|
46
|
+
if (existsSync(packPath)) unlinkSync(packPath);
|
|
47
|
+
if (existsSync(idxPath)) unlinkSync(idxPath);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const packs = {
|
|
51
|
+
source: packSource,
|
|
52
|
+
createBuilder() {
|
|
53
|
+
return createPackBuilder(gitDir);
|
|
54
|
+
},
|
|
55
|
+
writeRawObjects(objects) {
|
|
56
|
+
const builder = createPackBuilder(gitDir);
|
|
57
|
+
for (const obj of objects) builder.addRaw(obj);
|
|
58
|
+
const result = builder.build();
|
|
59
|
+
refreshPackView();
|
|
60
|
+
return result;
|
|
61
|
+
},
|
|
62
|
+
writeFromSource(source, hashes) {
|
|
63
|
+
return writeFromSource(source, hashes);
|
|
64
|
+
},
|
|
65
|
+
repack(source, options = {}) {
|
|
66
|
+
const hashes = Array.from(options.hashes ?? source.list());
|
|
67
|
+
const existingChecksums = packSource.listPacks().map((pack) => pack.checksum);
|
|
68
|
+
const result = writeFromSource(source, hashes);
|
|
69
|
+
if (options.replaceExistingPacks !== false) deletePackFiles(existingChecksums, result.checksum);
|
|
70
|
+
refreshPackView();
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
return {
|
|
75
|
+
gitDir,
|
|
76
|
+
objects,
|
|
77
|
+
refs: createFileRefStore(gitDir),
|
|
78
|
+
shallow: createFileShallowStore(gitDir),
|
|
79
|
+
packs
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
//#endregion
|
|
83
|
+
export { createFileRepositoryBackend };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { SHA1 } from "../core/types.mjs";
|
|
2
|
+
import { RepositoryBackend } from "./types.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/backend/memory-backend.d.ts
|
|
5
|
+
/** 创建内存仓库后端的可选参数 */
|
|
6
|
+
interface CreateMemoryRepositoryBackendOptions {
|
|
7
|
+
/** 初始引用集合,默认包含 HEAD -> refs/heads/main */
|
|
8
|
+
readonly initialRefs?: Map<string, string>;
|
|
9
|
+
/** 初始 shallow 边界集合,用于测试 shallow 仓库场景 */
|
|
10
|
+
readonly initialShallow?: SHA1[];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 创建基于内存的仓库后端
|
|
14
|
+
*
|
|
15
|
+
* @param options - 可选初始化参数
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* const backend = createMemoryRepositoryBackend();
|
|
20
|
+
* const repo = createRepository(backend);
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
declare function createMemoryRepositoryBackend(options?: CreateMemoryRepositoryBackendOptions): RepositoryBackend;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { CreateMemoryRepositoryBackendOptions, createMemoryRepositoryBackend };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import "../core/types/refs.mjs";
|
|
2
|
+
import { createMemoryObjectStore } from "../odb/memory.mjs";
|
|
3
|
+
import { createMemoryRefStore } from "../refs/memory.mjs";
|
|
4
|
+
import { createMemoryShallowStore } from "../refs/shallow/memory.mjs";
|
|
5
|
+
//#region src/backend/memory-backend.ts
|
|
6
|
+
/**
|
|
7
|
+
* 基于内存的仓库后端
|
|
8
|
+
*
|
|
9
|
+
* 适用于测试和临时操作场景。
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* 创建基于内存的仓库后端
|
|
13
|
+
*
|
|
14
|
+
* @param options - 可选初始化参数
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* const backend = createMemoryRepositoryBackend();
|
|
19
|
+
* const repo = createRepository(backend);
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
function createMemoryRepositoryBackend(options = {}) {
|
|
23
|
+
const refs = options.initialRefs ?? /* @__PURE__ */ new Map([["HEAD", `ref: refs/heads/main`]]);
|
|
24
|
+
return {
|
|
25
|
+
gitDir: null,
|
|
26
|
+
objects: createMemoryObjectStore(),
|
|
27
|
+
refs: createMemoryRefStore(refs),
|
|
28
|
+
shallow: createMemoryShallowStore(options.initialShallow),
|
|
29
|
+
packs: null
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { createMemoryRepositoryBackend };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { RawGitObject, SHA1 } from "../core/types.mjs";
|
|
2
|
+
import { RefStore, RefTransactionHook } from "../core/types/refs.mjs";
|
|
3
|
+
import { ShallowStore } from "../core/types/shallow.mjs";
|
|
4
|
+
import { ObjectDatabase, ObjectSource } from "../core/types/odb.mjs";
|
|
5
|
+
import { PackBuildResult } from "../pack/pack-builder-types.mjs";
|
|
6
|
+
import { PackBuilder } from "../pack/pack-builder.mjs";
|
|
7
|
+
import { PackObjectStore } from "../pack/pack-store.mjs";
|
|
8
|
+
|
|
9
|
+
//#region src/backend/types.d.ts
|
|
10
|
+
/** 仓库级 repack 选项 */
|
|
11
|
+
interface RepositoryRepackOptions {
|
|
12
|
+
/** 要打包的对象列表,默认使用 source.list() 的全部对象 */
|
|
13
|
+
readonly hashes?: Iterable<SHA1>;
|
|
14
|
+
/** 是否在成功写入新 pack 后删除旧 pack,默认 true */
|
|
15
|
+
readonly replaceExistingPacks?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* 是否删除已写入 pack 的 loose object 文件,默认 false
|
|
18
|
+
*
|
|
19
|
+
* 此选项由仓库层(RepositoryMaintenanceOperations)处理,
|
|
20
|
+
* RepositoryPackSupport 自身不处理 loose 对象删除。
|
|
21
|
+
*/
|
|
22
|
+
readonly pruneLoose?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/** 仓库级 gc 选项 */
|
|
25
|
+
interface RepositoryGCOptions {
|
|
26
|
+
/** 是否删除不可达的 loose objects,默认 true */
|
|
27
|
+
readonly pruneLoose?: boolean;
|
|
28
|
+
/** 是否替换旧 pack 文件,默认 true */
|
|
29
|
+
readonly replaceExistingPacks?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Packfile 层 repack 选项
|
|
33
|
+
*
|
|
34
|
+
* RepositoryPackSupport.repack() 的内部选项,
|
|
35
|
+
* 不包含 pruneLoose——那是仓库层的职责。
|
|
36
|
+
*/
|
|
37
|
+
interface PackRepackOptions {
|
|
38
|
+
/** 要打包的对象列表,默认使用 source.list() 的全部对象 */
|
|
39
|
+
readonly hashes?: Iterable<SHA1>;
|
|
40
|
+
/** 是否在成功写入新 pack 后删除旧 pack,默认 true */
|
|
41
|
+
readonly replaceExistingPacks?: boolean;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* 仓库 pack 支持接口
|
|
45
|
+
*
|
|
46
|
+
* 负责:
|
|
47
|
+
* - 暴露已存在的 pack 对象源
|
|
48
|
+
* - 创建新的 packfile
|
|
49
|
+
*
|
|
50
|
+
* GC 的编排逻辑(计算可达对象、删除不可达 loose 对象)不在本接口职责范围内,
|
|
51
|
+
* 请使用仓库层的 RepositoryMaintenanceOperations.gc()。
|
|
52
|
+
*/
|
|
53
|
+
interface RepositoryPackSupport {
|
|
54
|
+
/** 仅包含 packfile 中对象的只读对象源 */
|
|
55
|
+
readonly source: PackObjectStore;
|
|
56
|
+
/** 创建底层 PackBuilder */
|
|
57
|
+
createBuilder(): PackBuilder;
|
|
58
|
+
/** 将给定原始对象集合写入新的 packfile */
|
|
59
|
+
writeRawObjects(objects: Iterable<RawGitObject>): PackBuildResult;
|
|
60
|
+
/** 从对象源中读取指定对象并写入新的 packfile */
|
|
61
|
+
writeFromSource(source: ObjectSource, hashes: Iterable<SHA1>): PackBuildResult;
|
|
62
|
+
/** 执行仓库级 repack */
|
|
63
|
+
repack(source: ObjectSource, options?: PackRepackOptions): PackBuildResult;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* 仓库后端接口
|
|
67
|
+
*
|
|
68
|
+
* 聚合 Repository 所需的底层依赖:
|
|
69
|
+
* - objects: Git 对象存储
|
|
70
|
+
* - refs: Git 引用存储
|
|
71
|
+
* - shallow: Git shallow 边界存储
|
|
72
|
+
* - packs: Packfile 读写支持(可选)
|
|
73
|
+
* - gitDir: .git 目录路径(内存仓库为 null)
|
|
74
|
+
*/
|
|
75
|
+
interface RepositoryBackend {
|
|
76
|
+
/** Git 对象数据库(raw-first) */
|
|
77
|
+
readonly objects: ObjectDatabase;
|
|
78
|
+
/** Git 引用存储 */
|
|
79
|
+
readonly refs: RefStore;
|
|
80
|
+
/** Git shallow 边界存储 */
|
|
81
|
+
readonly shallow: ShallowStore;
|
|
82
|
+
/** Packfile 支持(内存仓库等后端可为 null) */
|
|
83
|
+
readonly packs: RepositoryPackSupport | null;
|
|
84
|
+
/** .git 目录路径(内存仓库为 null) */
|
|
85
|
+
readonly gitDir: string | null;
|
|
86
|
+
/** Reference transaction hooks(可选) */
|
|
87
|
+
readonly refTransactionHooks?: RefTransactionHook[];
|
|
88
|
+
}
|
|
89
|
+
//#endregion
|
|
90
|
+
export { PackRepackOptions, RepositoryBackend, RepositoryGCOptions, RepositoryPackSupport, RepositoryRepackOptions };
|