0
# Advanced Operations
1
2
Advanced Git operations including merging, stashing, and repository walking.
3
4
## Capabilities
5
6
### Merge Branches
7
8
Merges one or more branches into the current branch.
9
10
```javascript { .api }
11
/**
12
* Merge branches
13
* @param args.fs - File system client
14
* @param args.dir - Working tree directory path
15
* @param args.gitdir - Git directory path
16
* @param args.ours - Our branch (defaults to HEAD)
17
* @param args.theirs - Their branch to merge
18
* @param args.fastForward - Allow fast-forward merges
19
* @param args.noUpdateBranch - Don't update branch pointer
20
* @param args.dryRun - Simulate merge without changes
21
* @param args.abortOnConflict - Abort on merge conflicts
22
* @param args.message - Merge commit message
23
* @param args.author - Author for merge commit
24
* @param args.committer - Committer for merge commit
25
* @param args.signingKey - PGP signing key
26
* @param args.onSign - Signing callback
27
* @param args.cache - Cache object
28
* @returns Promise resolving to merge result
29
*/
30
function merge(args: {
31
fs: FsClient;
32
dir?: string;
33
gitdir?: string;
34
ours?: string;
35
theirs: string;
36
fastForward?: boolean;
37
noUpdateBranch?: boolean;
38
dryRun?: boolean;
39
abortOnConflict?: boolean;
40
message?: string;
41
author?: PersonObject;
42
committer?: PersonObject;
43
signingKey?: string;
44
onSign?: SignCallback;
45
cache?: object;
46
}): Promise<MergeResult>;
47
```
48
49
**Usage Examples:**
50
51
```javascript
52
import git from "isomorphic-git";
53
import fs from "fs";
54
55
// Basic merge
56
const mergeResult = await git.merge({
57
fs,
58
dir: "/path/to/repo",
59
theirs: "feature-branch"
60
});
61
62
if (mergeResult.alreadyMerged) {
63
console.log("Already up to date");
64
} else if (mergeResult.fastForward) {
65
console.log("Fast-forward merge completed");
66
} else {
67
console.log("Merge commit created:", mergeResult.oid);
68
}
69
70
// Merge with custom message
71
await git.merge({
72
fs,
73
dir: "/path/to/repo",
74
theirs: "feature-branch",
75
message: "Merge feature-branch into main\n\nAdds new functionality for user management"
76
});
77
78
// Dry run merge (test for conflicts)
79
const dryResult = await git.merge({
80
fs,
81
dir: "/path/to/repo",
82
theirs: "risky-branch",
83
dryRun: true
84
});
85
86
if (dryResult.conflicts && dryResult.conflicts.length > 0) {
87
console.log("Merge would have conflicts:", dryResult.conflicts);
88
} else {
89
console.log("Merge would succeed");
90
}
91
```
92
93
### Abort Merge
94
95
Aborts an in-progress merge operation.
96
97
```javascript { .api }
98
/**
99
* Abort an in-progress merge
100
* @param args.fs - File system client
101
* @param args.dir - Working tree directory path
102
* @param args.gitdir - Git directory path
103
* @returns Promise resolving when merge is aborted
104
*/
105
function abortMerge(args: {
106
fs: FsClient;
107
dir?: string;
108
gitdir?: string;
109
}): Promise<void>;
110
```
111
112
**Usage Example:**
113
114
```javascript
115
import git from "isomorphic-git";
116
import fs from "fs";
117
118
// Abort current merge
119
await git.abortMerge({
120
fs,
121
dir: "/path/to/repo"
122
});
123
console.log("Merge aborted - repository restored to pre-merge state");
124
```
125
126
### Walk Repository Tree
127
128
Walks through repository trees with custom logic.
129
130
```javascript { .api }
131
/**
132
* Walk repository trees
133
* @param args.fs - File system client
134
* @param args.dir - Working tree directory path
135
* @param args.gitdir - Git directory path
136
* @param args.trees - Array of tree walkers
137
* @param args.map - Map function for each file
138
* @param args.reduce - Reduce function for directories
139
* @param args.iterate - Iterate function for processing
140
* @param args.cache - Cache object
141
* @returns Promise resolving to walk result
142
*/
143
function walk(args: {
144
fs: FsClient;
145
dir?: string;
146
gitdir?: string;
147
trees: Walker[];
148
map?: (filepath: string, entries: WalkerEntry[]) => any;
149
reduce?: (parent: any, children: any[]) => any;
150
iterate?: (entries: WalkerEntry[], children: any[]) => any;
151
cache?: object;
152
}): Promise<any>;
153
```
154
155
**Usage Examples:**
156
157
```javascript
158
import git, { TREE, WORKDIR, STAGE } from "isomorphic-git";
159
import fs from "fs";
160
161
// Compare working directory with HEAD
162
const results = await git.walk({
163
fs,
164
dir: "/path/to/repo",
165
trees: [TREE({ ref: "HEAD" }), WORKDIR()],
166
map: async (filepath, [head, workdir]) => {
167
if (head && workdir) {
168
// File exists in both
169
if (head.oid !== (await workdir.oid())) {
170
return { filepath, status: "modified" };
171
}
172
} else if (head && !workdir) {
173
return { filepath, status: "deleted" };
174
} else if (!head && workdir) {
175
return { filepath, status: "added" };
176
}
177
return null;
178
}
179
});
180
181
const changes = results.filter(r => r !== null);
182
console.log("Changes detected:", changes);
183
184
// Compare two commits
185
const diff = await git.walk({
186
fs,
187
dir: "/path/to/repo",
188
trees: [TREE({ ref: "main" }), TREE({ ref: "feature-branch" })],
189
map: async (filepath, [commit1, commit2]) => {
190
if (commit1 && commit2) {
191
if (commit1.oid !== commit2.oid) {
192
return { filepath, type: "modified" };
193
}
194
} else if (commit1 && !commit2) {
195
return { filepath, type: "deleted" };
196
} else if (!commit1 && commit2) {
197
return { filepath, type: "added" };
198
}
199
return null;
200
}
201
});
202
203
console.log("Differences between branches:", diff.filter(d => d));
204
```
205
206
### Stash Changes
207
208
Stashes working directory changes.
209
210
```javascript { .api }
211
/**
212
* Stash working directory changes
213
* @param args.fs - File system client
214
* @param args.dir - Working tree directory path
215
* @param args.gitdir - Git directory path
216
* @param args.message - Stash message
217
* @param args.author - Author information
218
* @param args.cache - Cache object
219
* @returns Promise resolving to stash commit SHA
220
*/
221
function stash(args: {
222
fs: FsClient;
223
dir?: string;
224
gitdir?: string;
225
message?: string;
226
author?: PersonObject;
227
cache?: object;
228
}): Promise<string>;
229
```
230
231
**Usage Example:**
232
233
```javascript
234
import git from "isomorphic-git";
235
import fs from "fs";
236
237
// Stash current changes
238
const stashSha = await git.stash({
239
fs,
240
dir: "/path/to/repo",
241
message: "WIP: working on new feature",
242
author: {
243
name: "Developer",
244
email: "dev@example.com"
245
}
246
});
247
console.log("Created stash:", stashSha);
248
```
249
250
### Pack Objects
251
252
Creates a packfile containing Git objects.
253
254
```javascript { .api }
255
/**
256
* Pack Git objects into a packfile
257
* @param args.fs - File system client
258
* @param args.dir - Working tree directory path
259
* @param args.gitdir - Git directory path
260
* @param args.oids - Object IDs to pack
261
* @param args.write - Write packfile to disk
262
* @returns Promise resolving to packfile info
263
*/
264
function packObjects(args: {
265
fs: FsClient;
266
dir?: string;
267
gitdir?: string;
268
oids: string[];
269
write?: boolean;
270
}): Promise<PackObjectsResult>;
271
```
272
273
**Usage Example:**
274
275
```javascript
276
import git from "isomorphic-git";
277
import fs from "fs";
278
279
// Get commits to pack
280
const commits = await git.log({
281
fs,
282
dir: "/path/to/repo",
283
depth: 10
284
});
285
286
const oids = commits.map(commit => commit.oid);
287
288
// Create packfile
289
const packResult = await git.packObjects({
290
fs,
291
dir: "/path/to/repo",
292
oids,
293
write: true
294
});
295
console.log("Created packfile:", packResult.filename);
296
```
297
298
### Index Pack
299
300
Indexes a packfile for efficient access.
301
302
```javascript { .api }
303
/**
304
* Index a packfile
305
* @param args.fs - File system client
306
* @param args.dir - Working tree directory path
307
* @param args.gitdir - Git directory path
308
* @param args.filepath - Path to packfile
309
* @param args.cache - Cache object
310
* @returns Promise resolving when indexing completes
311
*/
312
function indexPack(args: {
313
fs: FsClient;
314
dir?: string;
315
gitdir?: string;
316
filepath: string;
317
cache?: object;
318
}): Promise<void>;
319
```
320
321
**Usage Example:**
322
323
```javascript
324
import git from "isomorphic-git";
325
import fs from "fs";
326
327
// Index a packfile
328
await git.indexPack({
329
fs,
330
dir: "/path/to/repo",
331
filepath: "/path/to/packfile.pack"
332
});
333
console.log("Packfile indexed successfully");
334
```
335
336
### Add Note
337
338
Adds a note to a Git object.
339
340
```javascript { .api }
341
/**
342
* Add a note to an object
343
* @param args.fs - File system client
344
* @param args.dir - Working tree directory path
345
* @param args.gitdir - Git directory path
346
* @param args.oid - Object ID to annotate
347
* @param args.note - Note content
348
* @param args.ref - Notes reference (defaults to 'refs/notes/commits')
349
* @param args.author - Author information
350
* @param args.committer - Committer information
351
* @param args.signingKey - PGP signing key
352
* @param args.force - Overwrite existing note
353
* @returns Promise resolving when note is added
354
*/
355
function addNote(args: {
356
fs: FsClient;
357
dir?: string;
358
gitdir?: string;
359
oid: string;
360
note: string;
361
ref?: string;
362
author?: PersonObject;
363
committer?: PersonObject;
364
signingKey?: string;
365
force?: boolean;
366
}): Promise<void>;
367
```
368
369
**Usage Example:**
370
371
```javascript
372
import git from "isomorphic-git";
373
import fs from "fs";
374
375
// Add note to a commit
376
await git.addNote({
377
fs,
378
dir: "/path/to/repo",
379
oid: "commit-sha-here",
380
note: "This commit fixes issue #123",
381
author: {
382
name: "Annotator",
383
email: "annotator@example.com"
384
}
385
});
386
```
387
388
### List Notes
389
390
Lists all notes in the repository.
391
392
```javascript { .api }
393
/**
394
* List notes
395
* @param args.fs - File system client
396
* @param args.dir - Working tree directory path
397
* @param args.gitdir - Git directory path
398
* @param args.ref - Notes reference (defaults to 'refs/notes/commits')
399
* @returns Promise resolving to array of note entries
400
*/
401
function listNotes(args: {
402
fs: FsClient;
403
dir?: string;
404
gitdir?: string;
405
ref?: string;
406
}): Promise<NoteEntry[]>;
407
```
408
409
**Usage Example:**
410
411
```javascript
412
import git from "isomorphic-git";
413
import fs from "fs";
414
415
const notes = await git.listNotes({
416
fs,
417
dir: "/path/to/repo"
418
});
419
420
for (const note of notes) {
421
console.log(`Note for ${note.target}: ${note.note}`);
422
}
423
```
424
425
### Read Note
426
427
Reads a note for a specific object.
428
429
```javascript { .api }
430
/**
431
* Read a note for an object
432
* @param args.fs - File system client
433
* @param args.dir - Working tree directory path
434
* @param args.gitdir - Git directory path
435
* @param args.oid - Object ID to read note for
436
* @param args.ref - Notes reference (defaults to 'refs/notes/commits')
437
* @returns Promise resolving to note content
438
*/
439
function readNote(args: {
440
fs: FsClient;
441
dir?: string;
442
gitdir?: string;
443
oid: string;
444
ref?: string;
445
}): Promise<string>;
446
```
447
448
**Usage Example:**
449
450
```javascript
451
import git from "isomorphic-git";
452
import fs from "fs";
453
454
try {
455
const note = await git.readNote({
456
fs,
457
dir: "/path/to/repo",
458
oid: "commit-sha-here"
459
});
460
console.log("Note:", note);
461
} catch (err) {
462
console.log("No note found for this commit");
463
}
464
```
465
466
### Remove Note
467
468
Removes a note from an object.
469
470
```javascript { .api }
471
/**
472
* Remove a note from an object
473
* @param args.fs - File system client
474
* @param args.dir - Working tree directory path
475
* @param args.gitdir - Git directory path
476
* @param args.oid - Object ID to remove note from
477
* @param args.ref - Notes reference (defaults to 'refs/notes/commits')
478
* @param args.author - Author information
479
* @param args.committer - Committer information
480
* @param args.signingKey - PGP signing key
481
* @returns Promise resolving when note is removed
482
*/
483
function removeNote(args: {
484
fs: FsClient;
485
dir?: string;
486
gitdir?: string;
487
oid: string;
488
ref?: string;
489
author?: PersonObject;
490
committer?: PersonObject;
491
signingKey?: string;
492
}): Promise<void>;
493
```
494
495
**Usage Example:**
496
497
```javascript
498
import git from "isomorphic-git";
499
import fs from "fs";
500
501
// Remove note from commit
502
await git.removeNote({
503
fs,
504
dir: "/path/to/repo",
505
oid: "commit-sha-here",
506
author: {
507
name: "Editor",
508
email: "editor@example.com"
509
}
510
});
511
```
512
513
## Types
514
515
```javascript { .api }
516
interface MergeResult {
517
oid?: string;
518
alreadyMerged?: boolean;
519
fastForward?: boolean;
520
mergeCommit?: boolean;
521
tree?: string;
522
conflicts?: string[];
523
}
524
525
interface WalkerEntry {
526
type: () => Promise<string>;
527
mode: () => Promise<string>;
528
oid: () => Promise<string>;
529
content: () => Promise<Uint8Array>;
530
stat: () => Promise<Stats>;
531
}
532
533
interface Walker {
534
(args: any): WalkerEntry;
535
}
536
537
interface PackObjectsResult {
538
filename: string;
539
packfile: Uint8Array;
540
}
541
542
interface NoteEntry {
543
target: string;
544
note: string;
545
}
546
547
// Walker constants
548
const STAGE: Walker; // Git index walker
549
const TREE: Walker; // Git tree walker
550
const WORKDIR: Walker; // Working directory walker
551
```
552
553
## Advanced Workflow Examples
554
555
### Conflict Resolution Workflow
556
557
```javascript
558
import git from "isomorphic-git";
559
import fs from "fs";
560
561
try {
562
// Attempt merge
563
const result = await git.merge({
564
fs,
565
dir: "/path/to/repo",
566
theirs: "feature-branch"
567
});
568
569
if (result.conflicts && result.conflicts.length > 0) {
570
console.log("Merge conflicts in:", result.conflicts);
571
572
// Manual conflict resolution would happen here
573
// After resolving conflicts, commit the merge:
574
575
await git.add({ fs, dir: "/path/to/repo", filepath: "conflicted-file.js" });
576
await git.commit({
577
fs,
578
dir: "/path/to/repo",
579
message: "Resolve merge conflicts",
580
author: { name: "Developer", email: "dev@example.com" }
581
});
582
}
583
} catch (error) {
584
// If merge fails, abort it
585
await git.abortMerge({ fs, dir: "/path/to/repo" });
586
console.log("Merge aborted due to error:", error.message);
587
}
588
```
589
590
### Repository Analysis
591
592
```javascript
593
import git, { TREE, WORKDIR } from "isomorphic-git";
594
import fs from "fs";
595
596
// Analyze repository changes
597
const analysis = await git.walk({
598
fs,
599
dir: "/path/to/repo",
600
trees: [TREE({ ref: "HEAD" }), WORKDIR()],
601
map: async (filepath, [head, workdir]) => {
602
if (!filepath.endsWith('.js')) return null;
603
604
if (head && workdir) {
605
const headContent = await head.content();
606
const workdirContent = await workdir.content();
607
608
if (!headContent.equals(workdirContent)) {
609
return {
610
filepath,
611
status: "modified",
612
headSize: headContent.length,
613
workdirSize: workdirContent.length
614
};
615
}
616
}
617
return null;
618
}
619
});
620
621
const jsChanges = analysis.filter(a => a !== null);
622
console.log("Modified JavaScript files:", jsChanges);
623
```