git-dedup-core 0.1.0 → 2.0.1
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 +27 -23
- package/dist/index.d.ts +45 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +780 -164
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -3,17 +3,18 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/git-dedup-core)
|
|
4
4
|
[](https://www.npmjs.com/package/git-dedup-core)
|
|
5
5
|
[](https://github.com/bhouston/git-dedup/actions/workflows/ci.yml)
|
|
6
|
+
[](https://codecov.io/gh/bhouston/git-dedup)
|
|
6
7
|
[](https://github.com/bhouston/git-dedup/blob/main/LICENSE)
|
|
7
|
-
[](https://git-dedup.ben3d.ca/)
|
|
8
9
|
[](https://discord.gg/5J5Ur3F6Z2)
|
|
9
10
|
|
|
10
|
-
_The TypeScript storage engine behind [git-dedup](https://www.npmjs.com/package/git-dedup)._
|
|
11
|
+
**Faster checkouts, a fraction of the disk space.** _The TypeScript storage engine behind [git-dedup](https://www.npmjs.com/package/git-dedup)._
|
|
11
12
|
|
|
12
|
-
Build Node.js tools that
|
|
13
|
+
Build agent runners, editors, and other Node.js tools that create many checkouts without storing the same Git history many times. Clones, forks, and worktree submodules share one local object pool and borrow from it through Git alternates. The pool holds objects from different remotes, including forks and unrelated repositories.
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
The core owns cloning, submodule and worktree integration, repository consolidation, and store maintenance. It invokes native Git; the CLI handles command parsing and presentation.
|
|
15
16
|
|
|
16
|
-
In one typical local setup spanning 117 checkouts (94 distinct Git object databases, with linked worktrees counted once), git-dedup uses 11.1 GB for Git objects versus
|
|
17
|
+
In one typical local setup spanning 117 checkouts (94 distinct Git object databases, with linked worktrees counted once), git-dedup uses 11.1 GB for Git objects versus 35.5 GB without sharing, saving about 24.4 GB (70%). Checkout is also 6x faster for large repos, dropping from over 1 minute to 10 seconds.
|
|
17
18
|
|
|
18
19
|
**[Documentation](https://git-dedup.ben3d.ca/) · [Source](https://github.com/bhouston/git-dedup) · [CLI package](https://www.npmjs.com/package/git-dedup)**
|
|
19
20
|
|
|
@@ -31,8 +32,12 @@ npm install git-dedup-core
|
|
|
31
32
|
import { createGitDedup } from 'git-dedup-core';
|
|
32
33
|
|
|
33
34
|
const dedup = createGitDedup({ cwd: process.cwd() });
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
|
|
36
|
+
// check out a new repo automatically using the dedup store
|
|
37
|
+
await dedup.run(['clone', 'https://github.com/you/project.git']);
|
|
38
|
+
|
|
39
|
+
// dedup an existing repo into the store
|
|
40
|
+
await dedup.add('./my-existing-repo');
|
|
36
41
|
```
|
|
37
42
|
|
|
38
43
|
`run()` accepts Git arguments and returns an exit code. It optimizes supported remote clones, `submodule update --init`, and `worktree add` with submodules. Recursive updates handle nested submodules. `submodule add` adopts the module after Git creates it. Other commands and unsupported clone forms, including local paths, shallow or partial clones, and SHA-256 repositories, pass through to Git.
|
|
@@ -50,16 +55,17 @@ process.exitCode = exitCode;
|
|
|
50
55
|
|
|
51
56
|
The returned methods are asynchronous:
|
|
52
57
|
|
|
53
|
-
| Method | Result and behavior
|
|
54
|
-
| -------------- |
|
|
55
|
-
| `run(args)` | Git exit code; optimizes supported operations
|
|
56
|
-
| `
|
|
57
|
-
| `storePath()` | Resolved store path
|
|
58
|
-
| `storeInfo()` | `{ path, sizeBytes, remoteCount }`
|
|
59
|
-
| `fetch()` | `{ fetched }`; fetches registered remotes into the pool
|
|
60
|
-
| `gc()` | `{ compacted }`; compacts the pool without pruning objects
|
|
61
|
-
| `doctor()` | `{ checks }`; each check has `name`, `ok`, and `detail`
|
|
62
|
-
| `gitVersion()` | Underlying Git version line, such as `git version 2.50.1`
|
|
58
|
+
| Method | Result and behavior |
|
|
59
|
+
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
60
|
+
| `run(args)` | Git exit code; optimizes supported operations |
|
|
61
|
+
| `add(path?)` | `{ added, skipped, failed, repositories }`; adopts a repository and discoverable submodules, including local commits. Each repository reports its path, status, and any reason or full error detail. |
|
|
62
|
+
| `storePath()` | Resolved store path |
|
|
63
|
+
| `storeInfo()` | `{ path, sizeBytes, remoteCount }` |
|
|
64
|
+
| `fetch()` | `{ fetched }`; fetches registered remotes into the pool |
|
|
65
|
+
| `gc()` | `{ compacted }`; compacts the pool without pruning objects |
|
|
66
|
+
| `doctor()` | `{ checks }`; each check has `name`, `ok`, and `detail` |
|
|
67
|
+
| `gitVersion()` | Underlying Git version line, such as `git version 2.50.1` |
|
|
68
|
+
| `gitPath()` | Path of the underlying Git executable, honoring the `gitPath` option and `git-dedup.gitPath` |
|
|
63
69
|
|
|
64
70
|
### Consolidate an existing repository
|
|
65
71
|
|
|
@@ -67,8 +73,8 @@ The returned methods are asynchronous:
|
|
|
67
73
|
import { createGitDedup } from 'git-dedup-core';
|
|
68
74
|
|
|
69
75
|
const dedup = createGitDedup({ cwd: process.cwd() });
|
|
70
|
-
const {
|
|
71
|
-
console.log({
|
|
76
|
+
const { added, skipped, failed, repositories } = await dedup.add('./git-dedup-checkout');
|
|
77
|
+
console.log({ added, skipped, failed, repositories });
|
|
72
78
|
console.log(await dedup.storeInfo());
|
|
73
79
|
```
|
|
74
80
|
|
|
@@ -91,12 +97,10 @@ const dedup = createGitDedup({
|
|
|
91
97
|
},
|
|
92
98
|
});
|
|
93
99
|
|
|
94
|
-
await dedup.
|
|
100
|
+
await dedup.add('./git-dedup-checkout');
|
|
95
101
|
```
|
|
96
102
|
|
|
97
|
-
The callback enables metadata scans after optimized clones and checkout adoption. Without it, these scans are skipped. `StorageReport` also includes optional `beforeUniqueBytes` and `afterUniqueBytes` for checkout adoption. The package exports `GitDedupOptions`, `StorageReport`, `StoreInfo`, `
|
|
98
|
-
|
|
99
|
-
Adoption estimates count the reduction in private pack bytes. Counts cover `.pack`, `.idx`, and `.rev` files, excluding loose objects. They measure logical file sizes, not physical disk blocks reclaimed. Clone reports do not estimate savings.
|
|
103
|
+
The callback enables metadata scans after optimized clones and checkout adoption. Without it, these scans are skipped. `StorageReport` also includes optional `beforeUniqueBytes` and `afterUniqueBytes` for checkout adoption. The package exports `GitDedupOptions`, `StorageReport`, `StoreInfo`, `StoreAddResult`, `DoctorCheck`, and `DoctorResult` types. See [storage reports](https://git-dedup.ben3d.ca/docs/how-it-works#storage-reports) for what the estimates measure.
|
|
100
104
|
|
|
101
105
|
## Configuration
|
|
102
106
|
|
package/dist/index.d.ts
CHANGED
|
@@ -5,11 +5,11 @@ export interface GitDedupOptions {
|
|
|
5
5
|
onStorageReport?: (report: StorageReport) => void;
|
|
6
6
|
}
|
|
7
7
|
export interface StorageReport {
|
|
8
|
-
operation: 'clone' | '
|
|
8
|
+
operation: 'clone' | 'add';
|
|
9
9
|
repository: string;
|
|
10
10
|
poolReused: boolean;
|
|
11
11
|
estimatedSavedBytes: number;
|
|
12
|
-
/** Logical bytes in private pack files before/after
|
|
12
|
+
/** Logical bytes in private pack files before/after checkout adoption. Loose objects are excluded. */
|
|
13
13
|
beforeUniqueBytes?: number;
|
|
14
14
|
afterUniqueBytes?: number;
|
|
15
15
|
}
|
|
@@ -22,23 +22,55 @@ export interface StoreRemote {
|
|
|
22
22
|
key: string;
|
|
23
23
|
remote: string;
|
|
24
24
|
}
|
|
25
|
+
export interface PruneResult {
|
|
26
|
+
reclaimedBytes: number;
|
|
27
|
+
}
|
|
25
28
|
export interface DoctorCheck {
|
|
26
29
|
name: string;
|
|
27
30
|
ok: boolean;
|
|
28
31
|
detail: string;
|
|
29
32
|
}
|
|
30
33
|
export interface DoctorResult {
|
|
34
|
+
/** True when no object pool exists yet; the pool check is then omitted. */
|
|
35
|
+
empty: boolean;
|
|
31
36
|
checks: DoctorCheck[];
|
|
32
37
|
}
|
|
33
|
-
export interface
|
|
34
|
-
|
|
38
|
+
export interface StoreAddResult {
|
|
39
|
+
added: number;
|
|
40
|
+
skipped: number;
|
|
41
|
+
failed: number;
|
|
42
|
+
repositories: StoreAddRepositoryResult[];
|
|
43
|
+
}
|
|
44
|
+
export interface StoreAddRepositoryResult {
|
|
45
|
+
path: string;
|
|
46
|
+
status: 'added' | 'skipped' | 'failed';
|
|
47
|
+
reason?: string;
|
|
48
|
+
/** Full underlying error for diagnostic output. */
|
|
49
|
+
detail?: string;
|
|
50
|
+
}
|
|
51
|
+
export interface StoreRemoveResult {
|
|
52
|
+
removed: number;
|
|
35
53
|
skipped: number;
|
|
36
54
|
failed: number;
|
|
37
|
-
repositories:
|
|
55
|
+
repositories: StoreRemoveRepositoryResult[];
|
|
38
56
|
}
|
|
39
|
-
export interface
|
|
57
|
+
export interface StoreRemoveRepositoryResult {
|
|
40
58
|
path: string;
|
|
41
|
-
status: '
|
|
59
|
+
status: 'removed' | 'skipped' | 'failed';
|
|
60
|
+
reason?: string;
|
|
61
|
+
/** Full underlying error for diagnostic output. */
|
|
62
|
+
detail?: string;
|
|
63
|
+
/** Bytes in the checkout's own object directory after removal. */
|
|
64
|
+
objectBytes?: number;
|
|
65
|
+
}
|
|
66
|
+
export interface StoreFetchResult {
|
|
67
|
+
fetched: number;
|
|
68
|
+
failed: number;
|
|
69
|
+
remotes: StoreFetchRemoteResult[];
|
|
70
|
+
}
|
|
71
|
+
export interface StoreFetchRemoteResult {
|
|
72
|
+
key: string;
|
|
73
|
+
status: 'fetched' | 'failed';
|
|
42
74
|
reason?: string;
|
|
43
75
|
/** Full underlying error for diagnostic output. */
|
|
44
76
|
detail?: string;
|
|
@@ -46,18 +78,20 @@ export interface CacheRepositoryResult {
|
|
|
46
78
|
declare function keyForRemote(remote: string): string | undefined;
|
|
47
79
|
export declare function createGitDedup(options?: GitDedupOptions): {
|
|
48
80
|
run: (args: string[]) => Promise<number>;
|
|
49
|
-
|
|
81
|
+
add: (path?: string, quiet?: boolean) => Promise<StoreAddResult>;
|
|
82
|
+
remove: (path?: string) => Promise<StoreRemoveResult>;
|
|
50
83
|
storeInfo: () => Promise<StoreInfo>;
|
|
51
84
|
listRemotes: () => Promise<StoreRemote[]>;
|
|
52
|
-
fetch: () => Promise<
|
|
53
|
-
fetched: number;
|
|
54
|
-
}>;
|
|
85
|
+
fetch: () => Promise<StoreFetchResult>;
|
|
55
86
|
gc: () => Promise<{
|
|
56
87
|
compacted: boolean;
|
|
57
88
|
}>;
|
|
89
|
+
prune: () => Promise<PruneResult>;
|
|
90
|
+
forget: (path: string) => Promise<string[]>;
|
|
58
91
|
doctor: () => Promise<DoctorResult>;
|
|
59
92
|
storePath: () => Promise<string>;
|
|
60
93
|
gitVersion: () => Promise<string>;
|
|
94
|
+
gitPath: () => Promise<string>;
|
|
61
95
|
};
|
|
62
96
|
export { keyForRemote };
|
|
63
97
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;CACnD;AACD,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,OAAO,GAAG,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|