memory-git 1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 memory-git contributors
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,263 @@
1
+ # MemoryGit
2
+
3
+ In-memory Git implementation that minimizes IO operations. The project is loaded into memory, all git operations are executed in memory, and only at the end are changes synchronized (flushed) to disk.
4
+
5
+ ## Features
6
+
7
+ - **Zero IO during git operations**: All operations are done in memory
8
+ - **Non-blocking**: All real disk operations use `fs.promises` (async) to not block the event loop
9
+ - **Operation logging**: Records all operations performed with timestamps
10
+ - **Controlled flush**: Syncs to disk only when you decide
11
+ - **Complete API**: Supports main git operations (init, add, commit, branch, merge, etc.)
12
+ - **In-memory stash**: Stash support without touching disk
13
+ - **Usage metrics**: Operation statistics and memory usage
14
+ - **Parallel copying**: Files are copied in parallel during `loadFromDisk` and `flush` for better performance
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install memory-git
20
+ # or
21
+ pnpm add memory-git
22
+ # or
23
+ yarn add memory-git
24
+ ```
25
+
26
+ ## Basic Usage
27
+
28
+ ```javascript
29
+ const { MemoryGit } = require('memory-git');
30
+
31
+ async function example() {
32
+ const memGit = new MemoryGit('my-project');
33
+
34
+ // Set the author
35
+ memGit.setAuthor('Your Name', 'email@example.com');
36
+
37
+ // Initialize a new repository in memory
38
+ await memGit.init();
39
+
40
+ // Create files (in memory)
41
+ await memGit.writeFile('README.md', '# My Project');
42
+ await memGit.writeFile('src/index.js', 'console.log("Hello");');
43
+
44
+ // Git operations (all in memory)
45
+ await memGit.add('.');
46
+ await memGit.commit('Initial commit');
47
+
48
+ // Create branch and make changes
49
+ await memGit.createBranch('feature/new');
50
+ await memGit.checkout('feature/new');
51
+
52
+ // More changes...
53
+ await memGit.writeFile('src/feature.js', 'export class Feature {}');
54
+ await memGit.add('.');
55
+ await memGit.commit('Add feature');
56
+
57
+ // Merge
58
+ await memGit.checkout('main');
59
+ await memGit.merge('feature/new');
60
+
61
+ // ONLY NOW save to disk
62
+ await memGit.flush('./output-directory');
63
+ }
64
+ ```
65
+
66
+ ## Loading Existing Repository
67
+
68
+ ```javascript
69
+ const memGit = new MemoryGit('loading');
70
+ memGit.setAuthor('Name', 'email@example.com');
71
+
72
+ // Load from disk to memory
73
+ await memGit.loadFromDisk('./my-existing-repo', {
74
+ ignore: ['node_modules', '.pnpm-store', 'dist']
75
+ });
76
+
77
+ // Make changes in memory
78
+ await memGit.writeFile('CHANGELOG.md', '# Changelog\n\n- New version');
79
+ await memGit.add('.');
80
+ await memGit.commit('docs: add changelog');
81
+
82
+ // Save back to disk
83
+ await memGit.flush();
84
+ ```
85
+
86
+ ## API
87
+
88
+ ### Initialization
89
+
90
+ | Method | Description |
91
+ |--------|-------------|
92
+ | `new MemoryGit(name)` | Creates new instance |
93
+ | `setAuthor(name, email)` | Sets author for commits |
94
+ | `init()` | Initializes repository in memory |
95
+ | `loadFromDisk(path, options)` | Loads repository from disk |
96
+ | `clone(url, options)` | Clones remote repository |
97
+ | `clear()` | Clears memory and reinitializes |
98
+
99
+ ### File Operations
100
+
101
+ | Method | Description |
102
+ |--------|-------------|
103
+ | `writeFile(filepath, content)` | Writes file in memory |
104
+ | `readFile(filepath)` | Reads file from memory |
105
+ | `deleteFile(filepath)` | Removes file from memory |
106
+ | `fileExists(filepath)` | Checks if file exists |
107
+ | `listFiles(dir)` | Lists files in directory |
108
+
109
+ ### Git Operations
110
+
111
+ | Method | Description |
112
+ |--------|-------------|
113
+ | `add(filepath)` | Adds to staging |
114
+ | `remove(filepath)` | Removes from staging and working tree |
115
+ | `commit(message)` | Creates commit |
116
+ | `status()` | Gets status |
117
+ | `log(depth)` | Lists commits |
118
+ | `diff()` | Shows changes |
119
+
120
+ ### Branches
121
+
122
+ | Method | Description |
123
+ |--------|-------------|
124
+ | `createBranch(name)` | Creates branch |
125
+ | `deleteBranch(name)` | Deletes branch |
126
+ | `checkout(name)` | Switches to branch |
127
+ | `listBranches()` | Lists branches |
128
+ | `currentBranch()` | Gets current branch |
129
+ | `merge(branch)` | Performs merge |
130
+
131
+ ### Remotes
132
+
133
+ | Method | Description |
134
+ |--------|-------------|
135
+ | `addRemote(name, url)` | Adds remote |
136
+ | `deleteRemote(name)` | Removes remote |
137
+ | `listRemotes()` | Lists remotes |
138
+ | `fetch(remote)` | Performs fetch |
139
+ | `pull(remote, branch)` | Performs pull |
140
+
141
+ ### Stash
142
+
143
+ | Method | Description |
144
+ |--------|-------------|
145
+ | `stash()` | Saves changes to stash |
146
+ | `stashPop()` | Restores from stash |
147
+ | `stashList()` | Counts available stashes |
148
+
149
+ ### Synchronization
150
+
151
+ | Method | Description |
152
+ |--------|-------------|
153
+ | `flush(targetPath)` | Saves everything to disk |
154
+
155
+ ### Logs and Metrics
156
+
157
+ | Method | Description |
158
+ |--------|-------------|
159
+ | `getOperationsLog()` | Returns operation log |
160
+ | `clearOperationsLog()` | Clears log |
161
+ | `getOperationsStats()` | Operation statistics |
162
+ | `exportOperationsLog()` | Exports log as JSON |
163
+ | `getMemoryUsage()` | Estimated memory usage |
164
+ | `getRepoInfo()` | Repository information |
165
+
166
+ ## Operation Logging
167
+
168
+ All operations are automatically recorded:
169
+
170
+ ```javascript
171
+ const ops = memGit.getOperationsLog();
172
+ // [
173
+ // {
174
+ // timestamp: '2024-01-15T10:30:00.000Z',
175
+ // operation: 'commit',
176
+ // params: { message: 'feat: add feature' },
177
+ // success: true,
178
+ // result: { sha: 'abc123...' },
179
+ // error: null
180
+ // },
181
+ // ...
182
+ // ]
183
+
184
+ // Statistics
185
+ const stats = memGit.getOperationsStats();
186
+ // {
187
+ // total: 25,
188
+ // successful: 24,
189
+ // failed: 1,
190
+ // byOperation: {
191
+ // commit: { total: 5, successful: 5, failed: 0 },
192
+ // ...
193
+ // }
194
+ // }
195
+
196
+ // Export to file
197
+ const json = memGit.exportOperationsLog();
198
+ fs.writeFileSync('operations.json', json);
199
+ ```
200
+
201
+ ## Complete Example
202
+
203
+ Run the included example:
204
+
205
+ ```bash
206
+ pnpm run example
207
+ ```
208
+
209
+ ## Benchmark: Git CLI vs MemoryGit
210
+
211
+ Run the benchmark:
212
+
213
+ ```bash
214
+ pnpm run benchmark
215
+ ```
216
+
217
+ ### Summary Results
218
+
219
+ | Metric | Git CLI | MemoryGit | Difference |
220
+ |--------|---------|-----------|------------|
221
+ | Overhead per call | 3.63ms | 0.03ms | **~100x faster** |
222
+ | Log read (50x) | 232ms | 161ms | **1.4x faster** |
223
+ | Init | 15ms | 2ms | **7x faster** |
224
+ | Create branch | 3ms | 0.5ms | **6x faster** |
225
+ | Add (50 files) | 24ms | 53ms | 2.2x slower |
226
+ | Commit | 8ms | 4ms | **2x faster** |
227
+
228
+ ### Analysis
229
+
230
+ - **Git CLI** is faster in heavy individual operations (add, checkout) because it's written in highly optimized C
231
+ - **MemoryGit** eliminates process spawn overhead (~3.6ms per call) and disk IO
232
+ - For **repeated reads** (status, log, branches), MemoryGit is significantly faster
233
+ - The final **flush** adds ~60ms to sync with disk
234
+
235
+ ### When to use each
236
+
237
+ | Scenario | Recommendation |
238
+ |----------|----------------|
239
+ | Large repositories (> 500MB) | Git CLI |
240
+ | Automated tests | MemoryGit |
241
+ | Programmatic repo generation | MemoryGit |
242
+ | Single operations | Git CLI |
243
+ | Many reads (status, log) | MemoryGit |
244
+ | Low latency applications | MemoryGit |
245
+
246
+ ## Dependencies
247
+
248
+ - [isomorphic-git](https://isomorphic-git.org/) - Pure JavaScript Git implementation
249
+ - [memfs](https://github.com/streamich/memfs) - In-memory filesystem
250
+
251
+ ## TypeScript
252
+
253
+ The package includes complete TypeScript definitions:
254
+
255
+ ```typescript
256
+ import { MemoryGit, CommitInfo, FileStatus } from 'memory-git';
257
+
258
+ const memGit = new MemoryGit('my-project');
259
+ ```
260
+
261
+ ## License
262
+
263
+ MIT
@@ -0,0 +1,376 @@
1
+ import { fs as memfs, vol } from 'memfs';
2
+ export interface Author {
3
+ name: string;
4
+ email: string;
5
+ }
6
+ export interface OperationLogEntry {
7
+ timestamp: string;
8
+ operation: string;
9
+ params: Record<string, unknown>;
10
+ success: boolean;
11
+ result: unknown;
12
+ error: string | null;
13
+ }
14
+ export interface FileStatus {
15
+ filepath: string;
16
+ head: number;
17
+ workdir: number;
18
+ stage: number;
19
+ status: string;
20
+ }
21
+ export interface CommitInfo {
22
+ sha: string;
23
+ message: string;
24
+ author: string;
25
+ email: string;
26
+ timestamp: string;
27
+ }
28
+ export interface BranchInfo {
29
+ name: string;
30
+ current: boolean;
31
+ }
32
+ export interface RemoteInfo {
33
+ remote: string;
34
+ url: string;
35
+ }
36
+ export interface OperationStats {
37
+ total: number;
38
+ successful: number;
39
+ failed: number;
40
+ byOperation: Record<string, {
41
+ total: number;
42
+ successful: number;
43
+ failed: number;
44
+ }>;
45
+ }
46
+ export interface RepoInfo {
47
+ initialized: boolean;
48
+ memoryDir: string;
49
+ realDir: string | null;
50
+ currentBranch: string | null;
51
+ branches: BranchInfo[];
52
+ remotes: RemoteInfo[];
53
+ fileCount: number;
54
+ commits: number;
55
+ }
56
+ export interface MemoryUsage {
57
+ files: number;
58
+ estimatedSizeBytes: number;
59
+ estimatedSizeMB: string;
60
+ operationsLogged: number;
61
+ }
62
+ export interface LoadFromDiskOptions {
63
+ /** Patterns of files/folders to ignore */
64
+ ignore?: string[];
65
+ }
66
+ export interface FlushOptions {
67
+ /** Remove files that don't exist in memory (default: false) */
68
+ clean?: boolean;
69
+ }
70
+ export interface CloneOptions {
71
+ /** Shallow clone depth */
72
+ depth?: number;
73
+ /** Clone only a single branch */
74
+ singleBranch?: boolean;
75
+ [key: string]: unknown;
76
+ }
77
+ export interface MergeResult {
78
+ oid?: string;
79
+ alreadyMerged?: boolean;
80
+ fastForward?: boolean;
81
+ }
82
+ export interface DiffEntry {
83
+ filepath: string;
84
+ status: string;
85
+ }
86
+ /**
87
+ * MemoryGit - In-memory Git implementation
88
+ *
89
+ * Loads the project into memory, executes all git operations in memory,
90
+ * and syncs to disk only when flush() is called.
91
+ *
92
+ * All real disk operations use async versions to not block the Node.js event loop.
93
+ */
94
+ export declare class MemoryGit {
95
+ /** Instance name */
96
+ readonly name: string;
97
+ /** Memory filesystem */
98
+ readonly fs: typeof memfs;
99
+ /** Volume instance */
100
+ readonly vol: typeof vol;
101
+ /** In-memory repository directory */
102
+ readonly dir: string;
103
+ /** Real disk directory (if loaded from disk) */
104
+ realDir: string | null;
105
+ /** Whether the repository is initialized */
106
+ isInitialized: boolean;
107
+ /** Author information for commits */
108
+ author: Author;
109
+ private operations;
110
+ private _stash;
111
+ /**
112
+ * Creates a new MemoryGit instance
113
+ * @param name - Unique name to identify the instance
114
+ */
115
+ constructor(name?: string);
116
+ /**
117
+ * Logs an operation
118
+ * @private
119
+ */
120
+ private _logOperation;
121
+ /**
122
+ * Removes large data from params for logging
123
+ * @private
124
+ */
125
+ private _sanitizeParams;
126
+ /**
127
+ * Checks if a path exists on real disk (async)
128
+ * @private
129
+ */
130
+ private _realPathExists;
131
+ /**
132
+ * Sets the author for commits
133
+ * @param name - Author name
134
+ * @param email - Author email
135
+ */
136
+ setAuthor(name: string, email: string): void;
137
+ /**
138
+ * Initializes a new repository in memory
139
+ */
140
+ init(): Promise<boolean>;
141
+ /**
142
+ * Loads an existing repository from disk to memory
143
+ * @param sourcePath - Path to the repository on disk
144
+ * @param options - Loading options
145
+ * @returns Number of files loaded
146
+ */
147
+ loadFromDisk(sourcePath: string, options?: LoadFromDiskOptions): Promise<number>;
148
+ /**
149
+ * Copies files from real disk to memory filesystem (async)
150
+ * @private
151
+ */
152
+ private _copyToMemoryAsync;
153
+ /**
154
+ * Counts files in a directory in memory
155
+ * @private
156
+ */
157
+ private _countFiles;
158
+ /**
159
+ * Writes a file to the in-memory repository
160
+ * @param filepath - Relative file path
161
+ * @param content - File content
162
+ */
163
+ writeFile(filepath: string, content: string | Buffer): Promise<boolean>;
164
+ /**
165
+ * Reads a file from the in-memory repository
166
+ * @param filepath - Relative file path
167
+ * @returns File content
168
+ */
169
+ readFile(filepath: string): Promise<string>;
170
+ /**
171
+ * Checks if a file exists
172
+ * @param filepath - Relative file path
173
+ */
174
+ fileExists(filepath: string): Promise<boolean>;
175
+ /**
176
+ * Deletes a file from the in-memory repository
177
+ * @param filepath - Relative file path
178
+ */
179
+ deleteFile(filepath: string): Promise<boolean>;
180
+ /**
181
+ * Adds file(s) to the staging area
182
+ * @param filepath - Relative file path(s)
183
+ */
184
+ add(filepath: string | string[]): Promise<boolean>;
185
+ /**
186
+ * Removes file(s) from the staging area and working tree
187
+ * @param filepath - Relative file path
188
+ */
189
+ remove(filepath: string): Promise<boolean>;
190
+ /**
191
+ * Creates a commit with staged changes
192
+ * @param message - Commit message
193
+ * @returns SHA of the created commit
194
+ */
195
+ commit(message: string): Promise<string>;
196
+ /**
197
+ * Gets repository status
198
+ * @returns List of files with their status
199
+ */
200
+ status(): Promise<FileStatus[]>;
201
+ /**
202
+ * Converts numeric status to readable text
203
+ * @private
204
+ */
205
+ private _getStatusText;
206
+ /**
207
+ * Gets commit log
208
+ * @param depth - Number of commits to return
209
+ * @returns List of commits
210
+ */
211
+ log(depth?: number): Promise<CommitInfo[]>;
212
+ /**
213
+ * Creates a new branch
214
+ * @param branchName - Branch name
215
+ */
216
+ createBranch(branchName: string): Promise<boolean>;
217
+ /**
218
+ * Deletes a branch
219
+ * @param branchName - Branch name
220
+ */
221
+ deleteBranch(branchName: string): Promise<boolean>;
222
+ /**
223
+ * Switches to a branch
224
+ * @param branchName - Branch name
225
+ */
226
+ checkout(branchName: string): Promise<boolean>;
227
+ /**
228
+ * Lists all branches
229
+ * @returns List of branches
230
+ */
231
+ listBranches(): Promise<BranchInfo[]>;
232
+ /**
233
+ * Gets the current branch
234
+ * @returns Current branch name
235
+ */
236
+ currentBranch(): Promise<string | undefined>;
237
+ /**
238
+ * Merges a branch into the current branch
239
+ * @param theirBranch - Branch name to merge
240
+ */
241
+ merge(theirBranch: string): Promise<MergeResult>;
242
+ /**
243
+ * Adds a remote
244
+ * @param remoteName - Remote name
245
+ * @param url - Remote URL
246
+ */
247
+ addRemote(remoteName: string, url: string): Promise<boolean>;
248
+ /**
249
+ * Removes a remote
250
+ * @param remoteName - Remote name
251
+ */
252
+ deleteRemote(remoteName: string): Promise<boolean>;
253
+ /**
254
+ * Lists configured remotes
255
+ * @returns List of remotes
256
+ */
257
+ listRemotes(): Promise<RemoteInfo[]>;
258
+ /**
259
+ * Creates a tag
260
+ * @param tagName - Tag name
261
+ * @param ref - Reference (commit SHA or branch)
262
+ */
263
+ createTag(tagName: string, ref?: string): Promise<boolean>;
264
+ /**
265
+ * Lists all tags
266
+ * @returns List of tags
267
+ */
268
+ listTags(): Promise<string[]>;
269
+ /**
270
+ * Returns the history of all operations performed
271
+ * @returns List of operations
272
+ */
273
+ getOperationsLog(): OperationLogEntry[];
274
+ /**
275
+ * Clears the operation log
276
+ */
277
+ clearOperationsLog(): void;
278
+ /**
279
+ * Gets operation statistics
280
+ * @returns Statistics
281
+ */
282
+ getOperationsStats(): OperationStats;
283
+ /**
284
+ * Exports the operation log in JSON format
285
+ * @returns JSON string of operations
286
+ */
287
+ exportOperationsLog(): string;
288
+ /**
289
+ * Syncs all changes from memory to disk
290
+ * @param targetPath - Destination path (optional, uses original path if not specified)
291
+ * @param options - Flush options
292
+ * @returns Number of files flushed
293
+ */
294
+ flush(targetPath?: string | null, options?: FlushOptions): Promise<number>;
295
+ /**
296
+ * Copies files from memory to disk (async)
297
+ * @private
298
+ */
299
+ private _copyToDiskAsync;
300
+ /**
301
+ * Lists files in the in-memory repository
302
+ * @param dir - Relative directory (optional)
303
+ * @param includeGit - Include .git folder in listing
304
+ * @returns List of files
305
+ */
306
+ listFiles(dir?: string, includeGit?: boolean): Promise<string[]>;
307
+ /**
308
+ * Lists files recursively
309
+ * @private
310
+ */
311
+ private _listFilesRecursive;
312
+ /**
313
+ * Gets the diff between working tree and HEAD
314
+ * @returns List of modified files
315
+ */
316
+ diff(): Promise<DiffEntry[]>;
317
+ /**
318
+ * Gets file content at a specific commit
319
+ * @param filepath - File path
320
+ * @param ref - Reference (commit SHA, branch, tag)
321
+ * @returns File content
322
+ */
323
+ readFileAtRef(filepath: string, ref?: string): Promise<string>;
324
+ /**
325
+ * Resets file changes
326
+ * @param filepath - File path
327
+ */
328
+ resetFile(filepath: string): Promise<boolean>;
329
+ /**
330
+ * Stashes current changes (simulates by saving in memory)
331
+ * @returns Number of files saved to stash
332
+ */
333
+ stash(): Promise<number>;
334
+ /**
335
+ * Restores from stash
336
+ * @returns Number of files restored
337
+ */
338
+ stashPop(): Promise<number>;
339
+ /**
340
+ * Lists available stashes
341
+ * @returns Number of stashes
342
+ */
343
+ stashList(): number;
344
+ /**
345
+ * Clones a remote repository to memory
346
+ * @param url - Repository URL
347
+ * @param options - Clone options
348
+ */
349
+ clone(url: string, options?: CloneOptions): Promise<boolean>;
350
+ /**
351
+ * Fetches from a remote
352
+ * @param remote - Remote name (default: 'origin')
353
+ */
354
+ fetch(remote?: string): Promise<boolean>;
355
+ /**
356
+ * Pulls from a remote
357
+ * @param remote - Remote name (default: 'origin')
358
+ * @param branch - Branch name
359
+ */
360
+ pull(remote?: string, branch?: string | null): Promise<boolean>;
361
+ /**
362
+ * Clears the in-memory filesystem and reinitializes
363
+ */
364
+ clear(): Promise<boolean>;
365
+ /**
366
+ * Gets repository information
367
+ * @returns Repository information
368
+ */
369
+ getRepoInfo(): Promise<RepoInfo>;
370
+ /**
371
+ * Gets estimated memory usage
372
+ * @returns Memory usage information
373
+ */
374
+ getMemoryUsage(): MemoryUsage;
375
+ }
376
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}