From fadd069d036c9d376769692e2726c5a1600d281c Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 7 Sep 2009 22:43:11 -0700 Subject: [PATCH] merge-recursive: give less scary messages when merge did not start When unpack_trees() three-way merge logic is called from merge-recursive and finds that local changes are going to be clobbered, its plumbing level messages were given as errors first, and then the merge driver added even more scary message "fatal: merging of trees and failed". This is most often encountered by new CVS/SVN migrants who are used to start a merge from a dirty work tree. The saddest part is that the merge refused to run to prevent _any_ damage from being done to your work tree when these messages are given, but the messages look a lot more scarier than the conflicted case where the user needs to resolve them. Replace the plumbing level messages so that they talk about what it is protecting the user from, and end the messages with "Aborting." so that it becomes clear that the command did not do any harm. The final "merging of trees failed" message is superfluous, unless you are interested in debugging the merge-recursive itself. Squelch the current die() message by default, but allow it to help people who debug git with verbosity level 4 or greater. Unless there is some bug, an inner merge that does not touch working tree should not trigger any such error, so emit the current die() message when we see an error return from it while running the inner merge, too. It would also help people who debug git. We could later add instructions on how to recover (i.e. "stash changes away or commit on a side branch and retry") instead of the silent exit(128) I have in this patch, and then use Peff's advice.* mechanism to squelch it (e.g. "advice.mergeindirtytree"), but they are separate topics. Tested-by: Nanako Shiraishi Signed-off-by: Junio C Hamano --- merge-recursive.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index 10d7913b0..f55b7ebe1 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -170,6 +170,18 @@ static int git_merge_trees(int index_only, int rc; struct tree_desc t[3]; struct unpack_trees_options opts; + static const struct unpack_trees_error_msgs msgs = { + /* would_overwrite */ + "Your local changes to '%s' would be overwritten by merge. Aborting.", + /* not_uptodate_file */ + "Your local changes to '%s' would be overwritten by merge. Aborting.", + /* not_uptodate_dir */ + "Updating '%s' would lose untracked files in it. Aborting.", + /* would_lose_untracked */ + "Untracked working tree file '%s' would be %s by merge. Aborting", + /* bind_overlap -- will not happen here */ + NULL, + }; memset(&opts, 0, sizeof(opts)); if (index_only) @@ -181,6 +193,7 @@ static int git_merge_trees(int index_only, opts.fn = threeway_merge; opts.src_index = &the_index; opts.dst_index = &the_index; + opts.msgs = msgs; init_tree_desc_from_tree(t+0, common); init_tree_desc_from_tree(t+1, head); @@ -1188,10 +1201,14 @@ int merge_trees(struct merge_options *o, code = git_merge_trees(o->call_depth, common, head, merge); - if (code != 0) - die("merging of trees %s and %s failed", - sha1_to_hex(head->object.sha1), - sha1_to_hex(merge->object.sha1)); + if (code != 0) { + if (show(o, 4) || o->call_depth) + die("merging of trees %s and %s failed", + sha1_to_hex(head->object.sha1), + sha1_to_hex(merge->object.sha1)); + else + exit(128); + } if (unmerged_cache()) { struct string_list *entries, *re_head, *re_merge; -- 2.26.2