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
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { GitAuthor, ObjectType, SHA1 } from "../../core/types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/repository/ops/ref-types.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* 仓库引用相关操作
|
|
6
|
+
*/
|
|
7
|
+
interface RepositoryRefOperations {
|
|
8
|
+
/**
|
|
9
|
+
* 更新引用(ref)
|
|
10
|
+
*
|
|
11
|
+
* 等价于 `git update-ref <ref> <hash>`
|
|
12
|
+
*/
|
|
13
|
+
updateRef(ref: string, hash: SHA1): void;
|
|
14
|
+
/**
|
|
15
|
+
* 读取引用(ref)
|
|
16
|
+
*
|
|
17
|
+
* 等价于 `git rev-parse <ref>`
|
|
18
|
+
*/
|
|
19
|
+
readRef(ref: string): SHA1 | null;
|
|
20
|
+
/**
|
|
21
|
+
* 获取当前检出的分支名
|
|
22
|
+
*
|
|
23
|
+
* detached HEAD 时返回 null。
|
|
24
|
+
*/
|
|
25
|
+
getCurrentBranch(): string | null;
|
|
26
|
+
/**
|
|
27
|
+
* 创建分支
|
|
28
|
+
*
|
|
29
|
+
* 未提供目标哈希时,默认基于当前 HEAD。
|
|
30
|
+
*/
|
|
31
|
+
createBranch(name: string, hash?: SHA1): void;
|
|
32
|
+
/**
|
|
33
|
+
* 读取分支引用
|
|
34
|
+
*/
|
|
35
|
+
readBranch(name: string): SHA1 | null;
|
|
36
|
+
/**
|
|
37
|
+
* 列出所有分支名
|
|
38
|
+
*/
|
|
39
|
+
listBranches(): string[];
|
|
40
|
+
/**
|
|
41
|
+
* 删除分支
|
|
42
|
+
*/
|
|
43
|
+
deleteBranch(name: string): void;
|
|
44
|
+
/**
|
|
45
|
+
* 创建轻量标签
|
|
46
|
+
*
|
|
47
|
+
* 未提供目标哈希时,默认指向当前 HEAD。
|
|
48
|
+
*/
|
|
49
|
+
createTag(name: string, hash?: SHA1): void;
|
|
50
|
+
/**
|
|
51
|
+
* 创建附注标签(annotated tag)
|
|
52
|
+
*
|
|
53
|
+
* 返回 tag 对象自身的哈希。
|
|
54
|
+
*/
|
|
55
|
+
createAnnotatedTag(name: string, target: SHA1, message: string, tagger: GitAuthor, objectType?: ObjectType): SHA1;
|
|
56
|
+
/**
|
|
57
|
+
* 读取标签引用
|
|
58
|
+
*/
|
|
59
|
+
readTag(name: string): SHA1 | null;
|
|
60
|
+
/**
|
|
61
|
+
* 列出所有标签名
|
|
62
|
+
*/
|
|
63
|
+
listTags(): string[];
|
|
64
|
+
/**
|
|
65
|
+
* 删除标签
|
|
66
|
+
*/
|
|
67
|
+
deleteTag(name: string): void;
|
|
68
|
+
}
|
|
69
|
+
//#endregion
|
|
70
|
+
export { RepositoryRefOperations };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { SHA1 } from "../../core/types.mjs";
|
|
2
|
+
import { ObjectDatabase } from "../../core/types/odb.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/repository/tree/tree-patch.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Tree patch 操作定义
|
|
7
|
+
*
|
|
8
|
+
* - `upsert`: 路径不存在则创建,存在则覆盖。通过 mode 区分文件类型:
|
|
9
|
+
* - `"100644"` 普通文件
|
|
10
|
+
* - `"100755"` 可执行文件
|
|
11
|
+
* - `"120000"` 符号链接
|
|
12
|
+
* - `delete`: 删除文件、符号链接或目录条目。目录条目删除仅移除 parent tree 引用。
|
|
13
|
+
* - `rename`: 移动文件、符号链接或目录到新路径。源路径不存在则抛出异常。
|
|
14
|
+
* 目录 rename 只移动 tree entry 引用,子树内容(tree hash)不变。
|
|
15
|
+
*/
|
|
16
|
+
type TreePatchOp = {
|
|
17
|
+
readonly op: "upsert";
|
|
18
|
+
readonly path: string;
|
|
19
|
+
readonly mode: string;
|
|
20
|
+
readonly hash: SHA1;
|
|
21
|
+
} | {
|
|
22
|
+
readonly op: "delete";
|
|
23
|
+
readonly path: string;
|
|
24
|
+
} | {
|
|
25
|
+
readonly op: "rename";
|
|
26
|
+
readonly from: string;
|
|
27
|
+
readonly to: string;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Tree patch 结果
|
|
31
|
+
*/
|
|
32
|
+
interface TreePatchResult {
|
|
33
|
+
/** 新的根 tree 哈希 */
|
|
34
|
+
readonly rootHash: SHA1;
|
|
35
|
+
/** 本次操作新写入的所有 tree 对象哈希(包含中间节点) */
|
|
36
|
+
readonly writtenTrees: readonly SHA1[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 对已有 tree 执行增量 patch 操作
|
|
40
|
+
*
|
|
41
|
+
* 算法描述:
|
|
42
|
+
* 1. 验证所有操作的路径格式
|
|
43
|
+
* 2. 将 ops 按 rename 操作分割为若干连续段
|
|
44
|
+
* 3. 段内 upsert/delete 保持现有 batch 算法(去重 + 递归)
|
|
45
|
+
* 4. rename 依次单独执行:查找源路径条目 → upsert(to) + delete(from) → batch 算法
|
|
46
|
+
* 5. 所有新/更新的条目按名称排序后写出新 tree
|
|
47
|
+
*
|
|
48
|
+
* @param objects - 对象存储
|
|
49
|
+
* @param rootHash - 根 tree 哈希
|
|
50
|
+
* @param ops - patch 操作列表(同路径多次操作最后一个生效,rename 按顺序逐一执行)
|
|
51
|
+
* @returns patch 结果
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* const result = patchTree(objects, rootHash, [
|
|
56
|
+
* { op: "upsert", path: "src/main.ts", mode: "100644", hash: blobHash },
|
|
57
|
+
* { op: "delete", path: "old.ts" },
|
|
58
|
+
* { op: "rename", from: "src/utils", to: "lib/utils" },
|
|
59
|
+
* ]);
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
declare function patchTree(objects: ObjectDatabase, rootHash: SHA1, ops: TreePatchOp[]): TreePatchResult;
|
|
63
|
+
//#endregion
|
|
64
|
+
export { TreePatchOp, TreePatchResult, patchTree };
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { readObject, writeObject } from "../../objects/raw.mjs";
|
|
2
|
+
//#region src/repository/tree/tree-patch.ts
|
|
3
|
+
/**
|
|
4
|
+
* 增量式 Tree Patch 操作
|
|
5
|
+
*
|
|
6
|
+
* 在不完整重新构造整棵树的前提下,对现有 tree 打补丁,
|
|
7
|
+
* 只更新受影响的路径,支持增、删、改、重命名操作。
|
|
8
|
+
*
|
|
9
|
+
* 核心策略:
|
|
10
|
+
* - 声明式 patch 列表,同路径多次操作最后一个生效
|
|
11
|
+
* - 自动创建缺失的中间目录(类似 mkdir -p)
|
|
12
|
+
* - delete 支持文件/符号链接/目录条目
|
|
13
|
+
* - rename 支持文件/符号链接/目录(直接移动 tree 引用,无需递归重写子树)
|
|
14
|
+
* - rename 按顺序逐一处理,upsert/delete 段内保持 batch 算法
|
|
15
|
+
* - 不存在的路径 delete/rename 会抛出异常
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* 对已有 tree 执行增量 patch 操作
|
|
19
|
+
*
|
|
20
|
+
* 算法描述:
|
|
21
|
+
* 1. 验证所有操作的路径格式
|
|
22
|
+
* 2. 将 ops 按 rename 操作分割为若干连续段
|
|
23
|
+
* 3. 段内 upsert/delete 保持现有 batch 算法(去重 + 递归)
|
|
24
|
+
* 4. rename 依次单独执行:查找源路径条目 → upsert(to) + delete(from) → batch 算法
|
|
25
|
+
* 5. 所有新/更新的条目按名称排序后写出新 tree
|
|
26
|
+
*
|
|
27
|
+
* @param objects - 对象存储
|
|
28
|
+
* @param rootHash - 根 tree 哈希
|
|
29
|
+
* @param ops - patch 操作列表(同路径多次操作最后一个生效,rename 按顺序逐一执行)
|
|
30
|
+
* @returns patch 结果
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* const result = patchTree(objects, rootHash, [
|
|
35
|
+
* { op: "upsert", path: "src/main.ts", mode: "100644", hash: blobHash },
|
|
36
|
+
* { op: "delete", path: "old.ts" },
|
|
37
|
+
* { op: "rename", from: "src/utils", to: "lib/utils" },
|
|
38
|
+
* ]);
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
function patchTree(objects, rootHash, ops) {
|
|
42
|
+
if (ops.length === 0) return {
|
|
43
|
+
rootHash,
|
|
44
|
+
writtenTrees: []
|
|
45
|
+
};
|
|
46
|
+
for (const op of ops) if (op.op === "rename") {
|
|
47
|
+
validatePath(op.from);
|
|
48
|
+
validatePath(op.to);
|
|
49
|
+
} else validatePath(op.path);
|
|
50
|
+
const result = processOpsSequentially(objects, rootHash, ops);
|
|
51
|
+
return {
|
|
52
|
+
rootHash: result.hash,
|
|
53
|
+
writtenTrees: result.written
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* 顺序执行 ops,rename 打断 batch
|
|
58
|
+
*
|
|
59
|
+
* 将连续的非 rename op 聚合成 batch,用现有递归算法处理;
|
|
60
|
+
* rename op 单独执行,每次在当前 tree 状态上查找源路径并转换为 upsert+delete。
|
|
61
|
+
*/
|
|
62
|
+
function processOpsSequentially(objects, rootHash, ops) {
|
|
63
|
+
let currentHash = rootHash;
|
|
64
|
+
const allWritten = [];
|
|
65
|
+
let currentBatch = [];
|
|
66
|
+
function flushBatch() {
|
|
67
|
+
if (currentBatch.length === 0) return;
|
|
68
|
+
const result = applyPatchBatch(objects, currentHash, currentBatch);
|
|
69
|
+
currentHash = result.hash;
|
|
70
|
+
allWritten.push(...result.written);
|
|
71
|
+
currentBatch = [];
|
|
72
|
+
}
|
|
73
|
+
for (const op of ops) if (op.op === "rename") {
|
|
74
|
+
flushBatch();
|
|
75
|
+
if (op.from === op.to) continue;
|
|
76
|
+
const entry = findEntryByPath(objects, currentHash, op.from);
|
|
77
|
+
if (entry === null) throw new Error(`Cannot rename '${op.from}': path does not exist`);
|
|
78
|
+
const renameOps = [{
|
|
79
|
+
op: "upsert",
|
|
80
|
+
path: op.to,
|
|
81
|
+
mode: entry.mode,
|
|
82
|
+
hash: entry.hash
|
|
83
|
+
}, {
|
|
84
|
+
op: "delete",
|
|
85
|
+
path: op.from
|
|
86
|
+
}];
|
|
87
|
+
const result = applyPatchBatch(objects, currentHash, renameOps);
|
|
88
|
+
currentHash = result.hash;
|
|
89
|
+
allWritten.push(...result.written);
|
|
90
|
+
} else currentBatch.push(op);
|
|
91
|
+
flushBatch();
|
|
92
|
+
return {
|
|
93
|
+
hash: currentHash,
|
|
94
|
+
written: allWritten
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* 在 tree 中查找路径对应的条目
|
|
99
|
+
*
|
|
100
|
+
* 沿路径依次读取 tree 对象,最后一段返回目标条目。
|
|
101
|
+
* 中间段必须为目录(mode "40000"),否则抛出异常。
|
|
102
|
+
*/
|
|
103
|
+
function findEntryByPath(objects, treeHash, path) {
|
|
104
|
+
const segments = path.split("/");
|
|
105
|
+
let currentHash = treeHash;
|
|
106
|
+
for (let i = 0; i < segments.length; i++) {
|
|
107
|
+
const obj = readObject(objects, currentHash);
|
|
108
|
+
if (obj.type !== "tree") throw new Error(`Expected tree at '${segments.slice(0, i).join("/") || "/"}', got '${obj.type}'`);
|
|
109
|
+
const entry = obj.entries.find((e) => e.name === segments[i]);
|
|
110
|
+
if (!entry) return null;
|
|
111
|
+
if (i === segments.length - 1) return entry;
|
|
112
|
+
if (entry.mode !== "40000") throw new Error(`Cannot access '${segments.slice(0, i + 1).join("/")}': not a directory (mode: ${entry.mode})`);
|
|
113
|
+
currentHash = entry.hash;
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* 验证 Git tree 路径格式
|
|
119
|
+
*/
|
|
120
|
+
function validatePath(path) {
|
|
121
|
+
if (path === "") throw new Error("Path must not be empty");
|
|
122
|
+
if (path.startsWith("/")) throw new Error(`Path must not start with '/': ${path}`);
|
|
123
|
+
if (path.endsWith("/")) throw new Error(`Path must not end with '/': ${path}`);
|
|
124
|
+
if (path.includes("//")) throw new Error(`Path must not contain consecutive slashes: ${path}`);
|
|
125
|
+
const segments = path.split("/");
|
|
126
|
+
for (const segment of segments) if (segment === "." || segment === "..") throw new Error(`Path must not contain '.' or '..': ${path}`);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* 按路径去重,同路径最后一个操作生效
|
|
130
|
+
*
|
|
131
|
+
* 仅处理 upsert/delete(rename 由顺序执行引擎单独处理,不会传给此函数)。
|
|
132
|
+
*/
|
|
133
|
+
function dedupOpsByPath(ops) {
|
|
134
|
+
const map = /* @__PURE__ */ new Map();
|
|
135
|
+
for (const op of ops) {
|
|
136
|
+
if (op.op === "rename") continue;
|
|
137
|
+
map.set(op.path, op);
|
|
138
|
+
}
|
|
139
|
+
return Array.from(map.values());
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* 对一批 upsert/delete 操作执行增量 patch
|
|
143
|
+
*
|
|
144
|
+
* 这是原先的 patchTree 实现,提取为内部函数供顺序执行引擎调用。
|
|
145
|
+
* 该函数不处理 rename 操作——调用方保证传入的 ops 不含 rename。
|
|
146
|
+
*/
|
|
147
|
+
function applyPatchBatch(objects, rootHash, ops) {
|
|
148
|
+
if (ops.length === 0) return {
|
|
149
|
+
hash: rootHash,
|
|
150
|
+
written: []
|
|
151
|
+
};
|
|
152
|
+
const upsertedPaths = /* @__PURE__ */ new Set();
|
|
153
|
+
for (const op of ops) if (op.op === "upsert") upsertedPaths.add(op.path);
|
|
154
|
+
const result = applyPatchRecursive(objects, rootHash, dedupOpsByPath(ops), "", upsertedPaths);
|
|
155
|
+
return {
|
|
156
|
+
hash: result.hash,
|
|
157
|
+
written: result.written
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* 递归应用 patch 操作到指定子树
|
|
162
|
+
*
|
|
163
|
+
* @param objects - 对象存储
|
|
164
|
+
* @param treeHash - 当前子树哈希(null 表示新建空树)
|
|
165
|
+
* @param ops - 去重后的操作列表(作用域为当前子树)
|
|
166
|
+
* @param prefix - 当前路径前缀(用于错误消息和 upsertedPaths 匹配)
|
|
167
|
+
* @param upsertedPaths - 原始操作列表中所有 upsert 的全路径集合
|
|
168
|
+
*/
|
|
169
|
+
function applyPatchRecursive(objects, treeHash, ops, prefix, upsertedPaths) {
|
|
170
|
+
const existingEntries = readTreeEntries(objects, treeHash);
|
|
171
|
+
const { directOps, deeperOps } = groupOpsByDepth(ops);
|
|
172
|
+
const finalEntryMap = /* @__PURE__ */ new Map();
|
|
173
|
+
const writtenTrees = [];
|
|
174
|
+
for (const [name, childOps] of deeperOps) {
|
|
175
|
+
const existingEntry = existingEntries.find((e) => e.name === name);
|
|
176
|
+
const existingHash = existingEntry?.hash ?? null;
|
|
177
|
+
if (existingEntry !== void 0 && existingEntry.mode !== "40000") throw new Error(`Cannot access '${prefix}${name}': existing entry is not a directory (mode: ${existingEntry.mode})`);
|
|
178
|
+
if (existingHash === null) {
|
|
179
|
+
const hasUpsertInBatch = childOps.some((op) => op.op === "upsert") || childOps.some((op) => op.op === "delete" && upsertedPaths.has(`${prefix}${name}/${op.path}`));
|
|
180
|
+
if (childOps.every((op) => op.op === "delete") && !hasUpsertInBatch) {
|
|
181
|
+
const samplePath = `${prefix}${name}/${childOps[0].path}`;
|
|
182
|
+
throw new Error(`Cannot delete '${samplePath}': path does not exist`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const result = applyPatchRecursive(objects, existingHash, childOps, `${prefix}${name}/`, upsertedPaths);
|
|
186
|
+
writtenTrees.push(...result.written);
|
|
187
|
+
finalEntryMap.set(name, {
|
|
188
|
+
mode: "40000",
|
|
189
|
+
name,
|
|
190
|
+
hash: result.hash
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
const deletedNames = /* @__PURE__ */ new Set();
|
|
194
|
+
for (const op of directOps) if (op.op === "upsert") finalEntryMap.set(op.path, {
|
|
195
|
+
mode: op.mode,
|
|
196
|
+
name: op.path,
|
|
197
|
+
hash: op.hash
|
|
198
|
+
});
|
|
199
|
+
else if (op.op === "delete") {
|
|
200
|
+
const fullPath = prefix + op.path;
|
|
201
|
+
const existsInExisting = existingEntries.some((e) => e.name === op.path);
|
|
202
|
+
const existsInCreated = finalEntryMap.has(op.path);
|
|
203
|
+
const existsInBatch = upsertedPaths.has(fullPath);
|
|
204
|
+
if (!existsInExisting && !existsInCreated && !existsInBatch) throw new Error(`Cannot delete '${prefix}${op.path}': path does not exist`);
|
|
205
|
+
deletedNames.add(op.path);
|
|
206
|
+
finalEntryMap.delete(op.path);
|
|
207
|
+
}
|
|
208
|
+
const finalEntries = [];
|
|
209
|
+
for (const entry of existingEntries) if (!finalEntryMap.has(entry.name) && !deletedNames.has(entry.name)) finalEntries.push(entry);
|
|
210
|
+
for (const [, entry] of finalEntryMap) finalEntries.push(entry);
|
|
211
|
+
finalEntries.sort((a, b) => a.name.localeCompare(b.name));
|
|
212
|
+
const newHash = writeObject(objects, {
|
|
213
|
+
type: "tree",
|
|
214
|
+
entries: finalEntries
|
|
215
|
+
});
|
|
216
|
+
writtenTrees.push(newHash);
|
|
217
|
+
return {
|
|
218
|
+
hash: newHash,
|
|
219
|
+
written: writtenTrees
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* 读取 tree 对象的条目列表
|
|
224
|
+
*/
|
|
225
|
+
function readTreeEntries(objects, treeHash) {
|
|
226
|
+
if (treeHash === null) return [];
|
|
227
|
+
const obj = readObject(objects, treeHash);
|
|
228
|
+
if (obj.type !== "tree") throw new Error(`Expected tree object, got '${obj.type}' for hash '${treeHash}'`);
|
|
229
|
+
return obj.entries;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* 将操作列表按路径深度分组
|
|
233
|
+
*
|
|
234
|
+
* 返回:
|
|
235
|
+
* - directOps: 路径只有一段的操作(直接作用于当前层)
|
|
236
|
+
* - deeperOps: 路径有多段的操作,按首段分组
|
|
237
|
+
*/
|
|
238
|
+
function groupOpsByDepth(ops) {
|
|
239
|
+
const directOps = [];
|
|
240
|
+
const deeperOps = /* @__PURE__ */ new Map();
|
|
241
|
+
for (const op of ops) {
|
|
242
|
+
if (op.op === "rename") continue;
|
|
243
|
+
const segments = op.path.split("/");
|
|
244
|
+
const first = segments[0];
|
|
245
|
+
if (segments.length === 1) directOps.push(op);
|
|
246
|
+
else {
|
|
247
|
+
const rest = segments.slice(1).join("/");
|
|
248
|
+
const childOp = op.op === "upsert" ? {
|
|
249
|
+
op: "upsert",
|
|
250
|
+
path: rest,
|
|
251
|
+
mode: op.mode,
|
|
252
|
+
hash: op.hash
|
|
253
|
+
} : {
|
|
254
|
+
op: "delete",
|
|
255
|
+
path: rest
|
|
256
|
+
};
|
|
257
|
+
const existing = deeperOps.get(first) ?? [];
|
|
258
|
+
existing.push(childOp);
|
|
259
|
+
deeperOps.set(first, existing);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
directOps,
|
|
264
|
+
deeperOps
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
//#endregion
|
|
268
|
+
export { patchTree };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { SHA1, TreeEntry } from "../../core/types.mjs";
|
|
2
|
+
import { ObjectDatabase } from "../../core/types/odb.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/repository/tree/tree-walk.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* 带完整路径的 tree 条目
|
|
7
|
+
*/
|
|
8
|
+
interface TreeEntryWithPath extends TreeEntry {
|
|
9
|
+
/** 相对于根 tree 的完整路径 */
|
|
10
|
+
readonly path: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 递归遍历 tree,返回所有条目的展平列表(深度优先,按目录排序)
|
|
14
|
+
*
|
|
15
|
+
* @param objects - 对象存储
|
|
16
|
+
* @param rootHash - 根 tree 哈希
|
|
17
|
+
* @returns 带完整路径的条目列表
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* const files = readTree(objects, treeHash);
|
|
22
|
+
* for (const entry of files) {
|
|
23
|
+
* console.log(entry.path, entry.mode, entry.hash);
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
declare function readTree(objects: ObjectDatabase, rootHash: SHA1): TreeEntryWithPath[];
|
|
28
|
+
/**
|
|
29
|
+
* 递归遍历 tree,对每个条目调用回调函数
|
|
30
|
+
*
|
|
31
|
+
* 深度优先,先遍历子目录(所有条目按目录分组输出)。
|
|
32
|
+
*
|
|
33
|
+
* @param objects - 对象存储
|
|
34
|
+
* @param rootHash - 根 tree 哈希
|
|
35
|
+
* @param visit - 对每个条目的回调
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* walkTree(objects, treeHash, (entry) => {
|
|
40
|
+
* console.log(entry.path);
|
|
41
|
+
* });
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
declare function walkTree(objects: ObjectDatabase, rootHash: SHA1, visit: (entry: TreeEntryWithPath) => void): void;
|
|
45
|
+
//#endregion
|
|
46
|
+
export { TreeEntryWithPath, readTree, walkTree };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { readObject } from "../../objects/raw.mjs";
|
|
2
|
+
//#region src/repository/tree/tree-walk.ts
|
|
3
|
+
/**
|
|
4
|
+
* Tree 遍历工具
|
|
5
|
+
*
|
|
6
|
+
* 提供展平的 tree 视图和递归遍历能力,
|
|
7
|
+
* 补充 patchTree 只有增量修改能力的不足。
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* 递归遍历 tree,返回所有条目的展平列表(深度优先,按目录排序)
|
|
11
|
+
*
|
|
12
|
+
* @param objects - 对象存储
|
|
13
|
+
* @param rootHash - 根 tree 哈希
|
|
14
|
+
* @returns 带完整路径的条目列表
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* const files = readTree(objects, treeHash);
|
|
19
|
+
* for (const entry of files) {
|
|
20
|
+
* console.log(entry.path, entry.mode, entry.hash);
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
function readTree(objects, rootHash) {
|
|
25
|
+
const result = [];
|
|
26
|
+
walkTreeRecursive(objects, rootHash, "", result);
|
|
27
|
+
return result;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 递归遍历 tree,对每个条目调用回调函数
|
|
31
|
+
*
|
|
32
|
+
* 深度优先,先遍历子目录(所有条目按目录分组输出)。
|
|
33
|
+
*
|
|
34
|
+
* @param objects - 对象存储
|
|
35
|
+
* @param rootHash - 根 tree 哈希
|
|
36
|
+
* @param visit - 对每个条目的回调
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* walkTree(objects, treeHash, (entry) => {
|
|
41
|
+
* console.log(entry.path);
|
|
42
|
+
* });
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
function walkTree(objects, rootHash, visit) {
|
|
46
|
+
walkTreeRecursive(objects, rootHash, "", void 0, visit);
|
|
47
|
+
}
|
|
48
|
+
function walkTreeRecursive(objects, treeHash, prefix, result, visit) {
|
|
49
|
+
const obj = readObject(objects, treeHash);
|
|
50
|
+
if (obj.type !== "tree") throw new Error(`Expected tree object, got '${obj.type}' for hash '${treeHash}'`);
|
|
51
|
+
for (const entry of obj.entries) {
|
|
52
|
+
const path = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
53
|
+
const entryWithPath = {
|
|
54
|
+
mode: entry.mode,
|
|
55
|
+
name: entry.name,
|
|
56
|
+
hash: entry.hash,
|
|
57
|
+
path
|
|
58
|
+
};
|
|
59
|
+
if (result) result.push(entryWithPath);
|
|
60
|
+
if (visit) visit(entryWithPath);
|
|
61
|
+
if (entry.mode === "40000") walkTreeRecursive(objects, entry.hash, path, result, visit);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
export { readTree, walkTree };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { writeObject } from "../../objects/raw.mjs";
|
|
2
|
+
import { lstatSync, readFileSync, readdirSync, readlinkSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
//#region src/repository/tree/tree-writer.ts
|
|
5
|
+
/**
|
|
6
|
+
* 工作目录到 tree 对象的写入工具
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* 递归将目录写入 tree 对象
|
|
10
|
+
*
|
|
11
|
+
* 遍历目录,为每个文件创建 blob,为每个子目录递归创建 tree,
|
|
12
|
+
* 为符号链接创建包含目标路径的 blob,最后将所有条目组合成一个 tree 对象。
|
|
13
|
+
*
|
|
14
|
+
* @param store - 对象存储
|
|
15
|
+
* @param dirPath - 要写入的目录路径
|
|
16
|
+
* @returns 根 tree 对象哈希
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* const hash = writeTreeRecursive(repo.objects, "/tmp/project");
|
|
21
|
+
* console.log(hash);
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
function writeTreeRecursive(store, dirPath) {
|
|
25
|
+
const entries = [];
|
|
26
|
+
const items = readdirSync(dirPath).sort();
|
|
27
|
+
for (const name of items) {
|
|
28
|
+
if (name === ".git") continue;
|
|
29
|
+
const fullPath = join(dirPath, name);
|
|
30
|
+
const stat = lstatSync(fullPath);
|
|
31
|
+
if (stat.isDirectory()) {
|
|
32
|
+
const subtreeHash = writeTreeRecursive(store, fullPath);
|
|
33
|
+
entries.push({
|
|
34
|
+
mode: "40000",
|
|
35
|
+
name,
|
|
36
|
+
hash: subtreeHash
|
|
37
|
+
});
|
|
38
|
+
} else if (stat.isSymbolicLink()) {
|
|
39
|
+
const target = readlinkSync(fullPath);
|
|
40
|
+
const blobHash = writeObject(store, {
|
|
41
|
+
type: "blob",
|
|
42
|
+
content: Buffer.from(target, "utf-8")
|
|
43
|
+
});
|
|
44
|
+
entries.push({
|
|
45
|
+
mode: "120000",
|
|
46
|
+
name,
|
|
47
|
+
hash: blobHash
|
|
48
|
+
});
|
|
49
|
+
} else if (stat.isFile()) {
|
|
50
|
+
const blobHash = writeObject(store, {
|
|
51
|
+
type: "blob",
|
|
52
|
+
content: readFileSync(fullPath)
|
|
53
|
+
});
|
|
54
|
+
const mode = stat.mode & 73 ? "100755" : "100644";
|
|
55
|
+
entries.push({
|
|
56
|
+
mode,
|
|
57
|
+
name,
|
|
58
|
+
hash: blobHash
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return writeObject(store, {
|
|
63
|
+
type: "tree",
|
|
64
|
+
entries
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
68
|
+
export { writeTreeRecursive };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { RefStore } from "../core/types/refs.mjs";
|
|
2
|
+
import { ShallowStore } from "../core/types/shallow.mjs";
|
|
3
|
+
import { ObjectDatabase } from "../core/types/odb.mjs";
|
|
4
|
+
import { RepositoryPackSupport } from "../backend/types.mjs";
|
|
5
|
+
import { RepoImportOperations } from "./import/import-session-types.mjs";
|
|
6
|
+
import { RepositoryFetchOperations } from "./ops/fetch-types.mjs";
|
|
7
|
+
import { RepositoryMaintenanceOperations } from "./ops/maintenance-types.mjs";
|
|
8
|
+
import { RepositoryFsObjectOperations, RepositoryObjectOperations } from "./ops/object-types.mjs";
|
|
9
|
+
import { RepositoryPushOperations } from "./ops/push-types.mjs";
|
|
10
|
+
import { RepositoryRefOperations } from "./ops/ref-types.mjs";
|
|
11
|
+
|
|
12
|
+
//#region src/repository/types.d.ts
|
|
13
|
+
/**
|
|
14
|
+
* Git 仓库接口
|
|
15
|
+
*/
|
|
16
|
+
interface Repository extends RepositoryObjectOperations, RepositoryRefOperations, RepositoryMaintenanceOperations, RepositoryPushOperations, RepositoryFetchOperations, RepoImportOperations {
|
|
17
|
+
/** Git 对象数据库(raw-first) */
|
|
18
|
+
readonly objects: ObjectDatabase;
|
|
19
|
+
/** Git 引用存储 */
|
|
20
|
+
readonly refs: RefStore;
|
|
21
|
+
/** Packfile 支持 */
|
|
22
|
+
readonly packs: RepositoryPackSupport | null;
|
|
23
|
+
/** Git shallow 边界存储 */
|
|
24
|
+
readonly shallow: ShallowStore;
|
|
25
|
+
/** .git 目录路径(内存仓库为 null) */
|
|
26
|
+
readonly gitDir: string | null;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 带文件系统扩展能力的仓库接口
|
|
30
|
+
*/
|
|
31
|
+
interface FileRepository extends Repository, RepositoryFsObjectOperations {
|
|
32
|
+
/** .git 目录路径 */
|
|
33
|
+
readonly gitDir: string;
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { FileRepository, Repository };
|
package/dist/sha1.d.mts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ObjectType, SHA1, assertObjectType, sha1 } from "./core/types.mjs";
|
|
2
|
+
import { hashData, hashObject } from "./core/hash-digest.mjs";
|
|
3
|
+
import { isValidSHA1 } from "./core/hash-path.mjs";
|
|
4
|
+
export { type ObjectType, type SHA1, assertObjectType, hashData, hashObject, isValidSHA1, sha1 };
|
package/dist/sha1.mjs
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { GitError } from "../../../core/errors.mjs";
|
|
2
|
+
import { GitServiceTransport } from "../../protocol/types.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/transport/client/receive-pack/http.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Smart HTTP 传输错误
|
|
7
|
+
*
|
|
8
|
+
* 当 HTTP 层面的传输出错时抛出(网络错误、非预期状态码等)。
|
|
9
|
+
*/
|
|
10
|
+
declare class SmartHttpError extends GitError {
|
|
11
|
+
readonly statusCode?: number | undefined;
|
|
12
|
+
constructor(message: string, statusCode?: number | undefined);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Smart HTTP 认证配置
|
|
16
|
+
*/
|
|
17
|
+
interface SmartHttpAuth {
|
|
18
|
+
readonly token?: string;
|
|
19
|
+
readonly headers?: Record<string, string>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 创建 receive-pack HTTP 客户端
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* const client = createReceivePackHttpClient("https://github.com/user/repo");
|
|
27
|
+
* const adv = await client.advertise();
|
|
28
|
+
* const raw = await client.request(body);
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
declare function createReceivePackHttpClient(baseUrl: string, auth?: SmartHttpAuth): GitServiceTransport;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { SmartHttpAuth, SmartHttpError, createReceivePackHttpClient };
|