git-dedup 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/LICENSE +21 -0
- package/README.md +140 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +9 -0
- package/dist/bin.js.map +1 -0
- package/dist/commands/cache.d.ts +22 -0
- package/dist/commands/cache.d.ts.map +1 -0
- package/dist/commands/cache.js +94 -0
- package/dist/commands/cache.js.map +1 -0
- package/dist/commands/docgen.d.ts +14 -0
- package/dist/commands/docgen.d.ts.map +1 -0
- package/dist/commands/docgen.js +16 -0
- package/dist/commands/docgen.js.map +1 -0
- package/dist/commands/doctor.d.ts +4 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +12 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/store/$default.d.ts +3 -0
- package/dist/commands/store/$default.d.ts.map +1 -0
- package/dist/commands/store/$default.js +7 -0
- package/dist/commands/store/$default.js.map +1 -0
- package/dist/commands/store/fetch.d.ts +4 -0
- package/dist/commands/store/fetch.d.ts.map +1 -0
- package/dist/commands/store/fetch.js +8 -0
- package/dist/commands/store/fetch.js.map +1 -0
- package/dist/commands/store/gc.d.ts +4 -0
- package/dist/commands/store/gc.d.ts.map +1 -0
- package/dist/commands/store/gc.js +8 -0
- package/dist/commands/store/gc.js.map +1 -0
- package/dist/commands/store/list.d.ts +4 -0
- package/dist/commands/store/list.d.ts.map +1 -0
- package/dist/commands/store/list.js +14 -0
- package/dist/commands/store/list.js.map +1 -0
- package/dist/context.d.ts +17 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +3 -0
- package/dist/context.js.map +1 -0
- package/dist/discover.d.ts +10 -0
- package/dist/discover.d.ts.map +1 -0
- package/dist/discover.js +71 -0
- package/dist/discover.js.map +1 -0
- package/dist/document.d.ts +6 -0
- package/dist/document.d.ts.map +1 -0
- package/dist/document.js +36 -0
- package/dist/document.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +54 -0
- package/dist/index.js.map +1 -0
- package/dist/stats.d.ts +4 -0
- package/dist/stats.d.ts.map +1 -0
- package/dist/stats.js +37 -0
- package/dist/stats.js.map +1 -0
- package/package.json +63 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ben Houston
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# git-dedup CLI
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/git-dedup)
|
|
4
|
+
[](https://www.npmjs.com/package/git-dedup)
|
|
5
|
+
[](https://github.com/bhouston/git-dedup/actions/workflows/ci.yml)
|
|
6
|
+
[](https://github.com/bhouston/git-dedup/blob/main/LICENSE)
|
|
7
|
+
[](https://git-dedup.ben3d.ca/)
|
|
8
|
+
[](https://discord.gg/5J5Ur3F6Z2)
|
|
9
|
+
|
|
10
|
+
git-dedup keeps Git objects from many remotes in one local object pool. Supported clones and linked repositories use Git alternates to borrow those objects, reducing duplicate storage across checkouts and forks. git-dedup is not a disposable cache: linked checkouts depend on the store.
|
|
11
|
+
|
|
12
|
+
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%).
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
# Populate the shared object pool in ~/.git-dedup.
|
|
16
|
+
git-dedup clone https://github.com/you/project.git project
|
|
17
|
+
|
|
18
|
+
# Another checkout borrows objects from the same pool.
|
|
19
|
+
git-dedup clone https://github.com/you/project.git project-review
|
|
20
|
+
cd project-review
|
|
21
|
+
|
|
22
|
+
# All normal Git commands work in the checkout.
|
|
23
|
+
git status
|
|
24
|
+
git diff
|
|
25
|
+
git log --oneline
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Repeated clones can borrow objects already in the pool, reducing download and storage work.
|
|
29
|
+
|
|
30
|
+
**[Documentation](https://git-dedup.ben3d.ca/) · [Source](https://github.com/bhouston/git-dedup) · [Agent setup](https://git-dedup.ben3d.ca/docs/agents)**
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
Requires **Node.js 22+ and Git** on macOS or Linux.
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
npm install --global git-dedup
|
|
38
|
+
git-dedup --help
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
If you previously installed `@bhouston/gitx`, install `git-dedup` and update scripts or editor settings that call `gitx`. Existing gitx stores and linked checkouts continue to work; the new CLI reuses an existing store automatically.
|
|
42
|
+
|
|
43
|
+
## Usage
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
# Repeated clones borrow from the shared pool.
|
|
47
|
+
git-dedup clone https://github.com/bhouston/git-dedup.git git-dedup-main
|
|
48
|
+
git-dedup --stats clone https://github.com/bhouston/git-dedup.git git-dedup-review
|
|
49
|
+
|
|
50
|
+
# Adopt an existing repository and its discoverable submodules.
|
|
51
|
+
git-dedup cache ./git-dedup-main --stats
|
|
52
|
+
|
|
53
|
+
# Preview, then adopt every checkout in a workspace directory.
|
|
54
|
+
git-dedup cache ~/Coding --all --dry-run
|
|
55
|
+
git-dedup cache ~/Coding --all
|
|
56
|
+
|
|
57
|
+
# Ordinary Git commands also work through git-dedup.
|
|
58
|
+
git-dedup -C git-dedup-main status
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Submodules and worktrees
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
git-dedup clone --recurse-submodules https://github.com/you/project.git
|
|
65
|
+
cd project
|
|
66
|
+
git-dedup submodule update --init --recursive
|
|
67
|
+
git-dedup worktree add -b review ../project-review
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Supported updates prepare missing submodule repositories from the pool, including nested modules with `--recursive`. `git-dedup submodule add` adds the module to the store after Git creates it. `git-dedup worktree add` uses Git's common object database and initializes supported submodules in the new worktree; `--no-checkout` defers initialization.
|
|
71
|
+
|
|
72
|
+
Other Git commands and unsupported clone forms pass through to Git. Local path clones, shallow or partial clones, and SHA-256 repositories use ordinary Git behavior.
|
|
73
|
+
|
|
74
|
+
`cache --all` scans checkout directories below the given path without following symlinks. It skips Git metadata and common dependency/build directories (`node_modules`, `vendor`, `dist`, `build`, `target`, `.next`, `.nuxt`, `.turbo`, `.venv`, and `coverage`). It does not initialize absent submodules. Linked worktrees sharing one Git object database are processed once. Each checkout's outcome appears separately, and a failed checkout does not stop the remaining targets.
|
|
75
|
+
|
|
76
|
+
### Store commands
|
|
77
|
+
|
|
78
|
+
| Command | Purpose |
|
|
79
|
+
| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
80
|
+
| `git-dedup cache [path]` | Adopt or relink a repository and its submodules; report skipped and failed paths (`--verbose` shows full Git errors) |
|
|
81
|
+
| `git-dedup cache <directory> --all` | Discover and adopt checkouts below a directory; use `--dry-run` to preview |
|
|
82
|
+
| `git-dedup store` | Show store path, remote count, and size |
|
|
83
|
+
| `git-dedup store fetch` | Fetch registered remotes into the pool |
|
|
84
|
+
| `git-dedup store gc` | Compact the pool without pruning consumer objects |
|
|
85
|
+
| `git-dedup doctor` | Inspect the pool and Git setup |
|
|
86
|
+
|
|
87
|
+
### Optional storage reports
|
|
88
|
+
|
|
89
|
+
```sh
|
|
90
|
+
git-dedup --stats clone https://github.com/bhouston/git-dedup.git git-dedup-extra
|
|
91
|
+
git-dedup cache ./git-dedup-extra --stats
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Reports go to stderr and show whether the pool already existed. Adoption reports compare private pack bytes before and after adoption. Clone reports identify use of Git alternates; they do not estimate disk savings.
|
|
95
|
+
|
|
96
|
+
Measurement is opt-in and scans local `.pack`, `.idx`, and `.rev` file metadata, without traversing Git objects. It excludes loose objects. These are logical file-size estimates, not measured disk blocks reclaimed. The first use populates the pool and can increase total disk use. Plain Git fallback does not print a report.
|
|
97
|
+
|
|
98
|
+
## Configuration
|
|
99
|
+
|
|
100
|
+
The default store is `~/.git-dedup`. Override it with `GIT_DEDUP_STORE`:
|
|
101
|
+
|
|
102
|
+
```sh
|
|
103
|
+
export GIT_DEDUP_STORE="$HOME/my-git-dedup-store"
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Changing `GIT_DEDUP_STORE` selects a different store; it does not move the existing one. git-dedup does not change global Git configuration.
|
|
107
|
+
|
|
108
|
+
| Setting | Purpose |
|
|
109
|
+
| ------------------- | ----------------------------------------- |
|
|
110
|
+
| `GIT_DEDUP_STORE` | Override the store path for an invocation |
|
|
111
|
+
| `git-dedup.gitPath` | Select the Git executable |
|
|
112
|
+
|
|
113
|
+
## Store dependency
|
|
114
|
+
|
|
115
|
+
Linked checkouts depend on the object pool through Git alternates. Deleting or moving the store can make their history unreadable. The pool can be on a different filesystem.
|
|
116
|
+
|
|
117
|
+
Read the [storage model](https://git-dedup.ben3d.ca/docs/how-it-works) and [store dependency guide](https://git-dedup.ben3d.ca/docs/safety) for details.
|
|
118
|
+
|
|
119
|
+
## Command documentation and agents
|
|
120
|
+
|
|
121
|
+
Run `git-dedup --help` or a store command's `--help` flag for options. `git-dedup docgen` writes [clidoc](https://github.com/bhouston/clidoc) documentation:
|
|
122
|
+
|
|
123
|
+
```sh
|
|
124
|
+
git-dedup docgen --format json --output git-dedup.json
|
|
125
|
+
git-dedup docgen --format markdown --output git-dedup-commands.md
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The [agent setup guide](https://git-dedup.ben3d.ca/docs/agents) has copyable instructions for `AGENTS.md` and `CLAUDE.md` after a global installation.
|
|
129
|
+
|
|
130
|
+
## Contributing
|
|
131
|
+
|
|
132
|
+
See [CONTRIBUTING.md](https://github.com/bhouston/git-dedup/blob/main/CONTRIBUTING.md) for the issue, branch, and PR workflow, and [GitHub Releases](https://github.com/bhouston/git-dedup/releases) for release notes.
|
|
133
|
+
|
|
134
|
+
## License
|
|
135
|
+
|
|
136
|
+
[MIT](https://github.com/bhouston/git-dedup/blob/main/LICENSE)
|
|
137
|
+
|
|
138
|
+
## Author
|
|
139
|
+
|
|
140
|
+
[Ben Houston](https://ben3d.ca)
|
package/dist/bin.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":""}
|
package/dist/bin.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { main } from './index.js';
|
|
3
|
+
main().then((code) => {
|
|
4
|
+
process.exitCode = code;
|
|
5
|
+
}, (error) => {
|
|
6
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
7
|
+
process.exitCode = 1;
|
|
8
|
+
});
|
|
9
|
+
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,IAAI,EAAE,CAAC,IAAI,CACT,CAAC,IAAI,EAAE,EAAE;IACP,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;AAC1B,CAAC,EACD,CAAC,KAAc,EAAE,EAAE;IACjB,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACtE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CACF,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ArgumentsCamelCase, Argv } from 'yargs';
|
|
2
|
+
export declare const command = "cache [path]";
|
|
3
|
+
export declare const describe = "Adopt or relink a repository to the shared store";
|
|
4
|
+
export declare const builder: (parser: Argv) => Argv<{
|
|
5
|
+
path: string | undefined;
|
|
6
|
+
} & {
|
|
7
|
+
stats: boolean;
|
|
8
|
+
} & {
|
|
9
|
+
all: boolean;
|
|
10
|
+
} & {
|
|
11
|
+
"dry-run": boolean;
|
|
12
|
+
} & {
|
|
13
|
+
verbose: boolean;
|
|
14
|
+
}>;
|
|
15
|
+
export declare const handler: (args: ArgumentsCamelCase<{
|
|
16
|
+
path?: string;
|
|
17
|
+
stats: boolean;
|
|
18
|
+
all: boolean;
|
|
19
|
+
dryRun: boolean;
|
|
20
|
+
verbose: boolean;
|
|
21
|
+
}>) => Promise<void>;
|
|
22
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/commands/cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAMtD,eAAO,MAAM,OAAO,iBAAiB,CAAC;AACtC,eAAO,MAAM,QAAQ,qDAAqD,CAAC;AAC3E,eAAO,MAAM,OAAO,WAAY,IAAI;;;;;;;;;;EAyB9B,CAAC;AAWP,eAAO,MAAM,OAAO,SACZ,kBAAkB,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,kBA+C7G,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { dedup } from '../context.js';
|
|
2
|
+
import { printStorageReports } from '../stats.js';
|
|
3
|
+
import { discoverCheckouts } from '../discover.js';
|
|
4
|
+
export const command = 'cache [path]';
|
|
5
|
+
export const describe = 'Adopt or relink a repository to the shared store';
|
|
6
|
+
export const builder = (parser) => parser
|
|
7
|
+
.positional('path', {
|
|
8
|
+
type: 'string',
|
|
9
|
+
describe: 'Repository path (defaults to the current directory)',
|
|
10
|
+
})
|
|
11
|
+
.option('stats', {
|
|
12
|
+
type: 'boolean',
|
|
13
|
+
default: false,
|
|
14
|
+
describe: 'Show the change in private pack storage',
|
|
15
|
+
})
|
|
16
|
+
.option('all', {
|
|
17
|
+
type: 'boolean',
|
|
18
|
+
default: false,
|
|
19
|
+
describe: 'Discover and cache all checkouts under the directory',
|
|
20
|
+
})
|
|
21
|
+
.option('dry-run', {
|
|
22
|
+
type: 'boolean',
|
|
23
|
+
default: false,
|
|
24
|
+
describe: 'Preview checkouts discovered by --all without caching',
|
|
25
|
+
})
|
|
26
|
+
.option('verbose', {
|
|
27
|
+
type: 'boolean',
|
|
28
|
+
default: false,
|
|
29
|
+
describe: 'Show full Git errors for skipped and failed repositories',
|
|
30
|
+
});
|
|
31
|
+
function reportRepositories(result, verbose) {
|
|
32
|
+
for (const repository of result.repositories) {
|
|
33
|
+
if (!repository.reason)
|
|
34
|
+
continue;
|
|
35
|
+
const label = repository.status === 'cached' ? 'Warning' : repository.status === 'failed' ? 'Failed' : 'Skipped';
|
|
36
|
+
console.error(`${label} ${repository.path}: ${repository.reason}`);
|
|
37
|
+
if (verbose && repository.detail)
|
|
38
|
+
console.error(repository.detail);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export const handler = async (args) => {
|
|
42
|
+
if (args.dryRun && !args.all)
|
|
43
|
+
throw new Error('--dry-run requires --all');
|
|
44
|
+
const reports = [];
|
|
45
|
+
const client = dedup(args.stats ? { onStorageReport: (report) => reports.push(report) } : undefined);
|
|
46
|
+
if (args.all) {
|
|
47
|
+
const targets = await discoverCheckouts(args.path ?? process.cwd());
|
|
48
|
+
console.log(`Discovered ${targets.length} checkout(s):`);
|
|
49
|
+
for (const target of targets)
|
|
50
|
+
console.log(` ${target.path}${target.coveredBy ? ` (submodule of ${target.coveredBy})` : ''}`);
|
|
51
|
+
if (args.dryRun)
|
|
52
|
+
return;
|
|
53
|
+
const completed = new Set();
|
|
54
|
+
let cached = 0;
|
|
55
|
+
let skipped = 0;
|
|
56
|
+
let failed = 0;
|
|
57
|
+
for (const target of targets) {
|
|
58
|
+
if (target.coveredBy && completed.has(target.coveredBy)) {
|
|
59
|
+
console.log(`Skipped ${target.path}: handled with ${target.coveredBy}`);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
const result = await client.cache(target.path);
|
|
64
|
+
cached += result.cached;
|
|
65
|
+
skipped += result.skipped;
|
|
66
|
+
failed += result.failed;
|
|
67
|
+
reportRepositories(result, args.verbose);
|
|
68
|
+
completed.add(target.path);
|
|
69
|
+
console.log(`Finished ${target.path}: cached ${result.cached}, skipped ${result.skipped}, failed ${result.failed}`);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
failed++;
|
|
73
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
74
|
+
console.error(`Failed ${target.path}: cache operation failed`);
|
|
75
|
+
if (args.verbose)
|
|
76
|
+
console.error(detail);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
console.log(`Cached ${cached} repository(s); skipped ${skipped}; failed ${failed}.`);
|
|
80
|
+
if (args.stats)
|
|
81
|
+
printStorageReports(reports);
|
|
82
|
+
if (failed)
|
|
83
|
+
process.exitCode = 1;
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const result = await client.cache(args.path);
|
|
87
|
+
reportRepositories(result, args.verbose);
|
|
88
|
+
console.log(`Cached ${result.cached} repository(s); skipped ${result.skipped}; failed ${result.failed}.`);
|
|
89
|
+
if (args.stats)
|
|
90
|
+
printStorageReports(reports);
|
|
91
|
+
if (result.failed)
|
|
92
|
+
process.exitCode = 1;
|
|
93
|
+
};
|
|
94
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/commands/cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DocumentFormat } from '@clidoc/core';
|
|
2
|
+
import type { ArgumentsCamelCase, Argv } from 'yargs';
|
|
3
|
+
export declare const command = "docgen";
|
|
4
|
+
export declare const describe = "Write the OpenCLI document to a file, or stdout if --output is omitted";
|
|
5
|
+
export declare const builder: (parser: Argv) => Argv<{
|
|
6
|
+
output: string | undefined;
|
|
7
|
+
} & {
|
|
8
|
+
format: string;
|
|
9
|
+
}>;
|
|
10
|
+
export declare const handler: (args: ArgumentsCamelCase<{
|
|
11
|
+
output?: string;
|
|
12
|
+
format: DocumentFormat;
|
|
13
|
+
}>) => Promise<void>;
|
|
14
|
+
//# sourceMappingURL=docgen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docgen.d.ts","sourceRoot":"","sources":["../../src/commands/docgen.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAGtD,eAAO,MAAM,OAAO,WAAW,CAAC;AAChC,eAAO,MAAM,QAAQ,2EAA2E,CAAC;AACjG,eAAO,MAAM,OAAO,WAAY,IAAI;;;;EAQ9B,CAAC;AACP,eAAO,MAAM,OAAO,SAAgB,kBAAkB,CAAC;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,cAAc,CAAA;CAAE,CAAC,kBAElG,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { writeOpenCliDocument } from '@clidoc/core';
|
|
2
|
+
import { cliDocument } from '../document.js';
|
|
3
|
+
export const command = 'docgen';
|
|
4
|
+
export const describe = 'Write the OpenCLI document to a file, or stdout if --output is omitted';
|
|
5
|
+
export const builder = (parser) => parser
|
|
6
|
+
.option('output', { type: 'string', alias: 'o', describe: 'Output file; defaults to stdout' })
|
|
7
|
+
.option('format', {
|
|
8
|
+
type: 'string',
|
|
9
|
+
choices: ['json', 'yaml', 'markdown'],
|
|
10
|
+
default: 'json',
|
|
11
|
+
describe: 'Output format',
|
|
12
|
+
});
|
|
13
|
+
export const handler = async (args) => {
|
|
14
|
+
await writeOpenCliDocument(await cliDocument(), args.output, args.format);
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=docgen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docgen.js","sourceRoot":"","sources":["../../src/commands/docgen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGpD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAC;AAChC,MAAM,CAAC,MAAM,QAAQ,GAAG,wEAAwE,CAAC;AACjG,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,MAAY,EAAE,EAAE,CACtC,MAAM;KACH,MAAM,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,iCAAiC,EAAE,CAAC;KAC7F,MAAM,CAAC,QAAQ,EAAE;IAChB,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAU;IAC9C,OAAO,EAAE,MAAM;IACf,QAAQ,EAAE,eAAe;CAC1B,CAAC,CAAC;AACP,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,EAAE,IAAqE,EAAE,EAAE;IACrG,MAAM,oBAAoB,CAAC,MAAM,WAAW,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;AAC5E,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,WAAW,CAAC;AAChC,eAAO,MAAM,QAAQ,6CAA6C,CAAC;AACnE,eAAO,MAAM,OAAO,qBAMnB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { dedup } from '../context.js';
|
|
2
|
+
export const command = 'doctor';
|
|
3
|
+
export const describe = 'Check Git and shared store configuration';
|
|
4
|
+
export const handler = async () => {
|
|
5
|
+
const result = await dedup().doctor();
|
|
6
|
+
for (const check of result.checks) {
|
|
7
|
+
console.log(`${check.ok ? 'OK' : 'WARN'} ${check.name}: ${check.detail}`);
|
|
8
|
+
}
|
|
9
|
+
if (result.checks.some((check) => !check.ok))
|
|
10
|
+
process.exitCode = 1;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEtC,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAC;AAChC,MAAM,CAAC,MAAM,QAAQ,GAAG,0CAA0C,CAAC;AACnE,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;IAChC,MAAM,MAAM,GAAG,MAAM,KAAK,EAAE,CAAC,MAAM,EAAE,CAAC;IACtC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5E,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QAAE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACrE,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"$default.d.ts","sourceRoot":"","sources":["../../../src/commands/store/$default.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,QAAQ,0BAA0B,CAAC;AAChD,eAAO,MAAM,OAAO,qBAGnB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { dedup } from '../../context.js';
|
|
2
|
+
export const describe = 'Show the shared store';
|
|
3
|
+
export const handler = async () => {
|
|
4
|
+
const info = await dedup().storeInfo();
|
|
5
|
+
console.log(`${info.path}\nRemotes: ${info.remoteCount}\nSize: ${info.sizeBytes} bytes`);
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=$default.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"$default.js","sourceRoot":"","sources":["../../../src/commands/store/$default.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEzC,MAAM,CAAC,MAAM,QAAQ,GAAG,uBAAuB,CAAC;AAChD,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;IAChC,MAAM,IAAI,GAAG,MAAM,KAAK,EAAE,CAAC,SAAS,EAAE,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,cAAc,IAAI,CAAC,WAAW,WAAW,IAAI,CAAC,SAAS,QAAQ,CAAC,CAAC;AAC3F,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../../src/commands/store/fetch.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,UAAU,CAAC;AAC/B,eAAO,MAAM,QAAQ,yDAAyD,CAAC;AAC/E,eAAO,MAAM,OAAO,qBAGnB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { dedup } from '../../context.js';
|
|
2
|
+
export const command = 'fetch';
|
|
3
|
+
export const describe = 'Fetch registered remotes into the shared object pool';
|
|
4
|
+
export const handler = async () => {
|
|
5
|
+
const result = await dedup().fetch();
|
|
6
|
+
console.log(`Fetched ${result.fetched} remote(s).`);
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../../src/commands/store/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEzC,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAC/B,MAAM,CAAC,MAAM,QAAQ,GAAG,sDAAsD,CAAC;AAC/E,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;IAChC,MAAM,MAAM,GAAG,MAAM,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gc.d.ts","sourceRoot":"","sources":["../../../src/commands/store/gc.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,OAAO,CAAC;AAC5B,eAAO,MAAM,QAAQ,oEAAoE,CAAC;AAC1F,eAAO,MAAM,OAAO,qBAGnB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { dedup } from '../../context.js';
|
|
2
|
+
export const command = 'gc';
|
|
3
|
+
export const describe = 'Compact the shared object pool without pruning consumer objects';
|
|
4
|
+
export const handler = async () => {
|
|
5
|
+
const result = await dedup().gc();
|
|
6
|
+
console.log(result.compacted ? 'Compacted the shared object pool.' : 'The shared object pool is empty.');
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=gc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gc.js","sourceRoot":"","sources":["../../../src/commands/store/gc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEzC,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,CAAC;AAC5B,MAAM,CAAC,MAAM,QAAQ,GAAG,iEAAiE,CAAC;AAC1F,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;IAChC,MAAM,MAAM,GAAG,MAAM,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,kCAAkC,CAAC,CAAC;AAC3G,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/store/list.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,SAAS,CAAC;AAC9B,eAAO,MAAM,QAAQ,gDAAgD,CAAC;AACtE,eAAO,MAAM,OAAO,qBAQnB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { dedup } from '../../context.js';
|
|
2
|
+
export const command = 'list';
|
|
3
|
+
export const describe = 'List remotes registered in the shared store';
|
|
4
|
+
export const handler = async () => {
|
|
5
|
+
const remotes = await dedup().listRemotes();
|
|
6
|
+
if (!remotes.length) {
|
|
7
|
+
console.log('No remotes registered.');
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
console.log('KEY\tFETCH URL');
|
|
11
|
+
for (const { key, remote } of remotes)
|
|
12
|
+
console.log(`${key}\t${remote}`);
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/store/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEzC,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC;AAC9B,MAAM,CAAC,MAAM,QAAQ,GAAG,6CAA6C,CAAC;AACtE,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;IAChC,MAAM,OAAO,GAAG,MAAM,KAAK,EAAE,CAAC,WAAW,EAAE,CAAC;IAC5C,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;QACtC,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC9B,KAAK,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,OAAO;QAAE,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,KAAK,MAAM,EAAE,CAAC,CAAC;AAC1E,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { GitDedupOptions } from 'git-dedup-core';
|
|
2
|
+
export declare const dedup: (options?: GitDedupOptions) => {
|
|
3
|
+
run: (args: string[]) => Promise<number>;
|
|
4
|
+
cache: (path?: string) => Promise<import("git-dedup-core").CacheResult>;
|
|
5
|
+
storeInfo: () => Promise<import("git-dedup-core").StoreInfo>;
|
|
6
|
+
listRemotes: () => Promise<import("git-dedup-core").StoreRemote[]>;
|
|
7
|
+
fetch: () => Promise<{
|
|
8
|
+
fetched: number;
|
|
9
|
+
}>;
|
|
10
|
+
gc: () => Promise<{
|
|
11
|
+
compacted: boolean;
|
|
12
|
+
}>;
|
|
13
|
+
doctor: () => Promise<import("git-dedup-core").DoctorResult>;
|
|
14
|
+
storePath: () => Promise<string>;
|
|
15
|
+
gitVersion: () => Promise<string>;
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,eAAO,MAAM,KAAK,aAAc,eAAe;;;;;;;;;;;;;;CAA4B,CAAC"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGhD,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,OAAyB,EAAE,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface DiscoveredCheckout {
|
|
2
|
+
path: string;
|
|
3
|
+
gitDir: string;
|
|
4
|
+
commonGitDir: string;
|
|
5
|
+
/** The parent repository whose cache operation visits this initialized submodule. */
|
|
6
|
+
coveredBy?: string;
|
|
7
|
+
}
|
|
8
|
+
/** Discover checkout roots without following symlinks or entering Git/object/build directories. */
|
|
9
|
+
export declare function discoverCheckouts(directory: string): Promise<DiscoveredCheckout[]>;
|
|
10
|
+
//# sourceMappingURL=discover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../src/discover.ts"],"names":[],"mappings":"AAsBA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,qFAAqF;IACrF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,mGAAmG;AACnG,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CA2CxF"}
|
package/dist/discover.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { readdir, realpath, stat } from 'node:fs/promises';
|
|
3
|
+
import { promisify } from 'node:util';
|
|
4
|
+
import { isAbsolute, join, resolve, sep } from 'node:path';
|
|
5
|
+
const execFileAsync = promisify(execFile);
|
|
6
|
+
const ignored = new Set([
|
|
7
|
+
'.git',
|
|
8
|
+
'.hg',
|
|
9
|
+
'.svn',
|
|
10
|
+
'.next',
|
|
11
|
+
'.nuxt',
|
|
12
|
+
'.turbo',
|
|
13
|
+
'.venv',
|
|
14
|
+
'build',
|
|
15
|
+
'coverage',
|
|
16
|
+
'dist',
|
|
17
|
+
'node_modules',
|
|
18
|
+
'target',
|
|
19
|
+
'vendor',
|
|
20
|
+
]);
|
|
21
|
+
/** Discover checkout roots without following symlinks or entering Git/object/build directories. */
|
|
22
|
+
export async function discoverCheckouts(directory) {
|
|
23
|
+
const root = resolve(directory);
|
|
24
|
+
if (!(await stat(root)).isDirectory())
|
|
25
|
+
throw new Error(`Not a directory: ${root}`);
|
|
26
|
+
const candidates = [];
|
|
27
|
+
const pending = [root];
|
|
28
|
+
while (pending.length) {
|
|
29
|
+
const current = pending.pop();
|
|
30
|
+
const entries = await readdir(current, { withFileTypes: true });
|
|
31
|
+
if (entries.some((entry) => entry.name === '.git' && (entry.isFile() || entry.isDirectory())))
|
|
32
|
+
candidates.push(current);
|
|
33
|
+
for (const entry of entries) {
|
|
34
|
+
if (entry.isDirectory() && !ignored.has(entry.name))
|
|
35
|
+
pending.push(join(current, entry.name));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const unique = new Map();
|
|
39
|
+
for (const path of candidates.toSorted((a, b) => a.length - b.length || a.localeCompare(b))) {
|
|
40
|
+
try {
|
|
41
|
+
const { stdout } = await execFileAsync('git', [
|
|
42
|
+
'-C',
|
|
43
|
+
path,
|
|
44
|
+
'rev-parse',
|
|
45
|
+
'--absolute-git-dir',
|
|
46
|
+
'--path-format=absolute',
|
|
47
|
+
'--git-common-dir',
|
|
48
|
+
]);
|
|
49
|
+
const [rawGitDir, rawCommonDir] = stdout.trim().split('\n');
|
|
50
|
+
if (!rawGitDir || !rawCommonDir)
|
|
51
|
+
continue;
|
|
52
|
+
const gitDir = await realpath(isAbsolute(rawGitDir) ? rawGitDir : resolve(path, rawGitDir));
|
|
53
|
+
const commonGitDir = await realpath(isAbsolute(rawCommonDir) ? rawCommonDir : resolve(path, rawCommonDir));
|
|
54
|
+
if (!unique.has(commonGitDir))
|
|
55
|
+
unique.set(commonGitDir, { path, gitDir, commonGitDir });
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// A .git entry alone is not enough to identify a valid checkout.
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const found = [...unique.values()].toSorted((a, b) => a.path.localeCompare(b.path));
|
|
62
|
+
for (const child of found) {
|
|
63
|
+
const parent = found
|
|
64
|
+
.filter((candidate) => candidate !== child && child.path.startsWith(candidate.path + sep))
|
|
65
|
+
.find((candidate) => child.gitDir.startsWith(join(candidate.gitDir, 'modules') + sep));
|
|
66
|
+
if (parent)
|
|
67
|
+
child.coveredBy = parent.path;
|
|
68
|
+
}
|
|
69
|
+
return found;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=discover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discover.js","sourceRoot":"","sources":["../src/discover.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { OpenCliDocument } from '@clidoc/core';
|
|
2
|
+
import type { CommandModule } from 'yargs';
|
|
3
|
+
export declare function loadCommands(): Promise<CommandModule[]>;
|
|
4
|
+
export declare function documentFromCommands(commands: CommandModule[]): Promise<OpenCliDocument>;
|
|
5
|
+
export declare function cliDocument(): Promise<OpenCliDocument>;
|
|
6
|
+
//# sourceMappingURL=document.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../src/document.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAK3C,wBAAsB,YAAY,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAE7D;AAED,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAwB9F;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,eAAe,CAAC,CAE5D"}
|
package/dist/document.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { infoFromPackageJson } from '@clidoc/core';
|
|
5
|
+
import { fromYargsAsync } from '@clidoc/yargs';
|
|
6
|
+
import { fileCommands } from 'yargs-file-commands';
|
|
7
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
export async function loadCommands() {
|
|
9
|
+
return fileCommands({ commandDirs: [join(here, 'commands')] });
|
|
10
|
+
}
|
|
11
|
+
export async function documentFromCommands(commands) {
|
|
12
|
+
const packageInfo = JSON.parse(readFileSync(join(here, '../package.json'), 'utf8'));
|
|
13
|
+
const document = await fromYargsAsync(commands, infoFromPackageJson(packageInfo, { title: 'git-dedup', binary: 'git-dedup' }));
|
|
14
|
+
document.global = {
|
|
15
|
+
flags: [
|
|
16
|
+
{
|
|
17
|
+
name: 'stats',
|
|
18
|
+
type: 'boolean',
|
|
19
|
+
summary: 'Show object pool use and checkout adoption measurements',
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
};
|
|
23
|
+
document.commands ??= {};
|
|
24
|
+
document.commands['git-dedup clone'] = {
|
|
25
|
+
summary: 'Clone a repository through the shared store when supported',
|
|
26
|
+
args: [
|
|
27
|
+
{ name: 'repository', required: true },
|
|
28
|
+
{ name: 'directory', required: false },
|
|
29
|
+
],
|
|
30
|
+
};
|
|
31
|
+
return document;
|
|
32
|
+
}
|
|
33
|
+
export async function cliDocument() {
|
|
34
|
+
return documentFromCommands(await loadCommands());
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=document.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document.js","sourceRoot":"","sources":["../src/document.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAErD,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,OAAO,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,QAAyB;IAClE,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC,CAA4B,CAAC;IAC/G,MAAM,QAAQ,GAAG,MAAM,cAAc,CACnC,QAAQ,EACR,mBAAmB,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAC9E,CAAC;IACF,QAAQ,CAAC,MAAM,GAAG;QAChB,KAAK,EAAE;YACL;gBACE,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,yDAAyD;aACnE;SACF;KACF,CAAC;IACF,QAAQ,CAAC,QAAQ,KAAK,EAAE,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,iBAAiB,CAAC,GAAG;QACrC,OAAO,EAAE,4DAA4D;QACrE,IAAI,EAAE;YACJ,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE;YACtC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE;SACvC;KACF,CAAC;IACF,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,OAAO,oBAAoB,CAAC,MAAM,YAAY,EAAE,CAAC,CAAC;AACpD,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,oFAAoF;AACpF,wBAAsB,IAAI,CAAC,IAAI,WAAwB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiDxE"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { createGitDedup } from 'git-dedup-core';
|
|
5
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const packageInfo = JSON.parse(readFileSync(join(here, '../package.json'), 'utf8'));
|
|
7
|
+
const ownCommands = new Set(['cache', 'store', 'doctor', 'docgen']);
|
|
8
|
+
/** Run the git-dedup CLI. All Git commands retain their original argument array. */
|
|
9
|
+
export async function main(args = process.argv.slice(2)) {
|
|
10
|
+
const stats = args[0] === '--stats';
|
|
11
|
+
const forwardedArgs = stats ? args.slice(1) : args;
|
|
12
|
+
const first = forwardedArgs[0];
|
|
13
|
+
const runGit = async () => {
|
|
14
|
+
if (!stats)
|
|
15
|
+
return createGitDedup().run(args);
|
|
16
|
+
const reports = [];
|
|
17
|
+
const code = await createGitDedup({ onStorageReport: (report) => reports.push(report) }).run(forwardedArgs);
|
|
18
|
+
const { printStorageReports } = await import('./stats.js');
|
|
19
|
+
printStorageReports(reports);
|
|
20
|
+
return code;
|
|
21
|
+
};
|
|
22
|
+
if (first &&
|
|
23
|
+
!ownCommands.has(first) &&
|
|
24
|
+
first !== '--help' &&
|
|
25
|
+
first !== '-h' &&
|
|
26
|
+
first !== '--version' &&
|
|
27
|
+
first !== '-v') {
|
|
28
|
+
return runGit();
|
|
29
|
+
}
|
|
30
|
+
// Editors such as VS Code parse this as Git's version, so lead with Git's line.
|
|
31
|
+
if (args.length === 1 && (first === '--version' || first === '-v')) {
|
|
32
|
+
console.log(`${await createGitDedup().gitVersion()} (git-dedup ${packageInfo.version})`);
|
|
33
|
+
return 0;
|
|
34
|
+
}
|
|
35
|
+
// Loaded lazily: these dominate startup and forwarded Git commands never need them.
|
|
36
|
+
const [{ default: yargs }, { loadCommands }] = await Promise.all([import('yargs'), import('./document.js')]);
|
|
37
|
+
const parser = yargs(args)
|
|
38
|
+
.scriptName('git-dedup')
|
|
39
|
+
.usage('$0 <command> [options]\n\nGit commands pass through to Git; clone, submodule, and worktree can use the shared store.')
|
|
40
|
+
.version(packageInfo.version)
|
|
41
|
+
.help()
|
|
42
|
+
.option('stats', { type: 'boolean', describe: 'Show object pool use and checkout adoption measurements' })
|
|
43
|
+
.strict()
|
|
44
|
+
.showHelpOnFail(true);
|
|
45
|
+
const commands = await loadCommands();
|
|
46
|
+
parser.command(commands);
|
|
47
|
+
if (args.length === 0) {
|
|
48
|
+
parser.showHelp();
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
await parser.parseAsync();
|
|
52
|
+
return Number(process.exitCode ?? 0);
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/stats.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../src/stats.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAcpD,iFAAiF;AACjF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,IAAI,CAwBlE"}
|
package/dist/stats.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
function bytes(value) {
|
|
2
|
+
if (value < 1024)
|
|
3
|
+
return `${value} B`;
|
|
4
|
+
const units = ['KiB', 'MiB', 'GiB', 'TiB'];
|
|
5
|
+
let scaled = value;
|
|
6
|
+
let unit = -1;
|
|
7
|
+
do {
|
|
8
|
+
scaled /= 1024;
|
|
9
|
+
unit++;
|
|
10
|
+
} while (scaled >= 1024 && unit < units.length - 1);
|
|
11
|
+
return `${scaled.toFixed(1)} ${units[unit]}`;
|
|
12
|
+
}
|
|
13
|
+
/** Report logical pack bytes; no filesystem allocation estimate is available. */
|
|
14
|
+
export function printStorageReports(reports) {
|
|
15
|
+
for (const report of reports) {
|
|
16
|
+
const prefix = `git-dedup: ${report.operation} ${report.repository}: ${report.poolReused ? 'reused' : 'created'} object pool; `;
|
|
17
|
+
if (report.operation === 'cache') {
|
|
18
|
+
process.stderr.write(prefix +
|
|
19
|
+
`private packs ${bytes(report.beforeUniqueBytes ?? 0)} -> ${bytes(report.afterUniqueBytes ?? 0)}; ` +
|
|
20
|
+
`estimated private pack reduction ${bytes(report.estimatedSavedBytes)}\n`);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
process.stderr.write(prefix + 'objects borrowed through Git alternates\n');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (reports.length) {
|
|
27
|
+
const total = reports.reduce((sum, report) => sum + report.estimatedSavedBytes, 0);
|
|
28
|
+
if (reports[0]?.operation === 'cache') {
|
|
29
|
+
process.stderr.write(`git-dedup: estimated private pack reduction ${bytes(total)} (${total.toLocaleString('en-US')} bytes); ` +
|
|
30
|
+
'logical pack bytes only; actual disk reclaimed may differ.\n');
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
process.stderr.write('git-dedup: clone storage depends on objects already present in the shared pool.\n');
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=stats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.js","sourceRoot":"","sources":["../src/stats.ts"],"names":[],"mappings":"AAEA,SAAS,KAAK,CAAC,KAAa;IAC1B,IAAI,KAAK,GAAG,IAAI;QAAE,OAAO,GAAG,KAAK,IAAI,CAAC;IACtC,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC3C,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC;IACd,GAAG,CAAC;QACF,MAAM,IAAI,IAAI,CAAC;QACf,IAAI,EAAE,CAAC;IACT,CAAC,QAAQ,MAAM,IAAI,IAAI,IAAI,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;IACpD,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;AAC/C,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,mBAAmB,CAAC,OAAwB;IAC1D,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,cAAc,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,UAAU,KAAK,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,gBAAgB,CAAC;QAChI,IAAI,MAAM,CAAC,SAAS,KAAK,OAAO,EAAE,CAAC;YACjC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,MAAM;gBACJ,iBAAiB,KAAK,CAAC,MAAM,CAAC,iBAAiB,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,MAAM,CAAC,gBAAgB,IAAI,CAAC,CAAC,IAAI;gBACnG,oCAAoC,KAAK,CAAC,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAC5E,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,2CAA2C,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC;QACnF,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,KAAK,OAAO,EAAE,CAAC;YACtC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,+CAA+C,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,WAAW;gBACtG,8DAA8D,CACjE,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mFAAmF,CAAC,CAAC;QAC5G,CAAC;IACH,CAAC;AACH,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "git-dedup",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A Git wrapper that shares repository object storage",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"cli",
|
|
7
|
+
"clone",
|
|
8
|
+
"coding-agents",
|
|
9
|
+
"git",
|
|
10
|
+
"git-wrapper",
|
|
11
|
+
"object-pool",
|
|
12
|
+
"shared-storage",
|
|
13
|
+
"submodule",
|
|
14
|
+
"vscode",
|
|
15
|
+
"worktree"
|
|
16
|
+
],
|
|
17
|
+
"homepage": "https://git-dedup.ben3d.ca",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/bhouston/git-dedup.git",
|
|
22
|
+
"directory": "packages/cli"
|
|
23
|
+
},
|
|
24
|
+
"bin": {
|
|
25
|
+
"git-dedup": "./dist/bin.js"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"README.md",
|
|
30
|
+
"LICENSE"
|
|
31
|
+
],
|
|
32
|
+
"type": "module",
|
|
33
|
+
"exports": {
|
|
34
|
+
".": {
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
|
+
"default": "./dist/index.js"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@clidoc/core": "^0.1.0",
|
|
44
|
+
"@clidoc/yargs": "^1.1.0",
|
|
45
|
+
"yargs": "^18.0.0",
|
|
46
|
+
"yargs-file-commands": "^2.1.0",
|
|
47
|
+
"git-dedup-core": "0.1.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/node": "^24.0.0",
|
|
51
|
+
"@types/yargs": "^17.0.35",
|
|
52
|
+
"vitest-command-line": "^0.9.1"
|
|
53
|
+
},
|
|
54
|
+
"engines": {
|
|
55
|
+
"node": ">=22"
|
|
56
|
+
},
|
|
57
|
+
"scripts": {
|
|
58
|
+
"build": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc -p tsconfig.json && chmod +x dist/bin.js",
|
|
59
|
+
"test": "vitest run",
|
|
60
|
+
"tsc": "tsc --noEmit -p tsconfig.json",
|
|
61
|
+
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
62
|
+
}
|
|
63
|
+
}
|