Allow for merges with whitespace discrepancies
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
diff --git a/include/git2/merge.h b/include/git2/merge.h
index 40330d0..73375b3 100644
--- a/include/git2/merge.h
+++ b/include/git2/merge.h
@@ -111,6 +111,23 @@ typedef enum {
} git_merge_file_favor_t;
/**
+ * Whitespace merging flags
+ */
+typedef enum {
+ /** Defaults */
+ GIT_MERGE_FILE_IGNORE_DEFAULT = 0,
+
+ /** Ignore all whitespace */
+ GIT_MERGE_FILE_IGNORE_WHITESPACE = (1 << 0),
+
+ /** Ignore changes in amount of whitespace */
+ GIT_MERGE_FILE_IGNORE_WHITESPACE_CHANGE = (1 << 1),
+
+ /** Ignore whitespace at end of line */
+ GIT_MERGE_FILE_IGNORE_WHITESPACE_EOL = (1 << 2),
+} git_merge_file_whitespace_t;
+
+/**
* File merging flags
*/
typedef enum {
@@ -156,6 +173,9 @@ typedef struct {
/** Merge file flags. */
git_merge_file_flags_t flags;
+
+ /** Whitespace merge flags */
+ unsigned int whitespace_flags;
} git_merge_file_options;
#define GIT_MERGE_FILE_OPTIONS_VERSION 1
@@ -230,6 +250,9 @@ typedef struct {
/** Flags for handling conflicting content. */
git_merge_file_favor_t file_favor;
+
+ /** Flags for handling whitespace */
+ unsigned int whitespace_flags;
} git_merge_options;
#define GIT_MERGE_OPTIONS_VERSION 1
diff --git a/src/merge.c b/src/merge.c
index 75ad091..2972d9f 100644
--- a/src/merge.c
+++ b/src/merge.c
@@ -653,7 +653,8 @@ static int merge_conflict_resolve_automerge(
int *resolved,
git_merge_diff_list *diff_list,
const git_merge_diff *conflict,
- unsigned int merge_file_favor)
+ unsigned int merge_file_favor,
+ unsigned int whitespace_flags)
{
const git_index_entry *ancestor = NULL, *ours = NULL, *theirs = NULL;
git_merge_file_options opts = GIT_MERGE_FILE_OPTIONS_INIT;
@@ -708,6 +709,7 @@ static int merge_conflict_resolve_automerge(
&conflict->their_entry : NULL;
opts.favor = merge_file_favor;
+ opts.whitespace_flags = whitespace_flags;
if ((error = git_repository_odb(&odb, diff_list->repo)) < 0 ||
(error = git_merge_file_from_index(&result, diff_list->repo, ancestor, ours, theirs, &opts)) < 0 ||
@@ -741,7 +743,8 @@ static int merge_conflict_resolve(
int *out,
git_merge_diff_list *diff_list,
const git_merge_diff *conflict,
- unsigned int merge_file_favor)
+ unsigned int merge_file_favor,
+ unsigned int whitespace_flags)
{
int resolved = 0;
int error = 0;
@@ -757,7 +760,8 @@ static int merge_conflict_resolve(
if (!resolved && (error = merge_conflict_resolve_one_renamed(&resolved, diff_list, conflict)) < 0)
goto done;
- if (!resolved && (error = merge_conflict_resolve_automerge(&resolved, diff_list, conflict, merge_file_favor)) < 0)
+ if (!resolved && (error = merge_conflict_resolve_automerge(&resolved, diff_list, conflict,
+ merge_file_favor, whitespace_flags)) < 0)
goto done;
*out = resolved;
@@ -1779,7 +1783,7 @@ int git_merge_trees(
git_vector_foreach(&changes, i, conflict) {
int resolved = 0;
- if ((error = merge_conflict_resolve(&resolved, diff_list, conflict, opts.file_favor)) < 0)
+ if ((error = merge_conflict_resolve(&resolved, diff_list, conflict, opts.file_favor, opts.whitespace_flags)) < 0)
goto done;
if (!resolved)
diff --git a/src/merge_file.c b/src/merge_file.c
index ff03644..b827ca9 100644
--- a/src/merge_file.c
+++ b/src/merge_file.c
@@ -151,6 +151,13 @@ static int git_merge_file__from_inputs(
if (options.flags & GIT_MERGE_FILE_STYLE_DIFF3)
xmparam.style = XDL_MERGE_DIFF3;
+ if (options.whitespace_flags & GIT_MERGE_FILE_IGNORE_WHITESPACE)
+ xmparam.xpp.flags |= XDF_IGNORE_WHITESPACE;
+ if (options.whitespace_flags & GIT_MERGE_FILE_IGNORE_WHITESPACE_CHANGE)
+ xmparam.xpp.flags |= XDF_IGNORE_WHITESPACE_CHANGE;
+ if (options.whitespace_flags & GIT_MERGE_FILE_IGNORE_WHITESPACE_EOL)
+ xmparam.xpp.flags |= XDF_IGNORE_WHITESPACE_AT_EOL;
+
if ((xdl_result = xdl_merge(&ancestor_mmfile, &our_mmfile,
&their_mmfile, &xmparam, &mmbuffer)) < 0) {
giterr_set(GITERR_MERGE, "Failed to merge files.");