mirror of
https://github.com/SkinnyMind/libgit2dart.git
synced 2025-05-04 20:29:08 -04:00
feat(merge): add ability to pass options to fileFromIndex(...)
API method
This commit is contained in:
parent
aa073c531e
commit
57f3f5fdb7
3 changed files with 85 additions and 14 deletions
|
@ -186,30 +186,39 @@ String mergeFile({
|
||||||
libgit2.git_merge_file_input_init(theirsC, GIT_MERGE_FILE_INPUT_VERSION);
|
libgit2.git_merge_file_input_init(theirsC, GIT_MERGE_FILE_INPUT_VERSION);
|
||||||
ancestorC.ref.ptr = ancestor.toChar();
|
ancestorC.ref.ptr = ancestor.toChar();
|
||||||
ancestorC.ref.size = ancestor.length;
|
ancestorC.ref.size = ancestor.length;
|
||||||
|
Pointer<Char> ancestorLabelC = nullptr;
|
||||||
oursC.ref.ptr = ours.toChar();
|
oursC.ref.ptr = ours.toChar();
|
||||||
oursC.ref.size = ours.length;
|
oursC.ref.size = ours.length;
|
||||||
|
Pointer<Char> oursLabelC = nullptr;
|
||||||
theirsC.ref.ptr = theirs.toChar();
|
theirsC.ref.ptr = theirs.toChar();
|
||||||
theirsC.ref.size = theirs.length;
|
theirsC.ref.size = theirs.length;
|
||||||
|
Pointer<Char> theirsLabelC = nullptr;
|
||||||
|
|
||||||
final opts = calloc<git_merge_file_options>();
|
final opts = calloc<git_merge_file_options>();
|
||||||
libgit2.git_merge_file_options_init(opts, GIT_MERGE_FILE_OPTIONS_VERSION);
|
libgit2.git_merge_file_options_init(opts, GIT_MERGE_FILE_OPTIONS_VERSION);
|
||||||
opts.ref.favor = favor;
|
opts.ref.favor = favor;
|
||||||
opts.ref.flags = flags;
|
opts.ref.flags = flags;
|
||||||
if (ancestorLabel.isNotEmpty) {
|
if (ancestorLabel.isNotEmpty) {
|
||||||
opts.ref.ancestor_label = ancestorLabel.toChar();
|
ancestorLabelC = ancestorLabel.toChar();
|
||||||
|
opts.ref.ancestor_label = ancestorLabelC;
|
||||||
}
|
}
|
||||||
if (oursLabel.isNotEmpty) {
|
if (oursLabel.isNotEmpty) {
|
||||||
opts.ref.our_label = oursLabel.toChar();
|
oursLabelC = oursLabel.toChar();
|
||||||
|
opts.ref.our_label = oursLabelC;
|
||||||
}
|
}
|
||||||
if (theirsLabel.isNotEmpty) {
|
if (theirsLabel.isNotEmpty) {
|
||||||
opts.ref.their_label = theirsLabel.toChar();
|
theirsLabelC = theirsLabel.toChar();
|
||||||
|
opts.ref.their_label = theirsLabelC;
|
||||||
}
|
}
|
||||||
|
|
||||||
libgit2.git_merge_file(out, ancestorC, oursC, theirsC, opts);
|
libgit2.git_merge_file(out, ancestorC, oursC, theirsC, opts);
|
||||||
|
|
||||||
calloc.free(ancestorC);
|
calloc.free(ancestorC);
|
||||||
|
calloc.free(ancestorLabelC);
|
||||||
calloc.free(oursC);
|
calloc.free(oursC);
|
||||||
|
calloc.free(oursLabelC);
|
||||||
calloc.free(theirsC);
|
calloc.free(theirsC);
|
||||||
|
calloc.free(theirsLabelC);
|
||||||
calloc.free(opts);
|
calloc.free(opts);
|
||||||
|
|
||||||
final result = out.ref.ptr.toDartString(length: out.ref.len);
|
final result = out.ref.ptr.toDartString(length: out.ref.len);
|
||||||
|
@ -226,17 +235,43 @@ String mergeFile({
|
||||||
String mergeFileFromIndex({
|
String mergeFileFromIndex({
|
||||||
required Pointer<git_repository> repoPointer,
|
required Pointer<git_repository> repoPointer,
|
||||||
required Pointer<git_index_entry>? ancestorPointer,
|
required Pointer<git_index_entry>? ancestorPointer,
|
||||||
|
required String ancestorLabel,
|
||||||
required Pointer<git_index_entry> oursPointer,
|
required Pointer<git_index_entry> oursPointer,
|
||||||
|
required String oursLabel,
|
||||||
required Pointer<git_index_entry> theirsPointer,
|
required Pointer<git_index_entry> theirsPointer,
|
||||||
|
required String theirsLabel,
|
||||||
|
required int favor,
|
||||||
|
required int flags,
|
||||||
}) {
|
}) {
|
||||||
final out = calloc<git_merge_file_result>();
|
final out = calloc<git_merge_file_result>();
|
||||||
|
final opts = calloc<git_merge_file_options>();
|
||||||
|
Pointer<Char> ancestorLabelC = nullptr;
|
||||||
|
Pointer<Char> oursLabelC = nullptr;
|
||||||
|
Pointer<Char> theirsLabelC = nullptr;
|
||||||
|
|
||||||
|
libgit2.git_merge_file_options_init(opts, GIT_MERGE_FILE_OPTIONS_VERSION);
|
||||||
|
opts.ref.favor = favor;
|
||||||
|
opts.ref.flags = flags;
|
||||||
|
if (ancestorLabel.isNotEmpty) {
|
||||||
|
ancestorLabelC = ancestorLabel.toChar();
|
||||||
|
opts.ref.ancestor_label = ancestorLabelC;
|
||||||
|
}
|
||||||
|
if (oursLabel.isNotEmpty) {
|
||||||
|
oursLabelC = oursLabel.toChar();
|
||||||
|
opts.ref.our_label = oursLabelC;
|
||||||
|
}
|
||||||
|
if (theirsLabel.isNotEmpty) {
|
||||||
|
theirsLabelC = theirsLabel.toChar();
|
||||||
|
opts.ref.their_label = theirsLabelC;
|
||||||
|
}
|
||||||
|
|
||||||
final error = libgit2.git_merge_file_from_index(
|
final error = libgit2.git_merge_file_from_index(
|
||||||
out,
|
out,
|
||||||
repoPointer,
|
repoPointer,
|
||||||
ancestorPointer ?? nullptr,
|
ancestorPointer ?? nullptr,
|
||||||
oursPointer,
|
oursPointer,
|
||||||
theirsPointer,
|
theirsPointer,
|
||||||
nullptr,
|
opts,
|
||||||
);
|
);
|
||||||
|
|
||||||
late final String result;
|
late final String result;
|
||||||
|
@ -244,6 +279,10 @@ String mergeFileFromIndex({
|
||||||
result = out.ref.ptr.toDartString(length: out.ref.len);
|
result = out.ref.ptr.toDartString(length: out.ref.len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
calloc.free(ancestorLabelC);
|
||||||
|
calloc.free(oursLabelC);
|
||||||
|
calloc.free(theirsLabelC);
|
||||||
|
calloc.free(opts);
|
||||||
calloc.free(out);
|
calloc.free(out);
|
||||||
|
|
||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
|
|
|
@ -265,18 +265,43 @@ class Merge {
|
||||||
/// given common [ancestor] as the baseline, producing a string that reflects
|
/// given common [ancestor] as the baseline, producing a string that reflects
|
||||||
/// the merge result containing possible conflicts.
|
/// the merge result containing possible conflicts.
|
||||||
///
|
///
|
||||||
|
/// [ancestorLabel] is optional label for the ancestor file side of the
|
||||||
|
/// conflict which will be prepended to labels in diff3-format merge files.
|
||||||
|
///
|
||||||
|
/// [oursLabel] is optional label for our file side of the conflict which
|
||||||
|
/// will be prepended to labels in merge files.
|
||||||
|
///
|
||||||
|
/// [theirsLabel] is optional label for their file side of the conflict which
|
||||||
|
/// will be prepended to labels in merge files.
|
||||||
|
///
|
||||||
|
/// [favor] is one of the [GitMergeFileFavor] flags for handling conflicting
|
||||||
|
/// content. Defaults to [GitMergeFileFavor.normal].
|
||||||
|
///
|
||||||
|
/// [flags] is a combination of [GitMergeFileFlag] flags. Defaults to
|
||||||
|
/// [GitMergeFileFlag.defaults].
|
||||||
|
///
|
||||||
/// Throws a [LibGit2Error] if error occured.
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
static String fileFromIndex({
|
static String fileFromIndex({
|
||||||
required Repository repo,
|
required Repository repo,
|
||||||
required IndexEntry? ancestor,
|
required IndexEntry? ancestor,
|
||||||
|
String ancestorLabel = '',
|
||||||
required IndexEntry ours,
|
required IndexEntry ours,
|
||||||
|
String oursLabel = '',
|
||||||
required IndexEntry theirs,
|
required IndexEntry theirs,
|
||||||
|
String theirsLabel = '',
|
||||||
|
GitMergeFileFavor favor = GitMergeFileFavor.normal,
|
||||||
|
Set<GitMergeFileFlag> flags = const {GitMergeFileFlag.defaults},
|
||||||
}) {
|
}) {
|
||||||
return bindings.mergeFileFromIndex(
|
return bindings.mergeFileFromIndex(
|
||||||
repoPointer: repo.pointer,
|
repoPointer: repo.pointer,
|
||||||
ancestorPointer: ancestor?.pointer,
|
ancestorPointer: ancestor?.pointer,
|
||||||
|
ancestorLabel: ancestorLabel,
|
||||||
oursPointer: ours.pointer,
|
oursPointer: ours.pointer,
|
||||||
|
oursLabel: oursLabel,
|
||||||
theirsPointer: theirs.pointer,
|
theirsPointer: theirs.pointer,
|
||||||
|
theirsLabel: theirsLabel,
|
||||||
|
favor: favor.value,
|
||||||
|
flags: flags.fold(0, (acc, e) => acc | e.value),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -168,31 +168,38 @@ Another feature edit
|
||||||
expect(diff, diffExpected);
|
expect(diff, diffExpected);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('merges with provided merge flags and file flags', () {
|
test('merges with provided options', () {
|
||||||
const diffExpected = """
|
const diffExpected = """
|
||||||
\<<<<<<< conflict_file
|
\<<<<<<< ours
|
||||||
master conflict edit
|
Feature edit on feature branch
|
||||||
|
||||||| ancestor
|
||||||
|
Feature edit
|
||||||
=======
|
=======
|
||||||
conflict branch edit
|
Another feature edit
|
||||||
>>>>>>> conflict_file
|
>>>>>>> theirs
|
||||||
""";
|
""";
|
||||||
|
|
||||||
|
Checkout.reference(repo: repo, name: 'refs/heads/feature');
|
||||||
|
repo.setHead('refs/heads/feature');
|
||||||
|
|
||||||
Merge.commit(
|
Merge.commit(
|
||||||
repo: repo,
|
repo: repo,
|
||||||
commit: AnnotatedCommit.lookup(
|
commit: AnnotatedCommit.lookup(
|
||||||
repo: repo,
|
repo: repo,
|
||||||
oid: Branch.lookup(repo: repo, name: 'conflict-branch').target,
|
oid: Branch.lookup(repo: repo, name: 'ancestor-conflict').target,
|
||||||
),
|
),
|
||||||
mergeFlags: {GitMergeFlag.noRecursive},
|
|
||||||
fileFlags: {GitMergeFileFlag.ignoreWhitespaceEOL},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
final conflictedFile = repo.index.conflicts['conflict_file']!;
|
final conflictedFile = repo.index.conflicts['feature_file']!;
|
||||||
final diff = Merge.fileFromIndex(
|
final diff = Merge.fileFromIndex(
|
||||||
repo: repo,
|
repo: repo,
|
||||||
ancestor: null,
|
ancestor: conflictedFile.ancestor,
|
||||||
|
ancestorLabel: 'ancestor',
|
||||||
ours: conflictedFile.our!,
|
ours: conflictedFile.our!,
|
||||||
|
oursLabel: 'ours',
|
||||||
theirs: conflictedFile.their!,
|
theirs: conflictedFile.their!,
|
||||||
|
theirsLabel: 'theirs',
|
||||||
|
flags: {GitMergeFileFlag.styleDiff3},
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(diff, diffExpected);
|
expect(diff, diffExpected);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue