From 45a86bbfd028a545a71d3e1ea5518d467be8b5aa Mon Sep 17 00:00:00 2001 From: Jacques Germishuys Date: Mon, 9 Mar 2015 17:02:52 +0200 Subject: [PATCH] Allow for merges with whitespace discrepancies --- include/git2/merge.h | 23 +++++++++++++++++++++++ src/merge.c | 12 ++++++++---- src/merge_file.c | 7 +++++++ 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/include/git2/merge.h b/include/git2/merge.h index 40330d0d8..73375b319 100644 --- a/include/git2/merge.h +++ b/include/git2/merge.h @@ -110,6 +110,23 @@ typedef enum { GIT_MERGE_FILE_FAVOR_UNION = 3, } 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 */ @@ -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 75ad0915e..2972d9ff3 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 ff0364432..b827ca977 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.");