From 3228e67120a8c71bf7804a5c52448a841d6f3b58 Mon Sep 17 00:00:00 2001 From: Johan Herland Date: Mon, 15 Nov 2010 00:55:12 +0100 Subject: git notes merge: Add automatic conflict resolvers (ours, theirs, union) The new -s/--strategy command-line option to 'git notes merge' allow the user to choose how notes merge conflicts should be resolved. There are four valid strategies to choose from: 1. "manual" (the default): This will let the user manually resolve conflicts. This option currently fails with an error message. It will be implemented properly in future patches. 2. "ours": This automatically chooses the local version of a conflict, and discards the remote version. 3. "theirs": This automatically chooses the remote version of a conflict, and discards the local version. 4. "union": This automatically resolves the conflict by appending the remote version to the local version. The strategies are implemented using the combine_notes_* functions from the notes.h API. The patch also includes testcases verifying the correct implementation of these strategies. This patch has been improved by the following contributions: - Jonathan Nieder: Future-proof by always checking add_note() return value - Stephen Boyd: Use test_commit - Stephen Boyd: Use correct option name Thanks-to: Jonathan Nieder Thanks-to: Stephen Boyd Signed-off-by: Johan Herland Signed-off-by: Junio C Hamano --- notes-merge.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'notes-merge.c') diff --git a/notes-merge.c b/notes-merge.c index b1afb7e52c..2c0b25b369 100644 --- a/notes-merge.c +++ b/notes-merge.c @@ -263,6 +263,36 @@ static void diff_tree_local(struct notes_merge_options *o, diff_tree_release_paths(&opt); } +static int merge_one_change(struct notes_merge_options *o, + struct notes_merge_pair *p, struct notes_tree *t) +{ + /* + * Return 0 if change was resolved (and added to notes_tree), + * 1 if conflict + */ + switch (o->strategy) { + case NOTES_MERGE_RESOLVE_MANUAL: + return 1; + case NOTES_MERGE_RESOLVE_OURS: + OUTPUT(o, 2, "Using local notes for %s", sha1_to_hex(p->obj)); + /* nothing to do */ + return 0; + case NOTES_MERGE_RESOLVE_THEIRS: + OUTPUT(o, 2, "Using remote notes for %s", sha1_to_hex(p->obj)); + if (add_note(t, p->obj, p->remote, combine_notes_overwrite)) + die("BUG: combine_notes_overwrite failed"); + return 0; + case NOTES_MERGE_RESOLVE_UNION: + OUTPUT(o, 2, "Concatenating local and remote notes for %s", + sha1_to_hex(p->obj)); + if (add_note(t, p->obj, p->remote, combine_notes_concatenate)) + die("failed to concatenate notes " + "(combine_notes_concatenate)"); + return 0; + } + die("Unknown strategy (%i).", o->strategy); +} + static int merge_changes(struct notes_merge_options *o, struct notes_merge_pair *changes, int *num_changes, struct notes_tree *t) @@ -292,7 +322,7 @@ static int merge_changes(struct notes_merge_options *o, } else { /* need file-level merge between local and remote */ trace_printf("\t\t\tneed content-level merge\n"); - conflicts += 1; /* TODO */ + conflicts += merge_one_change(o, p, t); } } -- cgit v1.2.1