Skip to content

Commit 28f3abd

Browse files
authored
feat: add merge features (#127)
1 parent bc0b2c7 commit 28f3abd

File tree

7 files changed

+1020
-1
lines changed

7 files changed

+1020
-1
lines changed

index.d.ts

Lines changed: 351 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,125 @@ export interface AddMailmapEntryData {
825825
* ```
826826
*/
827827
export declare function createMailmapFromBuffer(content: string): Mailmap
828+
export type FileFavor = /**
829+
* When a region of a file is changed in both branches, a conflict will be
830+
* recorded in the index so that git_checkout can produce a merge file with
831+
* conflict markers in the working directory. This is the default.
832+
*/
833+
'Normal' | /**
834+
* When a region of a file is changed in both branches, the file created
835+
* in the index will contain the "ours" side of any conflicting region.
836+
* The index will not record a conflict.
837+
*/
838+
'Ours' | /**
839+
* When a region of a file is changed in both branches, the file created
840+
* in the index will contain the "theirs" side of any conflicting region.
841+
* The index will not record a conflict.
842+
*/
843+
'Theirs' | /**
844+
* When a region of a file is changed in both branches, the file created
845+
* in the index will contain each unique line from each side, which has
846+
* the result of combining both files. The index will not record a conflict.
847+
*/
848+
'Union';
849+
export interface MergeOptions {
850+
/** Detect file renames */
851+
findRenames?: boolean
852+
/**
853+
* If a conflict occurs, exit immediately instead of attempting to continue
854+
* resolving conflicts
855+
*/
856+
failOnConflict?: boolean
857+
/** Do not write the REUC extension on the generated index */
858+
skipReuc?: boolean
859+
/**
860+
* If the commits being merged have multiple merge bases, do not build a
861+
* recursive merge base (by merging the multiple merge bases), instead
862+
* simply use the first base.
863+
*/
864+
noRecursive?: boolean
865+
/** Similarity to consider a file renamed (default 50) */
866+
renameThreshold?: number
867+
/**
868+
* Maximum similarity sources to examine for renames (default 200).
869+
* If the number of rename candidates (add / delete pairs) is greater
870+
* than this value, inexact rename detection is aborted. This setting
871+
* overrides the `merge.renameLimit` configuration value.
872+
*/
873+
targetLimit?: number
874+
/**
875+
* Maximum number of times to merge common ancestors to build a
876+
* virtual merge base when faced with criss-cross merges. When
877+
* this limit is reached, the next ancestor will simply be used
878+
* instead of attempting to merge it. The default is unlimited.
879+
*/
880+
recursionLimit?: number
881+
/** Specify a side to favor for resolving conflicts */
882+
filFavor?: FileFavor
883+
/** Create standard conflicted merge files */
884+
standardStyle?: boolean
885+
/** Create diff3-style file */
886+
diff3Style?: boolean
887+
/** Condense non-alphanumeric regions for simplified diff file */
888+
simplifyAlnum?: boolean
889+
/** Ignore all whitespace */
890+
ignoreWhitespace?: boolean
891+
/** Ignore changes in amount of whitespace */
892+
ignoreWhitespaceChange?: boolean
893+
/** Ignore whitespace at end of line */
894+
ignoreWhitespaceEol?: boolean
895+
/** Use the "patience diff" algorithm */
896+
patience?: boolean
897+
/** Take extra time to find minimal diff */
898+
minimal?: boolean
899+
}
900+
export interface MergeAnalysis {
901+
/** No merge is possible. */
902+
none: boolean
903+
/**
904+
* A "normal" merge; both HEAD and the given merge input have diverged
905+
* from their common ancestor. The divergent commits must be merged.
906+
*/
907+
normal: boolean
908+
/**
909+
* All given merge inputs are reachable from HEAD, meaning the
910+
* repository is up-to-date and no merge needs to be performed.
911+
*/
912+
upToDate: boolean
913+
/**
914+
* The given merge input is a fast-forward from HEAD and no merge
915+
* needs to be performed. Instead, the client can check out the
916+
* given merge input.
917+
*/
918+
fastForward: boolean
919+
/**
920+
* The HEAD of the current repository is "unborn" and does not point to
921+
* a valid commit. No merge can be performed, but the caller may wish
922+
* to simply set HEAD to the target commit(s).
923+
*/
924+
unborn: boolean
925+
}
926+
export interface MergePreference {
927+
/**
928+
* No configuration was found that suggests a preferred behavior for
929+
* merge.
930+
*/
931+
none: boolean
932+
/**
933+
* There is a `merge.ff=false` configuration setting, suggesting that
934+
* the user does not want to allow a fast-forward merge.
935+
*/
936+
noFastForward: boolean
937+
/**
938+
* There is a `merge.ff=only` configuration setting, suggesting that
939+
* the user only wants fast-forward merges.
940+
*/
941+
fastForwardOnly: boolean
942+
}
943+
export interface MergeAnalysisResult {
944+
analysis: MergeAnalysis
945+
preference: MergePreference
946+
}
828947
/**
829948
* - `Any` : Any kind of git object
830949
* - `Commit` : An object which corresponds to a git commit
@@ -4498,6 +4617,225 @@ export declare class Repository {
44984617
* @returns The mailmap object if it exists, null otherwise
44994618
*/
45004619
mailmap(): Mailmap | null
4620+
/**
4621+
* Find a merge base between two commits
4622+
*
4623+
* @category Repository/Methods
4624+
* @signature
4625+
* ```ts
4626+
* class Repository {
4627+
* mergeBase(one: string, two: string): string;
4628+
* }
4629+
* ```
4630+
*
4631+
* @param {string} one - One of the commits OID.
4632+
* @param {string} two - The other commit OID.
4633+
* @returns The OID of a merge base between 'one' and 'two'.
4634+
*/
4635+
getMergeBase(one: string, two: string): string
4636+
/**
4637+
* Find a merge base given a list of commits
4638+
*
4639+
* This behaves similar to [`git merge-base`](https://git-scm.com/docs/git-merge-base#_discussion).
4640+
* Given three commits `a`, `b`, and `c`, `getMergeBaseMany([a, b, c])`
4641+
* will compute a hypothetical commit `m`, which is a merge between `b`
4642+
* and `c`.
4643+
*
4644+
* For example, with the following topology:
4645+
* ```text
4646+
* o---o---o---o---C
4647+
* /
4648+
* / o---o---o---B
4649+
* / /
4650+
* ---2---1---o---o---o---A
4651+
* ```
4652+
*
4653+
* the result of `getMergeBaseMany([a, b, c])` is 1. This is because the
4654+
* equivalent topology with a merge commit `m` between `b` and `c` would
4655+
* is:
4656+
* ```text
4657+
* o---o---o---o---o
4658+
* / \
4659+
* / o---o---o---o---M
4660+
* / /
4661+
* ---2---1---o---o---o---A
4662+
* ```
4663+
*
4664+
* and the result of `getMergeBaseMany([a, m])` is 1.
4665+
*
4666+
* ---
4667+
*
4668+
* If you're looking to recieve the common merge base between all the
4669+
* given commits, use `getMergeBaseOctopus`.
4670+
*
4671+
* @category Repository/Methods
4672+
* @signature
4673+
* ```ts
4674+
* class Repository {
4675+
* getMergeBaseMany(oids: string[]): string;
4676+
* }
4677+
* ```
4678+
*
4679+
* @param {string[]} oids - Oids of the commits.
4680+
* @returns The OID of a merge base considering all the commits.
4681+
*/
4682+
getMergeBaseMany(oids: Array<string>): string
4683+
/**
4684+
* Find a merge base in preparation for an octopus merge.
4685+
*
4686+
* @category Repository/Methods
4687+
* @signature
4688+
* ```ts
4689+
* class Repository {
4690+
* getMergeBaseOctopus(oids: string[]): string;
4691+
* }
4692+
* ```
4693+
*
4694+
* @param {string[]} oids - Oids of the commits.
4695+
* @returns The OID of a merge base considering all the commits.
4696+
*/
4697+
getMergeBaseOctopus(oids: Array<string>): string
4698+
/**
4699+
* Find all merge bases between two commits
4700+
*
4701+
* @category Repository/Methods
4702+
* @signature
4703+
* ```ts
4704+
* class Repository {
4705+
* getMergeBases(one: string, two: string): string[];
4706+
* }
4707+
* ```
4708+
*
4709+
* @param {string} one - One of the commits OID.
4710+
* @param {string} two - The other commit OID.
4711+
* @returns Array in which to store the resulting OIDs.
4712+
*/
4713+
getMergeBases(one: string, two: string): Array<string>
4714+
/**
4715+
* Find all merge bases given a list of commits
4716+
*
4717+
* @category Repository/Methods
4718+
* @signature
4719+
* ```ts
4720+
* class Repository {
4721+
* getMergeBasesMany(oids: string[]): string[];
4722+
* }
4723+
* ```
4724+
*
4725+
* @param {string[]} oids - Oids of the commits.
4726+
* @returns Array in which to store the resulting OIDs.
4727+
*/
4728+
getMergeBasesMany(oids: Array<string>): Array<string>
4729+
/**
4730+
* Merges the given commit(s) into HEAD, writing the results into the
4731+
* working directory. Any changes are staged for commit and any conflicts
4732+
* are written to the index. Callers should inspect the repository's index
4733+
* after this completes, resolve any conflicts and prepare a commit.
4734+
*
4735+
* For compatibility with git, the repository is put into a merging state.
4736+
* Once the commit is done (or if the user wishes to abort), you should
4737+
* clear this state by calling `cleanupState()`.
4738+
*
4739+
* @category Repository/Methods
4740+
* @signature
4741+
* ```ts
4742+
* class Repository {
4743+
* merge(
4744+
* annotatedCommits: AnnotatedCommit[],
4745+
* mergeOptions?: MergeOptions | undefined | null,
4746+
* checkoutOptions?: CheckoutOptions | undefined | null,
4747+
* ): void;
4748+
* }
4749+
* ```
4750+
*
4751+
* @param {AnnotatedCommit[]} annotatedCommits - Commits to merge.
4752+
* @param {MergeOptions} [mergeOptions] - Merge options.
4753+
* @param {CheckoutOptions} [checkoutOptions] - Checkout options.
4754+
*/
4755+
merge(annotatedCommits: Array<AnnotatedCommit>, mergeOptions?: MergeOptions | undefined | null, checkoutOptions?: CheckoutOptions | undefined | null): void
4756+
/**
4757+
* Merge two commits, producing an index that reflects the result of
4758+
* the merge. The index may be written as-is to the working directory or
4759+
* checked out. If the index is to be converted to a tree, the caller
4760+
* should resolve any conflicts that arose as part of the merge.
4761+
*
4762+
* @category Repository/Methods
4763+
* @signature
4764+
* ```ts
4765+
* class Repository {
4766+
* mergeCommits(
4767+
* ourCommit: Commit,
4768+
* theirCommit: Commit,
4769+
* options?: MergeOptions | undefined | null,
4770+
* ): Index;
4771+
* }
4772+
* ```
4773+
*
4774+
* @param {Commit} outCommit - The commit that reflects the destination tree.
4775+
* @param {Commit} theirCommit - The commit to merge in to `ourCommit`.
4776+
* @param {MergeOptions} [options] - Merge options.
4777+
* @returns The index result.
4778+
*/
4779+
mergeCommits(ourCommit: Commit, theirCommit: Commit, options?: MergeOptions | undefined | null): Index
4780+
/**
4781+
* Merge two trees, producing an index that reflects the result of
4782+
* the merge. The index may be written as-is to the working directory or
4783+
* checked out. If the index is to be converted to a tree, the caller
4784+
* should resolve any conflicts that arose as part of the merge.
4785+
*
4786+
* @category Repository/Methods
4787+
* @signature
4788+
* ```ts
4789+
* class Repository {
4790+
* mergeTrees(
4791+
* ancestorTree: Tree,
4792+
* ourTree: Tree,
4793+
* theirTree: Tree,
4794+
* options?: MergeOptions | undefined | null,
4795+
* ): Index;
4796+
* }
4797+
* ```
4798+
*
4799+
* @param {Tree} ancestorTree - The common ancestor between.
4800+
* @param {Tree} outTree - The tree that reflects the destination tree.
4801+
* @param {Tree} theirTree - The tree to merge in to `ourTree`.
4802+
* @param {MergeOptions} [options] - Merge options.
4803+
* @returns The index result.
4804+
*/
4805+
mergeTrees(ancestorTree: Tree, ourTree: Tree, theirTree: Tree, options?: MergeOptions | undefined | null): Index
4806+
/**
4807+
* Analyzes the given branch(es) and determines the opportunities for
4808+
* merging them into the HEAD of the repository.
4809+
*
4810+
* @category Repository/Methods
4811+
* @signature
4812+
* ```ts
4813+
* class Repository {
4814+
* analyzeMergeFor(theirHeads: AnnotatedCommit[]): MergeAnalysisResult;
4815+
* }
4816+
* ```
4817+
*
4818+
* @param {AnnotatedCommit[]} theirHeads - The heads to merge into.
4819+
* @returns Merge analysis result.
4820+
*/
4821+
analyzeMerge(theirHeads: Array<AnnotatedCommit>): MergeAnalysisResult
4822+
/**
4823+
* Analyzes the given branch(es) and determines the opportunities for
4824+
* merging them into a reference.
4825+
*
4826+
* @category Repository/Methods
4827+
* @signature
4828+
* ```ts
4829+
* class Repository {
4830+
* analyzeMergeForRef(ourRef: Reference, theirHeads: AnnotatedCommit[]): MergeAnalysisResult;
4831+
* }
4832+
* ```
4833+
*
4834+
* @param {Reference} ourRef - The reference to perform the analysis from.
4835+
* @param {AnnotatedCommit[]} theirHeads - The heads to merge into.
4836+
* @returns Merge analysis result.
4837+
*/
4838+
analyzeMergeForRef(ourRef: Reference, theirHeads: Array<AnnotatedCommit>): MergeAnalysisResult
45014839
/**
45024840
* Lookup a reference to one of the objects in a repository.
45034841
*
@@ -4868,6 +5206,19 @@ export declare class Repository {
48685206
* or null if the object is not signed.
48695207
*/
48705208
extractSignature(oid: string): ExtractedSignature | null
5209+
/**
5210+
* Remove all the metadata associated with an ongoing command like merge,
5211+
* revert, cherry-pick, etc. For example: `MERGE_HEAD`, `MERGE_MSG`, etc.
5212+
*
5213+
* @category Repository/Methods
5214+
* @signature
5215+
* ```ts
5216+
* class Repository {
5217+
* cleanupState(): void;
5218+
* }
5219+
* ```
5220+
*/
5221+
cleanupState(): void
48715222
/**
48725223
* Execute a rev-parse operation against the `spec` listed.
48735224
*

index.js

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)