diff options
Diffstat (limited to 'merge-recursive.c')
-rw-r--r-- | merge-recursive.c | 224 |
1 files changed, 115 insertions, 109 deletions
diff --git a/merge-recursive.c b/merge-recursive.c index cc664c39b6..f95933b0aa 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -38,16 +38,15 @@ static struct tree *shift_tree_object(struct tree *one, struct tree *two, return lookup_tree(shifted); } -/* - * A virtual commit has (const char *)commit->util set to the name. - */ - static struct commit *make_virtual_commit(struct tree *tree, const char *comment) { struct commit *commit = xcalloc(1, sizeof(struct commit)); + struct merge_remote_desc *desc = xmalloc(sizeof(*desc)); + + desc->name = comment; + desc->obj = (struct object *)commit; commit->tree = tree; - commit->util = (void*)comment; - /* avoid warnings */ + commit->util = desc; commit->object.parsed = 1; return commit; } @@ -184,11 +183,11 @@ static void output_commit_title(struct merge_options *o, struct commit *commit) for (i = o->call_depth; i--;) fputs(" ", stdout); if (commit->util) - printf("virtual %s\n", (char *)commit->util); + printf("virtual %s\n", merge_remote_util(commit)->name); else { printf("%s ", find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV)); if (parse_commit(commit) != 0) - printf("(bad commit)\n"); + printf(_("(bad commit)\n")); else { const char *title; int len = find_commit_subject(commit->buffer, &title); @@ -204,7 +203,7 @@ static int add_cacheinfo(unsigned int mode, const unsigned char *sha1, struct cache_entry *ce; ce = make_cache_entry(mode, sha1 ? sha1 : null_sha1, path, stage, refresh); if (!ce) - return error("addinfo_cache failed for path '%s'", path); + return error(_("addinfo_cache failed for path '%s'"), path); return add_cache_entry(ce, options); } @@ -252,7 +251,7 @@ struct tree *write_tree_from_memory(struct merge_options *o) int i; fprintf(stderr, "BUG: There are unmerged index entries:\n"); for (i = 0; i < active_nr; i++) { - struct cache_entry *ce = active_cache[i]; + const struct cache_entry *ce = active_cache[i]; if (ce_stage(ce)) fprintf(stderr, "BUG: %d %.*s\n", ce_stage(ce), (int)ce_namelen(ce), ce->name); @@ -265,8 +264,9 @@ struct tree *write_tree_from_memory(struct merge_options *o) if (!cache_tree_fully_valid(active_cache_tree) && cache_tree_update(active_cache_tree, - active_cache, active_nr, 0, 0) < 0) - die("error building trees"); + (const struct cache_entry * const *)active_cache, + active_nr, 0) < 0) + die(_("error building trees")); result = lookup_tree(active_cache_tree->sha1); @@ -340,7 +340,7 @@ static struct string_list *get_unmerged(void) for (i = 0; i < active_nr; i++) { struct string_list_item *item; struct stage_data *e; - struct cache_entry *ce = active_cache[i]; + const struct cache_entry *ce = active_cache[i]; if (!ce_stage(ce)) continue; @@ -486,6 +486,7 @@ static struct string_list *get_renames(struct merge_options *o, renames = xcalloc(1, sizeof(struct string_list)); diff_setup(&opts); DIFF_OPT_SET(&opts, RECURSIVE); + DIFF_OPT_CLR(&opts, RENAME_EMPTY); opts.detect_rename = DIFF_DETECT_RENAME; opts.rename_limit = o->merge_rename_limit >= 0 ? o->merge_rename_limit : o->diff_rename_limit >= 0 ? o->diff_rename_limit : @@ -493,8 +494,7 @@ static struct string_list *get_renames(struct merge_options *o, opts.rename_score = o->rename_score; opts.show_rename_progress = o->show_rename_progress; opts.output_format = DIFF_FORMAT_NO_OUTPUT; - if (diff_setup_done(&opts) < 0) - die("diff setup failed"); + diff_setup_done(&opts); diff_tree_sha1(o_tree->object.sha1, tree->object.sha1, "", &opts); diffcore_std(&opts); if (opts.needed_rename_limit > o->needed_rename_limit) @@ -614,23 +614,6 @@ static char *unique_path(struct merge_options *o, const char *path, const char * return newpath; } -static void flush_buffer(int fd, const char *buf, unsigned long size) -{ - while (size > 0) { - long ret = write_in_full(fd, buf, size); - if (ret < 0) { - /* Ignore epipe */ - if (errno == EPIPE) - break; - die_errno("merge-recursive"); - } else if (!ret) { - die("merge-recursive: disk full?"); - } - size -= ret; - buf += ret; - } -} - static int dir_in_way(const char *path, int check_working_copy) { int pos, pathlen = strlen(path); @@ -687,7 +670,7 @@ static int would_lose_untracked(const char *path) static int make_room_for_path(struct merge_options *o, const char *path) { int status, i; - const char *msg = "failed to create path '%s'%s"; + const char *msg = _("failed to create path '%s'%s"); /* Unlink any D/F conflict files that are in the way */ for (i = 0; i < o->df_conflict_file_set.nr; i++) { @@ -698,7 +681,7 @@ static int make_room_for_path(struct merge_options *o, const char *path) path[df_pathlen] == '/' && strncmp(path, df_path, df_pathlen) == 0) { output(o, 3, - "Removing %s to make room for subdirectory\n", + _("Removing %s to make room for subdirectory\n"), df_path); unlink(df_path); unsorted_string_list_delete_item(&o->df_conflict_file_set, @@ -712,7 +695,7 @@ static int make_room_for_path(struct merge_options *o, const char *path) if (status) { if (status == -3) { /* something else exists */ - error(msg, path, ": perhaps a D/F conflict?"); + error(msg, path, _(": perhaps a D/F conflict?")); return -1; } die(msg, path, ""); @@ -723,7 +706,7 @@ static int make_room_for_path(struct merge_options *o, const char *path) * tracking it. */ if (would_lose_untracked(path)) - return error("refusing to lose untracked file at '%s'", + return error(_("refusing to lose untracked file at '%s'"), path); /* Successful unlink is good.. */ @@ -733,7 +716,7 @@ static int make_room_for_path(struct merge_options *o, const char *path) if (errno == ENOENT) return 0; /* .. but not some other error (who really cares what?) */ - return error(msg, path, ": perhaps a D/F conflict?"); + return error(msg, path, _(": perhaps a D/F conflict?")); } static void update_file_flags(struct merge_options *o, @@ -763,9 +746,9 @@ static void update_file_flags(struct merge_options *o, buf = read_sha1_file(sha, &type, &size); if (!buf) - die("cannot read object %s '%s'", sha1_to_hex(sha), path); + die(_("cannot read object %s '%s'"), sha1_to_hex(sha), path); if (type != OBJ_BLOB) - die("blob expected for %s '%s'", sha1_to_hex(sha), path); + die(_("blob expected for %s '%s'"), sha1_to_hex(sha), path); if (S_ISREG(mode)) { struct strbuf strbuf = STRBUF_INIT; if (convert_to_working_tree(path, buf, size, &strbuf)) { @@ -788,18 +771,18 @@ static void update_file_flags(struct merge_options *o, mode = 0666; fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, mode); if (fd < 0) - die_errno("failed to open '%s'", path); - flush_buffer(fd, buf, size); + die_errno(_("failed to open '%s'"), path); + write_in_full(fd, buf, size); close(fd); } else if (S_ISLNK(mode)) { char *lnk = xmemdupz(buf, size); safe_create_leading_directories_const(path); unlink(path); if (symlink(lnk, path)) - die_errno("failed to symlink '%s'", path); + die_errno(_("failed to symlink '%s'"), path); free(lnk); } else - die("do not know what to do with %06o %s '%s'", + die(_("do not know what to do with %06o %s '%s'"), mode, sha1_to_hex(sha), path); free(buf); } @@ -862,14 +845,14 @@ static int merge_3way(struct merge_options *o, if (strcmp(a->path, b->path) || (o->ancestor != NULL && strcmp(a->path, one->path) != 0)) { base_name = o->ancestor == NULL ? NULL : - xstrdup(mkpath("%s:%s", o->ancestor, one->path)); - name1 = xstrdup(mkpath("%s:%s", branch1, a->path)); - name2 = xstrdup(mkpath("%s:%s", branch2, b->path)); + mkpathdup("%s:%s", o->ancestor, one->path); + name1 = mkpathdup("%s:%s", branch1, a->path); + name2 = mkpathdup("%s:%s", branch2, b->path); } else { base_name = o->ancestor == NULL ? NULL : - xstrdup(mkpath("%s", o->ancestor)); - name1 = xstrdup(mkpath("%s", branch1)); - name2 = xstrdup(mkpath("%s", branch2)); + mkpathdup("%s", o->ancestor); + name1 = mkpathdup("%s", branch1); + name2 = mkpathdup("%s", branch2); } read_mmblob(&orig, one->sha1); @@ -879,6 +862,7 @@ static int merge_3way(struct merge_options *o, merge_status = ll_merge(result_buf, a->path, &orig, base_name, &src1, name1, &src2, name2, &ll_opts); + free(base_name); free(name1); free(name2); free(orig.ptr); @@ -936,11 +920,11 @@ static struct merge_file_info merge_file_1(struct merge_options *o, branch1, branch2); if ((merge_status < 0) || !result_buf.ptr) - die("Failed to execute internal merge"); + die(_("Failed to execute internal merge")); if (write_sha1_file(result_buf.ptr, result_buf.size, blob_type, result.sha)) - die("Unable to add %s to database", + die(_("Unable to add %s to database"), a->path); free(result_buf.ptr); @@ -956,7 +940,7 @@ static struct merge_file_info merge_file_1(struct merge_options *o, if (!sha_eq(a->sha1, b->sha1)) result.clean = 0; } else { - die("unsupported object type in the tree"); + die(_("unsupported object type in the tree")); } } @@ -993,7 +977,7 @@ merge_file_special_markers(struct merge_options *o, return mfi; } -static struct merge_file_info merge_file(struct merge_options *o, +static struct merge_file_info merge_file_one(struct merge_options *o, const char *path, const unsigned char *o_sha, int o_mode, const unsigned char *a_sha, int a_mode, @@ -1034,22 +1018,32 @@ static void handle_change_delete(struct merge_options *o, remove_file_from_cache(path); update_file(o, 0, o_sha, o_mode, renamed ? renamed : path); } else if (!a_sha) { - output(o, 1, "CONFLICT (%s/delete): %s deleted in %s " - "and %s in %s. Version %s of %s left in tree%s%s.", - change, path, o->branch1, - change_past, o->branch2, o->branch2, path, - NULL == renamed ? "" : " at ", - NULL == renamed ? "" : renamed); - update_file(o, 0, b_sha, b_mode, renamed ? renamed : path); + if (!renamed) { + output(o, 1, _("CONFLICT (%s/delete): %s deleted in %s " + "and %s in %s. Version %s of %s left in tree."), + change, path, o->branch1, change_past, + o->branch2, o->branch2, path); + update_file(o, 0, b_sha, b_mode, path); + } else { + output(o, 1, _("CONFLICT (%s/delete): %s deleted in %s " + "and %s in %s. Version %s of %s left in tree at %s."), + change, path, o->branch1, change_past, + o->branch2, o->branch2, path, renamed); + update_file(o, 0, b_sha, b_mode, renamed); + } } else { - output(o, 1, "CONFLICT (%s/delete): %s deleted in %s " - "and %s in %s. Version %s of %s left in tree%s%s.", - change, path, o->branch2, - change_past, o->branch1, o->branch1, path, - NULL == renamed ? "" : " at ", - NULL == renamed ? "" : renamed); - if (renamed) + if (!renamed) { + output(o, 1, _("CONFLICT (%s/delete): %s deleted in %s " + "and %s in %s. Version %s of %s left in tree."), + change, path, o->branch2, change_past, + o->branch1, o->branch1, path); + } else { + output(o, 1, _("CONFLICT (%s/delete): %s deleted in %s " + "and %s in %s. Version %s of %s left in tree at %s."), + change, path, o->branch2, change_past, + o->branch1, o->branch1, path, renamed); update_file(o, 0, a_sha, a_mode, renamed); + } /* * No need to call update_file() on path when !renamed, since * that would needlessly touch path. We could call @@ -1085,7 +1079,7 @@ static void conflict_rename_delete(struct merge_options *o, orig->sha1, orig->mode, a_sha, a_mode, b_sha, b_mode, - "rename", "renamed"); + _("rename"), _("renamed")); if (o->call_depth) { remove_file_from_cache(dest->path); @@ -1141,7 +1135,7 @@ static void handle_file(struct merge_options *o, } else { if (dir_in_way(rename->path, !o->call_depth)) { dst_name = unique_path(o, rename->path, cur_branch); - output(o, 1, "%s is a directory in %s adding as %s instead", + output(o, 1, _("%s is a directory in %s adding as %s instead"), rename->path, other_branch, dst_name); } } @@ -1163,17 +1157,17 @@ static void conflict_rename_rename_1to2(struct merge_options *o, struct diff_filespec *a = ci->pair1->two; struct diff_filespec *b = ci->pair2->two; - output(o, 1, "CONFLICT (rename/rename): " + output(o, 1, _("CONFLICT (rename/rename): " "Rename \"%s\"->\"%s\" in branch \"%s\" " - "rename \"%s\"->\"%s\" in \"%s\"%s", + "rename \"%s\"->\"%s\" in \"%s\"%s"), one->path, a->path, ci->branch1, one->path, b->path, ci->branch2, - o->call_depth ? " (left unresolved)" : ""); + o->call_depth ? _(" (left unresolved)") : ""); if (o->call_depth) { struct merge_file_info mfi; struct diff_filespec other; struct diff_filespec *add; - mfi = merge_file(o, one->path, + mfi = merge_file_one(o, one->path, one->sha1, one->mode, a->sha1, a->mode, b->sha1, b->mode, @@ -1222,9 +1216,9 @@ static void conflict_rename_rename_2to1(struct merge_options *o, struct merge_file_info mfi_c1; struct merge_file_info mfi_c2; - output(o, 1, "CONFLICT (rename/rename): " + output(o, 1, _("CONFLICT (rename/rename): " "Rename %s->%s in %s. " - "Rename %s->%s in %s", + "Rename %s->%s in %s"), a->path, c1->path, ci->branch1, b->path, c2->path, ci->branch2); @@ -1252,7 +1246,7 @@ static void conflict_rename_rename_2to1(struct merge_options *o, } else { char *new_path1 = unique_path(o, path, ci->branch1); char *new_path2 = unique_path(o, path, ci->branch2); - output(o, 1, "Renaming %s to %s and %s to %s instead", + output(o, 1, _("Renaming %s to %s and %s to %s instead"), a->path, new_path1, b->path, new_path2); remove_file(o, 0, path, 0); update_file(o, 0, mfi_c1.sha, mfi_c1.mode, new_path1); @@ -1451,22 +1445,22 @@ static int process_renames(struct merge_options *o, } else if (!sha_eq(dst_other.sha1, null_sha1)) { clean_merge = 0; try_merge = 1; - output(o, 1, "CONFLICT (rename/add): Rename %s->%s in %s. " - "%s added in %s", + output(o, 1, _("CONFLICT (rename/add): Rename %s->%s in %s. " + "%s added in %s"), ren1_src, ren1_dst, branch1, ren1_dst, branch2); if (o->call_depth) { struct merge_file_info mfi; - mfi = merge_file(o, ren1_dst, null_sha1, 0, + mfi = merge_file_one(o, ren1_dst, null_sha1, 0, ren1->pair->two->sha1, ren1->pair->two->mode, dst_other.sha1, dst_other.mode, branch1, branch2); - output(o, 1, "Adding merged %s", ren1_dst); + output(o, 1, _("Adding merged %s"), ren1_dst); update_file(o, 0, mfi.sha, mfi.mode, ren1_dst); try_merge = 0; } else { char *new_path = unique_path(o, ren1_dst, branch2); - output(o, 1, "Adding as %s instead", new_path); + output(o, 1, _("Adding as %s instead"), new_path); update_file(o, 0, dst_other.sha1, dst_other.mode, new_path); free(new_path); } @@ -1517,10 +1511,10 @@ static int read_sha1_strbuf(const unsigned char *sha1, struct strbuf *dst) unsigned long size; buf = read_sha1_file(sha1, &type, &size); if (!buf) - return error("cannot read object %s", sha1_to_hex(sha1)); + return error(_("cannot read object %s"), sha1_to_hex(sha1)); if (type != OBJ_BLOB) { free(buf); - return error("object %s is not a blob", sha1_to_hex(sha1)); + return error(_("object %s is not a blob"), sha1_to_hex(sha1)); } strbuf_attach(dst, buf, size, size + 1); return 0; @@ -1568,7 +1562,7 @@ static void handle_modify_delete(struct merge_options *o, o_sha, o_mode, a_sha, a_mode, b_sha, b_mode, - "modify", "modified"); + _("modify"), _("modified")); } static int merge_content(struct merge_options *o, @@ -1578,14 +1572,14 @@ static int merge_content(struct merge_options *o, unsigned char *b_sha, int b_mode, struct rename_conflict_info *rename_conflict_info) { - const char *reason = "content"; + const char *reason = _("content"); const char *path1 = NULL, *path2 = NULL; struct merge_file_info mfi; struct diff_filespec one, a, b; unsigned df_conflict_remains = 0; if (!o_sha) { - reason = "add/add"; + reason = _("add/add"); o_sha = (unsigned char *)null_sha1; } one.path = a.path = b.path = (char *)path; @@ -1619,7 +1613,7 @@ static int merge_content(struct merge_options *o, if (mfi.clean && !df_conflict_remains && sha_eq(mfi.sha, a_sha) && mfi.mode == a_mode) { int path_renamed_outside_HEAD; - output(o, 3, "Skipped %s (merged same as existing)", path); + output(o, 3, _("Skipped %s (merged same as existing)"), path); /* * The content merge resulted in the same file contents we * already had. We can return early if those file contents @@ -1633,12 +1627,12 @@ static int merge_content(struct merge_options *o, return mfi.clean; } } else - output(o, 2, "Auto-merging %s", path); + output(o, 2, _("Auto-merging %s"), path); if (!mfi.clean) { if (S_ISGITLINK(mfi.mode)) - reason = "submodule"; - output(o, 1, "CONFLICT (%s): Merge conflict in %s", + reason = _("submodule"); + output(o, 1, _("CONFLICT (%s): Merge conflict in %s"), reason, path); if (rename_conflict_info && !df_conflict_remains) update_stages(path, &one, &a, &b); @@ -1664,7 +1658,7 @@ static int merge_content(struct merge_options *o, } new_path = unique_path(o, path, rename_conflict_info->branch1); - output(o, 1, "Adding as %s instead", new_path); + output(o, 1, _("Adding as %s instead"), new_path); update_file(o, 0, mfi.sha, mfi.mode, new_path); free(new_path); mfi.clean = 0; @@ -1728,7 +1722,7 @@ static int process_entry(struct merge_options *o, /* Deleted in both or deleted in one and * unchanged in the other */ if (a_sha) - output(o, 2, "Removing %s", path); + output(o, 2, _("Removing %s"), path); /* do not touch working file if it did not exist */ remove_file(o, 1, path, !a_sha); } else { @@ -1753,19 +1747,19 @@ static int process_entry(struct merge_options *o, other_branch = o->branch2; mode = a_mode; sha = a_sha; - conf = "file/directory"; + conf = _("file/directory"); } else { add_branch = o->branch2; other_branch = o->branch1; mode = b_mode; sha = b_sha; - conf = "directory/file"; + conf = _("directory/file"); } if (dir_in_way(path, !o->call_depth)) { char *new_path = unique_path(o, path, add_branch); clean_merge = 0; - output(o, 1, "CONFLICT (%s): There is a directory with name %s in %s. " - "Adding %s as %s", + output(o, 1, _("CONFLICT (%s): There is a directory with name %s in %s. " + "Adding %s as %s"), conf, path, other_branch, path, new_path); if (o->call_depth) remove_file_from_cache(path); @@ -1774,7 +1768,7 @@ static int process_entry(struct merge_options *o, remove_file_from_cache(path); free(new_path); } else { - output(o, 2, "Adding %s", path); + output(o, 2, _("Adding %s"), path); /* do not overwrite file if already present */ update_file_flags(o, sha, mode, path, 1, !a_sha); } @@ -1791,7 +1785,7 @@ static int process_entry(struct merge_options *o, */ remove_file(o, 1, path, !a_mode); } else - die("Fatal merge failure, shouldn't happen."); + die(_("Fatal merge failure, shouldn't happen.")); return clean_merge; } @@ -1810,7 +1804,7 @@ int merge_trees(struct merge_options *o, } if (sha_eq(common->object.sha1, merge->object.sha1)) { - output(o, 0, "Already up-to-date!"); + output(o, 0, _("Already up-to-date!")); *result = head; return 1; } @@ -1819,7 +1813,7 @@ int merge_trees(struct merge_options *o, if (code != 0) { if (show(o, 4) || o->call_depth) - die("merging of trees %s and %s failed", + die(_("merging of trees %s and %s failed"), sha1_to_hex(head->object.sha1), sha1_to_hex(merge->object.sha1)); else @@ -1849,7 +1843,7 @@ int merge_trees(struct merge_options *o, for (i = 0; i < entries->nr; i++) { struct stage_data *e = entries->items[i].util; if (!e->processed) - die("Unprocessed path??? %s", + die(_("Unprocessed path??? %s"), entries->items[i].string); } @@ -1894,7 +1888,7 @@ int merge_recursive(struct merge_options *o, int clean; if (show(o, 4)) { - output(o, 4, "Merging:"); + output(o, 4, _("Merging:")); output_commit_title(o, h1); output_commit_title(o, h2); } @@ -1905,7 +1899,10 @@ int merge_recursive(struct merge_options *o, } if (show(o, 5)) { - output(o, 5, "found %u common ancestor(s):", commit_list_count(ca)); + unsigned cnt = commit_list_count(ca); + + output(o, 5, Q_("found %u common ancestor:", + "found %u common ancestors:", cnt), cnt); for (iter = ca; iter; iter = iter->next) output_commit_title(o, iter->item); } @@ -1915,7 +1912,7 @@ int merge_recursive(struct merge_options *o, /* if there is no common ancestor, use an empty tree */ struct tree *tree; - tree = lookup_tree((const unsigned char *)EMPTY_TREE_SHA1_BIN); + tree = lookup_tree(EMPTY_TREE_SHA1_BIN); merged_common_ancestors = make_virtual_commit(tree, "ancestor"); } @@ -1941,7 +1938,7 @@ int merge_recursive(struct merge_options *o, o->call_depth--; if (!merged_common_ancestors) - die("merge returned no commit"); + die(_("merge returned no commit")); } discard_cache(); @@ -1998,7 +1995,7 @@ int merge_recursive_generic(struct merge_options *o, for (i = 0; i < num_base_list; ++i) { struct commit *base; if (!(base = get_ref(base_list[i], sha1_to_hex(base_list[i])))) - return error("Could not parse object '%s'", + return error(_("Could not parse object '%s'"), sha1_to_hex(base_list[i])); commit_list_insert(base, &ca); } @@ -2010,7 +2007,7 @@ int merge_recursive_generic(struct merge_options *o, if (active_cache_changed && (write_cache(index_fd, active_cache, active_nr) || commit_locked_index(lock))) - return error("Unable to write index."); + return error(_("Unable to write index.")); return clean ? 0 : 1; } @@ -2069,9 +2066,18 @@ int parse_merge_opt(struct merge_options *o, const char *s) else if (!prefixcmp(s, "subtree=")) o->subtree_shift = s + strlen("subtree="); else if (!strcmp(s, "patience")) - o->xdl_opts |= XDF_PATIENCE_DIFF; + o->xdl_opts = DIFF_WITH_ALG(o, PATIENCE_DIFF); else if (!strcmp(s, "histogram")) - o->xdl_opts |= XDF_HISTOGRAM_DIFF; + o->xdl_opts = DIFF_WITH_ALG(o, HISTOGRAM_DIFF); + else if (!strcmp(s, "diff-algorithm=")) { + long value = parse_algorithm_value(s+15); + if (value < 0) + return -1; + /* clear out previous settings */ + DIFF_XDL_CLR(o, NEED_MINIMAL); + o->xdl_opts &= ~XDF_DIFF_ALGORITHM_MASK; + o->xdl_opts |= value; + } else if (!strcmp(s, "ignore-space-change")) o->xdl_opts |= XDF_IGNORE_WHITESPACE_CHANGE; else if (!strcmp(s, "ignore-all-space")) |