git-dedup-core 0.1.0 → 2.0.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 CHANGED
@@ -3,15 +3,16 @@
3
3
  [![npm version](https://img.shields.io/npm/v/git-dedup-core.svg)](https://www.npmjs.com/package/git-dedup-core)
4
4
  [![npm downloads](https://img.shields.io/npm/dm/git-dedup-core.svg)](https://www.npmjs.com/package/git-dedup-core)
5
5
  [![CI](https://github.com/bhouston/git-dedup/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/bhouston/git-dedup/actions/workflows/ci.yml)
6
+ [![Coverage](https://codecov.io/gh/bhouston/git-dedup/branch/main/graph/badge.svg)](https://codecov.io/gh/bhouston/git-dedup)
6
7
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/bhouston/git-dedup/blob/main/LICENSE)
7
- [![Documentation](https://img.shields.io/badge/docs-git-dedup-blue)](https://git-dedup.ben3d.ca/)
8
+ [![Documentation](https://img.shields.io/badge/docs-git--dedup-blue)](https://git-dedup.ben3d.ca/)
8
9
  [![Discord](https://img.shields.io/badge/Discord-Join-5865F2?logo=discord&logoColor=white)](https://discord.gg/5J5Ur3F6Z2)
9
10
 
10
- _The TypeScript storage engine behind [git-dedup](https://www.npmjs.com/package/git-dedup)._
11
+ **Many coding agents, one copy of Git history.** _The TypeScript storage engine behind [git-dedup](https://www.npmjs.com/package/git-dedup)._
11
12
 
12
- Build Node.js tools that share one Git object pool across checkouts. The core owns cloning, submodule and worktree integration, repository consolidation, and store maintenance. It invokes native Git; the CLI handles command parsing and presentation.
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
- Optimized for short-lived repositories in agentic workflows. **Automatically** reuse Git objects across repeated checkouts and worktrees with submodules. The pool holds objects from different remotes, including forks and unrelated repositories. Checkouts borrow from it through Git alternates.
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
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 an estimated 35.5 GB without sharing, saving about 24.4 GB (69%).
17
18
 
@@ -50,16 +51,17 @@ process.exitCode = exitCode;
50
51
 
51
52
  The returned methods are asynchronous:
52
53
 
53
- | Method | Result and behavior |
54
- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
55
- | `run(args)` | Git exit code; optimizes supported operations |
56
- | `cache(path?)` | `{ cached, 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. |
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` |
54
+ | Method | Result and behavior |
55
+ | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
56
+ | `run(args)` | Git exit code; optimizes supported operations |
57
+ | `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. |
58
+ | `storePath()` | Resolved store path |
59
+ | `storeInfo()` | `{ path, sizeBytes, remoteCount }` |
60
+ | `fetch()` | `{ fetched }`; fetches registered remotes into the pool |
61
+ | `gc()` | `{ compacted }`; compacts the pool without pruning objects |
62
+ | `doctor()` | `{ checks }`; each check has `name`, `ok`, and `detail` |
63
+ | `gitVersion()` | Underlying Git version line, such as `git version 2.50.1` |
64
+ | `gitPath()` | Path of the underlying Git executable, honoring the `gitPath` option and `git-dedup.gitPath` |
63
65
 
64
66
  ### Consolidate an existing repository
65
67
 
@@ -67,8 +69,8 @@ The returned methods are asynchronous:
67
69
  import { createGitDedup } from 'git-dedup-core';
68
70
 
69
71
  const dedup = createGitDedup({ cwd: process.cwd() });
70
- const { cached, skipped, failed, repositories } = await dedup.cache('./git-dedup-checkout');
71
- console.log({ cached, skipped, failed, repositories });
72
+ const { added, skipped, failed, repositories } = await dedup.add('./git-dedup-checkout');
73
+ console.log({ added, skipped, failed, repositories });
72
74
  console.log(await dedup.storeInfo());
73
75
  ```
74
76
 
@@ -91,12 +93,10 @@ const dedup = createGitDedup({
91
93
  },
92
94
  });
93
95
 
94
- await dedup.cache('./git-dedup-checkout');
96
+ await dedup.add('./git-dedup-checkout');
95
97
  ```
96
98
 
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`, `CacheResult`, `DoctorCheck`, and `DoctorResult` types.
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.
99
+ 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
100
 
101
101
  ## Configuration
102
102
 
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' | 'cache';
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 cache adoption. Loose objects are excluded. */
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 CacheResult {
34
- cached: number;
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: CacheRepositoryResult[];
55
+ repositories: StoreRemoveRepositoryResult[];
38
56
  }
39
- export interface CacheRepositoryResult {
57
+ export interface StoreRemoveRepositoryResult {
40
58
  path: string;
41
- status: 'cached' | 'skipped' | 'failed';
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
- cache: (path?: string) => Promise<CacheResult>;
81
+ add: (path?: string) => 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
@@ -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,OAAO,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mGAAmG;IACnG,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AACD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AACD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AACD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AACD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AACD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,qBAAqB,EAAE,CAAC;CACvC;AACD,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA6BD,iBAAS,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CA8BxD;AAiPD,wBAAgB,cAAc,CAAC,OAAO,GAAE,eAAoB;gBAskBjC,MAAM,EAAE,KAAG,OAAO,CAAC,MAAM,CAAC;8BAxQjB,OAAO,CAAC,WAAW,CAAC;qBAuI1B,OAAO,CAAC,SAAS,CAAC;uBAUhB,OAAO,CAAC,WAAW,EAAE,CAAC;iBA2B5B,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;cAkB/B,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC;kBAS3B,OAAO,CAAC,YAAY,CAAC;qBA/ZlB,OAAO,CAAC,MAAM,CAAC;sBA2fd,OAAO,CAAC,MAAM,CAAC;EAO7C;AAWD,OAAO,EAAE,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}