Skip to content

Commit fadd069

Browse files
committed
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 <a long object name> and <another long object name> 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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 5ad9dce commit fadd069

File tree

1 file changed

+21
-4
lines changed

1 file changed

+21
-4
lines changed

merge-recursive.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,18 @@ static int git_merge_trees(int index_only,
170170
int rc;
171171
struct tree_desc t[3];
172172
struct unpack_trees_options opts;
173+
static const struct unpack_trees_error_msgs msgs = {
174+
/* would_overwrite */
175+
"Your local changes to '%s' would be overwritten by merge. Aborting.",
176+
/* not_uptodate_file */
177+
"Your local changes to '%s' would be overwritten by merge. Aborting.",
178+
/* not_uptodate_dir */
179+
"Updating '%s' would lose untracked files in it. Aborting.",
180+
/* would_lose_untracked */
181+
"Untracked working tree file '%s' would be %s by merge. Aborting",
182+
/* bind_overlap -- will not happen here */
183+
NULL,
184+
};
173185

174186
memset(&opts, 0, sizeof(opts));
175187
if (index_only)
@@ -181,6 +193,7 @@ static int git_merge_trees(int index_only,
181193
opts.fn = threeway_merge;
182194
opts.src_index = &the_index;
183195
opts.dst_index = &the_index;
196+
opts.msgs = msgs;
184197

185198
init_tree_desc_from_tree(t+0, common);
186199
init_tree_desc_from_tree(t+1, head);
@@ -1188,10 +1201,14 @@ int merge_trees(struct merge_options *o,
11881201

11891202
code = git_merge_trees(o->call_depth, common, head, merge);
11901203

1191-
if (code != 0)
1192-
die("merging of trees %s and %s failed",
1193-
sha1_to_hex(head->object.sha1),
1194-
sha1_to_hex(merge->object.sha1));
1204+
if (code != 0) {
1205+
if (show(o, 4) || o->call_depth)
1206+
die("merging of trees %s and %s failed",
1207+
sha1_to_hex(head->object.sha1),
1208+
sha1_to_hex(merge->object.sha1));
1209+
else
1210+
exit(128);
1211+
}
11951212

11961213
if (unmerged_cache()) {
11971214
struct string_list *entries, *re_head, *re_merge;

0 commit comments

Comments
 (0)