diff options
Diffstat (limited to 'merge-recursive.c')
| -rw-r--r-- | merge-recursive.c | 61 |
1 files changed, 42 insertions, 19 deletions
diff --git a/merge-recursive.c b/merge-recursive.c index cc5fa0a949..0b690d4dcc 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -101,7 +101,7 @@ static struct commit *make_virtual_commit(struct tree *tree, const char *comment struct commit *commit = alloc_commit_node(); set_merge_remote_desc(commit, comment, (struct object *)commit); - commit->tree = tree; + commit->maybe_tree = tree; commit->object.parsed = 1; return commit; } @@ -228,7 +228,7 @@ static void output_commit_title(struct merge_options *o, struct commit *commit) strbuf_addf(&o->obuf, "virtual %s\n", merge_remote_util(commit)->name); else { - strbuf_add_unique_abbrev(&o->obuf, commit->object.oid.hash, + strbuf_add_unique_abbrev(&o->obuf, &commit->object.oid, DEFAULT_ABBREV); strbuf_addch(&o->obuf, ' '); if (parse_commit(commit) != 0) @@ -335,7 +335,7 @@ struct tree *write_tree_from_memory(struct merge_options *o) return result; } -static int save_files_dirs(const unsigned char *sha1, +static int save_files_dirs(const struct object_id *oid, struct strbuf *base, const char *path, unsigned int mode, int stage, void *context) { @@ -370,12 +370,12 @@ static struct stage_data *insert_stage_data(const char *path, { struct string_list_item *item; struct stage_data *e = xcalloc(1, sizeof(struct stage_data)); - get_tree_entry(o->object.oid.hash, path, - e->stages[1].oid.hash, &e->stages[1].mode); - get_tree_entry(a->object.oid.hash, path, - e->stages[2].oid.hash, &e->stages[2].mode); - get_tree_entry(b->object.oid.hash, path, - e->stages[3].oid.hash, &e->stages[3].mode); + get_tree_entry(&o->object.oid, path, + &e->stages[1].oid, &e->stages[1].mode); + get_tree_entry(&a->object.oid, path, + &e->stages[2].oid, &e->stages[2].mode); + get_tree_entry(&b->object.oid, path, + &e->stages[3].oid, &e->stages[3].mode); item = string_list_insert(entries, path); item->util = e; return e; @@ -513,6 +513,25 @@ static void record_df_conflict_files(struct merge_options *o, struct rename { struct diff_filepair *pair; + /* + * Purpose of src_entry and dst_entry: + * + * If 'before' is renamed to 'after' then src_entry will contain + * the versions of 'before' from the merge_base, HEAD, and MERGE in + * stages 1, 2, and 3; dst_entry will contain the respective + * versions of 'after' in corresponding locations. Thus, we have a + * total of six modes and oids, though some will be null. (Stage 0 + * is ignored; we're interested in handling conflicts.) + * + * Since we don't turn on break-rewrites by default, neither + * src_entry nor dst_entry can have all three of their stages have + * non-null oids, meaning at most four of the six will be non-null. + * Also, since this is a rename, both src_entry and dst_entry will + * have at least one non-null oid, meaning at least two will be + * non-null. Of the six oids, a typical rename will have three be + * non-null. Only two implies a rename/delete, and four implies a + * rename/add. + */ struct stage_data *src_entry; struct stage_data *dst_entry; unsigned processed:1; @@ -823,7 +842,7 @@ static int update_file_flags(struct merge_options *o, goto update_index; } - buf = read_sha1_file(oid->hash, &type, &size); + buf = read_object_file(oid, &type, &size); if (!buf) return err(o, _("cannot read object %s '%s'"), oid_to_hex(oid), path); if (type != OBJ_BLOB) { @@ -1009,8 +1028,9 @@ static int merge_file_1(struct merge_options *o, if ((merge_status < 0) || !result_buf.ptr) ret = err(o, _("Failed to execute internal merge")); - if (!ret && write_sha1_file(result_buf.ptr, result_buf.size, - blob_type, result->oid.hash)) + if (!ret && + write_object_file(result_buf.ptr, result_buf.size, + blob_type, &result->oid)) ret = err(o, _("Unable to add %s to database"), a->path); @@ -1636,7 +1656,7 @@ static int read_oid_strbuf(struct merge_options *o, void *buf; enum object_type type; unsigned long size; - buf = read_sha1_file(oid->hash, &type, &size); + buf = read_object_file(oid, &type, &size); if (!buf) return err(o, _("cannot read object %s"), oid_to_hex(oid)); if (type != OBJ_BLOB) { @@ -1998,10 +2018,10 @@ int merge_trees(struct merge_options *o, get_files_dirs(o, merge); entries = get_unmerged(); - record_df_conflict_files(o, entries); re_head = get_renames(o, head, common, head, merge, entries); re_merge = get_renames(o, merge, common, head, merge, entries); clean = process_renames(o, re_head, re_merge); + record_df_conflict_files(o, entries); if (clean < 0) goto cleanup; for (i = entries->nr-1; 0 <= i; i--) { @@ -2070,7 +2090,7 @@ int merge_recursive(struct merge_options *o, { struct commit_list *iter; struct commit *merged_common_ancestors; - struct tree *mrtree = mrtree; + struct tree *mrtree; int clean; if (show(o, 4)) { @@ -2134,7 +2154,8 @@ int merge_recursive(struct merge_options *o, read_cache(); o->ancestor = "merged common ancestors"; - clean = merge_trees(o, h1->tree, h2->tree, merged_common_ancestors->tree, + clean = merge_trees(o, get_commit_tree(h1), get_commit_tree(h2), + get_commit_tree(merged_common_ancestors), &mrtree); if (clean < 0) { flush_output(o); @@ -2198,11 +2219,13 @@ int merge_recursive_generic(struct merge_options *o, hold_locked_index(&lock, LOCK_DIE_ON_ERROR); clean = merge_recursive(o, head_commit, next_commit, ca, result); - if (clean < 0) + if (clean < 0) { + rollback_lock_file(&lock); return clean; + } - if (active_cache_changed && - write_locked_index(&the_index, &lock, COMMIT_LOCK)) + if (write_locked_index(&the_index, &lock, + COMMIT_LOCK | SKIP_IF_UNCHANGED)) return err(o, _("Unable to write index.")); return clean ? 0 : 1; |
