0
# Advanced Operations
1
2
Complex Git workflows including merging, rebasing, stashing, and cherry-picking. These operations enable sophisticated repository management and collaborative workflows.
3
4
## Capabilities
5
6
### Merge Operations
7
8
Combine changes from different branches or commits.
9
10
```javascript { .api }
11
/**
12
* Find merge base between commits
13
* @param {Repository} repo - Repository instance
14
* @param {Oid} one - First commit OID
15
* @param {Oid} two - Second commit OID
16
* @returns {Promise<Oid>} Merge base OID
17
*/
18
Merge.base(repo, one, two): Promise<Oid>;
19
20
/**
21
* Find merge base of many commits
22
* @param {Repository} repo - Repository instance
23
* @param {Oid[]} oids - Array of commit OIDs
24
* @returns {Promise<Oid>} Merge base OID
25
*/
26
Merge.baseMany(repo, oids): Promise<Oid>;
27
28
/**
29
* Find octopus merge base
30
* @param {Repository} repo - Repository instance
31
* @param {Oid[]} oids - Array of commit OIDs
32
* @returns {Promise<Oid>} Octopus merge base OID
33
*/
34
Merge.baseOctopus(repo, oids): Promise<Oid>;
35
36
/**
37
* Merge commits
38
* @param {Repository} repo - Repository instance
39
* @param {Commit} ourCommit - Our commit
40
* @param {Commit} theirCommit - Their commit
41
* @param {MergeOptions} opts - Merge options
42
* @returns {Promise<Index>} Merged index
43
*/
44
Merge.commits(repo, ourCommit, theirCommit, opts): Promise<Index>;
45
46
/**
47
* Merge trees
48
* @param {Repository} repo - Repository instance
49
* @param {Tree} ancestorTree - Common ancestor tree
50
* @param {Tree} ourTree - Our tree
51
* @param {Tree} theirTree - Their tree
52
* @param {MergeOptions} opts - Merge options
53
* @returns {Promise<Index>} Merged index
54
*/
55
Merge.trees(repo, ancestorTree, ourTree, theirTree, opts): Promise<Index>;
56
```
57
58
**Usage Examples:**
59
60
```javascript
61
const NodeGit = require('nodegit');
62
63
const repo = await NodeGit.Repository.open('./my-repo');
64
65
// Find merge base
66
const mainCommit = await repo.getBranchCommit('main');
67
const featureCommit = await repo.getBranchCommit('feature');
68
69
const mergeBase = await NodeGit.Merge.base(
70
repo,
71
mainCommit.id(),
72
featureCommit.id()
73
);
74
75
console.log('Merge base:', mergeBase.tostrS());
76
77
// Merge commits
78
const mergeOptions = {
79
fileFavor: NodeGit.Merge.FILE_FAVOR.NORMAL,
80
fileFlags: NodeGit.Merge.FILE_FLAGS.DEFAULT
81
};
82
83
const mergedIndex = await NodeGit.Merge.commits(
84
repo,
85
mainCommit,
86
featureCommit,
87
mergeOptions
88
);
89
90
if (mergedIndex.hasConflicts()) {
91
console.log('Merge has conflicts - manual resolution required');
92
} else {
93
console.log('Merge completed successfully');
94
95
// Create merge commit
96
const treeOid = await mergedIndex.writeTreeTo(repo);
97
const tree = await NodeGit.Tree.lookup(repo, treeOid);
98
99
const signature = NodeGit.Signature.now('Merger', 'merge@example.com');
100
101
const commitOid = await NodeGit.Commit.create(
102
repo,
103
'HEAD',
104
signature,
105
signature,
106
null,
107
'Merge feature branch into main',
108
tree,
109
2,
110
[mainCommit, featureCommit]
111
);
112
113
console.log('Merge commit created:', commitOid.tostrS());
114
}
115
```
116
117
### Repository Merge Methods
118
119
High-level merge operations on Repository.
120
121
```javascript { .api }
122
/**
123
* Merge branches
124
* @param {string|Reference} to - Target branch
125
* @param {string|Reference} from - Source branch
126
* @param {Signature} signature - Merge signature
127
* @param {MergeOptions} mergeOpts - Merge options
128
* @param {CheckoutOptions} checkoutOpts - Checkout options
129
* @returns {Promise<Oid>} Merge commit OID
130
*/
131
repository.mergeBranches(to, from, signature, mergeOpts, checkoutOpts): Promise<Oid>;
132
```
133
134
**Usage Examples:**
135
136
```javascript
137
// High-level branch merge
138
const signature = NodeGit.Signature.now('John Doe', 'john@example.com');
139
140
const mergeOid = await repo.mergeBranches(
141
'main',
142
'feature-branch',
143
signature,
144
null,
145
null
146
);
147
148
console.log('Merged into commit:', mergeOid.tostrS());
149
```
150
151
### Rebase Operations
152
153
Replay commits on top of another base commit.
154
155
```javascript { .api }
156
/**
157
* Initialize rebase
158
* @param {Repository} repo - Repository instance
159
* @param {AnnotatedCommit} branch - Branch to rebase
160
* @param {AnnotatedCommit} upstream - Upstream commit
161
* @param {AnnotatedCommit} onto - Onto commit
162
* @param {RebaseOptions} opts - Rebase options
163
* @returns {Promise<Rebase>} Rebase object
164
*/
165
Rebase.init(repo, branch, upstream, onto, opts): Promise<Rebase>;
166
167
/**
168
* Open existing rebase
169
* @param {Repository} repo - Repository instance
170
* @param {RebaseOptions} opts - Rebase options
171
* @returns {Promise<Rebase>} Rebase object
172
*/
173
Rebase.open(repo, opts): Promise<Rebase>;
174
```
175
176
**Rebase Instance Methods:**
177
178
```javascript { .api }
179
/**
180
* Get next rebase operation
181
* @returns {Promise<RebaseOperation>} Next operation
182
*/
183
rebase.next(): Promise<RebaseOperation>;
184
185
/**
186
* Commit current rebase operation
187
* @param {Signature} author - Author signature
188
* @param {Signature} committer - Committer signature
189
* @returns {Promise<Oid>} Commit OID
190
*/
191
rebase.commit(author, committer): Promise<Oid>;
192
193
/**
194
* Finish rebase
195
* @param {Signature} signature - Signature for reflog
196
* @returns {Promise<void>}
197
*/
198
rebase.finish(signature): Promise<void>;
199
200
/**
201
* Abort rebase
202
* @returns {Promise<void>}
203
*/
204
rebase.abort(): Promise<void>;
205
206
/**
207
* Get operation count
208
* @returns {number} Number of operations
209
*/
210
rebase.operationCount(): number;
211
212
/**
213
* Get current operation index
214
* @returns {number} Current operation index
215
*/
216
rebase.operationCurrent(): number;
217
218
/**
219
* Get operation by index
220
* @param {number} idx - Operation index
221
* @returns {RebaseOperation} Rebase operation
222
*/
223
rebase.operationAt(idx): RebaseOperation;
224
225
/**
226
* Get onto commit ID
227
* @returns {Oid} Onto commit OID
228
*/
229
rebase.ontoId(): Oid;
230
231
/**
232
* Get onto name
233
* @returns {string} Onto name
234
*/
235
rebase.ontoName(): string;
236
237
/**
238
* Check if rebase is in-memory
239
* @returns {boolean} True if in-memory
240
*/
241
rebase.inmemory(): boolean;
242
```
243
244
**Usage Examples:**
245
246
```javascript
247
// Interactive rebase
248
const branch = await repo.getBranch('feature');
249
const upstream = await repo.getBranch('main');
250
const branchCommit = await NodeGit.AnnotatedCommit.fromRef(repo, branch);
251
const upstreamCommit = await NodeGit.AnnotatedCommit.fromRef(repo, upstream);
252
253
const rebase = await NodeGit.Rebase.init(
254
repo,
255
branchCommit,
256
upstreamCommit,
257
null,
258
null
259
);
260
261
console.log('Rebase operations:', rebase.operationCount());
262
263
const signature = NodeGit.Signature.now('John Doe', 'john@example.com');
264
265
// Process each rebase operation
266
while (rebase.operationCurrent() < rebase.operationCount()) {
267
try {
268
const operation = await rebase.next();
269
console.log('Processing operation:', operation.type());
270
271
// Commit the operation (or handle conflicts)
272
const commitOid = await rebase.commit(signature, signature);
273
console.log('Rebased commit:', commitOid.tostrS());
274
275
} catch (error) {
276
if (error.message.includes('conflicts')) {
277
console.log('Conflicts detected - resolve manually');
278
// Handle conflicts here
279
break;
280
}
281
throw error;
282
}
283
}
284
285
// Finish rebase
286
await rebase.finish(signature);
287
console.log('Rebase completed');
288
```
289
290
### Repository Rebase Methods
291
292
High-level rebase operations on Repository.
293
294
```javascript { .api }
295
/**
296
* Rebase branches
297
* @param {string} branch - Branch to rebase
298
* @param {string} upstream - Upstream branch
299
* @param {string} onto - Onto branch
300
* @param {Signature} signature - Rebase signature
301
* @param {Function} beforeNextFn - Callback before each operation
302
* @returns {Promise<Oid>} Final commit OID
303
*/
304
repository.rebaseBranches(branch, upstream, onto, signature, beforeNextFn): Promise<Oid>;
305
```
306
307
### Stash Operations
308
309
Save and restore work-in-progress changes.
310
311
```javascript { .api }
312
/**
313
* Save stash
314
* @param {Repository} repo - Repository instance
315
* @param {Signature} stasher - Stasher signature
316
* @param {string} message - Stash message
317
* @param {number} flags - Stash flags
318
* @returns {Promise<Oid>} Stash OID
319
*/
320
Stash.save(repo, stasher, message, flags): Promise<Oid>;
321
322
/**
323
* Apply stash
324
* @param {Repository} repo - Repository instance
325
* @param {number} index - Stash index
326
* @param {StashApplyOptions} opts - Apply options
327
* @returns {Promise<void>}
328
*/
329
Stash.apply(repo, index, opts): Promise<void>;
330
331
/**
332
* Pop stash (apply and drop)
333
* @param {Repository} repo - Repository instance
334
* @param {number} index - Stash index
335
* @param {StashApplyOptions} opts - Apply options
336
* @returns {Promise<void>}
337
*/
338
Stash.pop(repo, index, opts): Promise<void>;
339
340
/**
341
* Drop stash
342
* @param {Repository} repo - Repository instance
343
* @param {number} index - Stash index
344
* @returns {Promise<void>}
345
*/
346
Stash.drop(repo, index): Promise<void>;
347
348
/**
349
* Iterate through stashes
350
* @param {Repository} repo - Repository instance
351
* @param {Function} callback - Stash callback
352
* @returns {Promise<void>}
353
*/
354
Stash.foreach(repo, callback): Promise<void>;
355
```
356
357
**Usage Examples:**
358
359
```javascript
360
// Save stash
361
const signature = NodeGit.Signature.now('John Doe', 'john@example.com');
362
363
const stashOid = await NodeGit.Stash.save(
364
repo,
365
signature,
366
'Work in progress on feature',
367
NodeGit.Stash.FLAGS.DEFAULT
368
);
369
370
console.log('Stashed changes:', stashOid.tostrS());
371
372
// List stashes
373
await NodeGit.Stash.foreach(repo, function(index, message, oid) {
374
console.log(`Stash ${index}: ${message} (${oid.tostrS()})`);
375
});
376
377
// Apply latest stash
378
const applyOptions = {
379
flags: NodeGit.Stash.APPLY_FLAGS.APPLY_DEFAULT,
380
checkoutOptions: {
381
strategy: NodeGit.Checkout.STRATEGY.SAFE
382
}
383
};
384
385
await NodeGit.Stash.apply(repo, 0, applyOptions);
386
console.log('Applied stash');
387
388
// Pop stash (apply and remove)
389
await NodeGit.Stash.pop(repo, 0, applyOptions);
390
console.log('Popped stash');
391
```
392
393
### Repository Stash Methods
394
395
Convenience stash method on Repository.
396
397
```javascript { .api }
398
/**
399
* Stash changes
400
* @param {Signature} signature - Stasher signature
401
* @param {string} message - Stash message
402
* @param {number} flags - Stash flags
403
* @returns {Promise<Oid>} Stash OID
404
*/
405
repository.stash(signature, message, flags): Promise<Oid>;
406
```
407
408
### Cherry-pick Operations
409
410
Apply specific commits to current branch.
411
412
```javascript { .api }
413
/**
414
* Cherry-pick commit
415
* @param {Repository} repo - Repository instance
416
* @param {Commit} commit - Commit to cherry-pick
417
* @param {CherrypickOptions} opts - Cherry-pick options
418
* @returns {Promise<void>}
419
*/
420
Cherrypick.cherrypick(repo, commit, opts): Promise<void>;
421
422
/**
423
* Cherry-pick commit with merge
424
* @param {Repository} repo - Repository instance
425
* @param {Commit} cherrypickCommit - Commit to cherry-pick
426
* @param {Commit} ourCommit - Our commit
427
* @param {number} mainline - Mainline parent (for merges)
428
* @param {MergeOptions} opts - Merge options
429
* @returns {Promise<Index>} Cherry-pick result index
430
*/
431
Cherrypick.commit(repo, cherrypickCommit, ourCommit, mainline, opts): Promise<Index>;
432
```
433
434
### Repository Cherry-pick Methods
435
436
Convenience cherry-pick method on Repository.
437
438
```javascript { .api }
439
/**
440
* Cherry-pick commit
441
* @param {Commit} commit - Commit to cherry-pick
442
* @param {CherrypickOptions} opts - Cherry-pick options
443
* @returns {Promise<void>}
444
*/
445
repository.cherrypick(commit, opts): Promise<void>;
446
```
447
448
**Usage Examples:**
449
450
```javascript
451
// Cherry-pick specific commit
452
const commitToPick = await NodeGit.Commit.lookup(repo, someOid);
453
454
const cherrypickOptions = {
455
mainline: 0,
456
mergeOpts: {
457
fileFavor: NodeGit.Merge.FILE_FAVOR.NORMAL
458
},
459
checkoutOpts: {
460
strategy: NodeGit.Checkout.STRATEGY.SAFE
461
}
462
};
463
464
await repo.cherrypick(commitToPick, cherrypickOptions);
465
console.log('Cherry-picked commit:', commitToPick.sha());
466
```
467
468
### Revert Operations
469
470
Create commits that undo previous commits.
471
472
```javascript { .api }
473
/**
474
* Revert commit
475
* @param {Repository} repo - Repository instance
476
* @param {Commit} commit - Commit to revert
477
* @param {RevertOptions} opts - Revert options
478
* @returns {Promise<void>}
479
*/
480
Revert.revert(repo, commit, opts): Promise<void>;
481
482
/**
483
* Revert commit with merge
484
* @param {Repository} repo - Repository instance
485
* @param {Commit} revertCommit - Commit to revert
486
* @param {Commit} ourCommit - Our commit
487
* @param {number} mainline - Mainline parent (for merges)
488
* @param {MergeOptions} opts - Merge options
489
* @returns {Promise<Index>} Revert result index
490
*/
491
Revert.commit(repo, revertCommit, ourCommit, mainline, opts): Promise<Index>;
492
```
493
494
### Repository Revert Methods
495
496
Convenience revert method on Repository.
497
498
```javascript { .api }
499
/**
500
* Revert commit
501
* @param {Commit} commit - Commit to revert
502
* @param {RevertOptions} opts - Revert options
503
* @returns {Promise<void>}
504
*/
505
repository.revert(commit, opts): Promise<void>;
506
```
507
508
**Usage Examples:**
509
510
```javascript
511
// Revert specific commit
512
const commitToRevert = await NodeGit.Commit.lookup(repo, badCommitOid);
513
514
const revertOptions = {
515
mainline: 0,
516
mergeOpts: {
517
fileFavor: NodeGit.Merge.FILE_FAVOR.NORMAL
518
},
519
checkoutOpts: {
520
strategy: NodeGit.Checkout.STRATEGY.SAFE
521
}
522
};
523
524
await repo.revert(commitToRevert, revertOptions);
525
console.log('Reverted commit:', commitToRevert.sha());
526
```
527
528
### Reset Operations
529
530
Reset repository state to specific commits.
531
532
```javascript { .api }
533
/**
534
* Reset repository to commit
535
* @param {Repository} repo - Repository instance
536
* @param {Commit|Oid} target - Target commit or OID
537
* @param {number} resetType - Reset type (SOFT, MIXED, HARD)
538
* @param {CheckoutOptions} checkoutOpts - Checkout options
539
* @returns {Promise<void>}
540
*/
541
Reset.reset(repo, target, resetType, checkoutOpts): Promise<void>;
542
543
/**
544
* Reset from annotated commit
545
* @param {Repository} repo - Repository instance
546
* @param {AnnotatedCommit} commit - Annotated commit
547
* @param {number} resetType - Reset type
548
* @param {CheckoutOptions} checkoutOpts - Checkout options
549
* @returns {Promise<void>}
550
*/
551
Reset.fromAnnotated(repo, commit, resetType, checkoutOpts): Promise<void>;
552
553
/**
554
* Reset default (unstage files)
555
* @param {Repository} repo - Repository instance
556
* @param {Commit|Oid} target - Target commit or OID
557
* @param {string[]} pathspecs - Paths to reset
558
* @returns {Promise<void>}
559
*/
560
Reset.default(repo, target, pathspecs): Promise<void>;
561
```
562
563
### Repository Reset Methods
564
565
Convenience reset method on Repository.
566
567
```javascript { .api }
568
/**
569
* Reset repository state
570
* @param {Commit|Oid} target - Target commit or OID
571
* @param {number} type - Reset type
572
* @param {CheckoutOptions} checkoutOpts - Checkout options
573
* @returns {Promise<void>}
574
*/
575
repository.reset(target, type, checkoutOpts): Promise<void>;
576
```
577
578
**Usage Examples:**
579
580
```javascript
581
// Hard reset to previous commit
582
const headCommit = await repo.getHeadCommit();
583
const previousCommit = await headCommit.parent(0);
584
585
await repo.reset(previousCommit, NodeGit.Reset.TYPE.HARD, {
586
strategy: NodeGit.Checkout.STRATEGY.FORCE
587
});
588
589
console.log('Reset to:', previousCommit.sha());
590
591
// Soft reset (keep working directory and index)
592
await repo.reset(previousCommit, NodeGit.Reset.TYPE.SOFT, null);
593
594
// Mixed reset (reset index but keep working directory)
595
await repo.reset(previousCommit, NodeGit.Reset.TYPE.MIXED, {
596
strategy: NodeGit.Checkout.STRATEGY.SAFE
597
});
598
599
// Reset specific files (unstage)
600
await NodeGit.Reset.default(repo, headCommit, ['file1.txt', 'file2.txt']);
601
console.log('Unstaged specific files');
602
```
603
604
## Types
605
606
```javascript { .api }
607
interface MergeOptions {
608
fileFavor: number;
609
fileFlags: number;
610
renameThreshold: number;
611
targetLimit: number;
612
metric: Function;
613
recursionLimit: number;
614
defaultDriver: string;
615
}
616
617
interface RebaseOptions {
618
quiet: boolean;
619
inmemory: boolean;
620
rewriteNotesRef: string;
621
mergeOptions: MergeOptions;
622
checkoutOptions: CheckoutOptions;
623
}
624
625
interface RebaseOperation {
626
type(): number;
627
id(): Oid;
628
exec(): string;
629
}
630
631
interface StashApplyOptions {
632
flags: number;
633
checkoutOptions: CheckoutOptions;
634
progressCallback: Function;
635
}
636
637
interface CherrypickOptions {
638
mainline: number;
639
mergeOpts: MergeOptions;
640
checkoutOpts: CheckoutOptions;
641
}
642
643
interface RevertOptions {
644
mainline: number;
645
mergeOpts: MergeOptions;
646
checkoutOpts: CheckoutOptions;
647
}
648
649
// Merge file favor
650
Merge.FILE_FAVOR = {
651
NORMAL: 0,
652
OURS: 1,
653
THEIRS: 2,
654
UNION: 3
655
};
656
657
// Merge file flags
658
Merge.FILE_FLAGS = {
659
DEFAULT: 0,
660
STYLE_MERGE: 1,
661
STYLE_DIFF3: 2,
662
SIMPLIFY_ALNUM: 4,
663
IGNORE_WHITESPACE: 8,
664
IGNORE_WHITESPACE_CHANGE: 16,
665
IGNORE_WHITESPACE_EOL: 32,
666
DIFF_PATIENCE: 64,
667
DIFF_MINIMAL: 128
668
};
669
670
// Reset types
671
Reset.TYPE = {
672
SOFT: 1,
673
MIXED: 2,
674
HARD: 3
675
};
676
677
// Stash flags
678
Stash.FLAGS = {
679
DEFAULT: 0,
680
KEEP_INDEX: 1,
681
INCLUDE_UNTRACKED: 2,
682
INCLUDE_IGNORED: 4
683
};
684
685
// Stash apply flags
686
Stash.APPLY_FLAGS = {
687
APPLY_DEFAULT: 0,
688
APPLY_REINSTATE_INDEX: 1
689
};
690
691
// Rebase operation types
692
Rebase.OPERATION = {
693
PICK: 0,
694
REWORD: 1,
695
EDIT: 2,
696
SQUASH: 3,
697
FIXUP: 4,
698
EXEC: 5
699
};
700
```