|
|
|
@ -56,11 +56,11 @@ static struct commit *make_virtual_commit(struct tree *tree, const char *comment
@@ -56,11 +56,11 @@ static struct commit *make_virtual_commit(struct tree *tree, const char *comment
|
|
|
|
|
* Since we use get_tree_entry(), which does not put the read object into |
|
|
|
|
* the object pool, we cannot rely on a == b. |
|
|
|
|
*/ |
|
|
|
|
static int sha_eq(const unsigned char *a, const unsigned char *b) |
|
|
|
|
static int oid_eq(const struct object_id *a, const struct object_id *b) |
|
|
|
|
{ |
|
|
|
|
if (!a && !b) |
|
|
|
|
return 2; |
|
|
|
|
return a && b && hashcmp(a, b) == 0; |
|
|
|
|
return a && b && oidcmp(a, b) == 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
enum rename_type { |
|
|
|
@ -90,7 +90,7 @@ struct rename_conflict_info {
@@ -90,7 +90,7 @@ struct rename_conflict_info {
|
|
|
|
|
struct stage_data { |
|
|
|
|
struct { |
|
|
|
|
unsigned mode; |
|
|
|
|
unsigned char sha[20]; |
|
|
|
|
struct object_id oid; |
|
|
|
|
} stages[4]; |
|
|
|
|
struct rename_conflict_info *rename_conflict_info; |
|
|
|
|
unsigned processed:1; |
|
|
|
@ -134,11 +134,11 @@ static inline void setup_rename_conflict_info(enum rename_type rename_type,
@@ -134,11 +134,11 @@ static inline void setup_rename_conflict_info(enum rename_type rename_type,
|
|
|
|
|
int ostage2 = ostage1 ^ 1; |
|
|
|
|
|
|
|
|
|
ci->ren1_other.path = pair1->one->path; |
|
|
|
|
hashcpy(ci->ren1_other.sha1, src_entry1->stages[ostage1].sha); |
|
|
|
|
oidcpy(&ci->ren1_other.oid, &src_entry1->stages[ostage1].oid); |
|
|
|
|
ci->ren1_other.mode = src_entry1->stages[ostage1].mode; |
|
|
|
|
|
|
|
|
|
ci->ren2_other.path = pair2->one->path; |
|
|
|
|
hashcpy(ci->ren2_other.sha1, src_entry2->stages[ostage2].sha); |
|
|
|
|
oidcpy(&ci->ren2_other.oid, &src_entry2->stages[ostage2].oid); |
|
|
|
|
ci->ren2_other.mode = src_entry2->stages[ostage2].mode; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -198,11 +198,11 @@ static void output_commit_title(struct merge_options *o, struct commit *commit)
@@ -198,11 +198,11 @@ static void output_commit_title(struct merge_options *o, struct commit *commit)
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int add_cacheinfo(unsigned int mode, const unsigned char *sha1, |
|
|
|
|
static int add_cacheinfo(unsigned int mode, const struct object_id *oid, |
|
|
|
|
const char *path, int stage, int refresh, int options) |
|
|
|
|
{ |
|
|
|
|
struct cache_entry *ce; |
|
|
|
|
ce = make_cache_entry(mode, sha1 ? sha1 : null_sha1, path, stage, |
|
|
|
|
ce = make_cache_entry(mode, oid ? oid->hash : null_sha1, path, stage, |
|
|
|
|
(refresh ? (CE_MATCH_REFRESH | |
|
|
|
|
CE_MATCH_IGNORE_MISSING) : 0 )); |
|
|
|
|
if (!ce) |
|
|
|
@ -314,11 +314,11 @@ static struct stage_data *insert_stage_data(const char *path,
@@ -314,11 +314,11 @@ 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].sha, &e->stages[1].mode); |
|
|
|
|
e->stages[1].oid.hash, &e->stages[1].mode); |
|
|
|
|
get_tree_entry(a->object.oid.hash, path, |
|
|
|
|
e->stages[2].sha, &e->stages[2].mode); |
|
|
|
|
e->stages[2].oid.hash, &e->stages[2].mode); |
|
|
|
|
get_tree_entry(b->object.oid.hash, path, |
|
|
|
|
e->stages[3].sha, &e->stages[3].mode); |
|
|
|
|
e->stages[3].oid.hash, &e->stages[3].mode); |
|
|
|
|
item = string_list_insert(entries, path); |
|
|
|
|
item->util = e; |
|
|
|
|
return e; |
|
|
|
@ -349,7 +349,7 @@ static struct string_list *get_unmerged(void)
@@ -349,7 +349,7 @@ static struct string_list *get_unmerged(void)
|
|
|
|
|
} |
|
|
|
|
e = item->util; |
|
|
|
|
e->stages[ce_stage(ce)].mode = ce->ce_mode; |
|
|
|
|
hashcpy(e->stages[ce_stage(ce)].sha, ce->sha1); |
|
|
|
|
hashcpy(e->stages[ce_stage(ce)].oid.hash, ce->sha1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return unmerged; |
|
|
|
@ -552,13 +552,13 @@ static int update_stages(const char *path, const struct diff_filespec *o,
@@ -552,13 +552,13 @@ static int update_stages(const char *path, const struct diff_filespec *o,
|
|
|
|
|
if (remove_file_from_cache(path)) |
|
|
|
|
return -1; |
|
|
|
|
if (o) |
|
|
|
|
if (add_cacheinfo(o->mode, o->sha1, path, 1, 0, options)) |
|
|
|
|
if (add_cacheinfo(o->mode, &o->oid, path, 1, 0, options)) |
|
|
|
|
return -1; |
|
|
|
|
if (a) |
|
|
|
|
if (add_cacheinfo(a->mode, a->sha1, path, 2, 0, options)) |
|
|
|
|
if (add_cacheinfo(a->mode, &a->oid, path, 2, 0, options)) |
|
|
|
|
return -1; |
|
|
|
|
if (b) |
|
|
|
|
if (add_cacheinfo(b->mode, b->sha1, path, 3, 0, options)) |
|
|
|
|
if (add_cacheinfo(b->mode, &b->oid, path, 3, 0, options)) |
|
|
|
|
return -1; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
@ -572,9 +572,9 @@ static void update_entry(struct stage_data *entry,
@@ -572,9 +572,9 @@ static void update_entry(struct stage_data *entry,
|
|
|
|
|
entry->stages[1].mode = o->mode; |
|
|
|
|
entry->stages[2].mode = a->mode; |
|
|
|
|
entry->stages[3].mode = b->mode; |
|
|
|
|
hashcpy(entry->stages[1].sha, o->sha1); |
|
|
|
|
hashcpy(entry->stages[2].sha, a->sha1); |
|
|
|
|
hashcpy(entry->stages[3].sha, b->sha1); |
|
|
|
|
oidcpy(&entry->stages[1].oid, &o->oid); |
|
|
|
|
oidcpy(&entry->stages[2].oid, &a->oid); |
|
|
|
|
oidcpy(&entry->stages[3].oid, &b->oid); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int remove_file(struct merge_options *o, int clean, |
|
|
|
@ -736,7 +736,7 @@ static int make_room_for_path(struct merge_options *o, const char *path)
@@ -736,7 +736,7 @@ static int make_room_for_path(struct merge_options *o, const char *path)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void update_file_flags(struct merge_options *o, |
|
|
|
|
const unsigned char *sha, |
|
|
|
|
const struct object_id *oid, |
|
|
|
|
unsigned mode, |
|
|
|
|
const char *path, |
|
|
|
|
int update_cache, |
|
|
|
@ -760,11 +760,11 @@ static void update_file_flags(struct merge_options *o,
@@ -760,11 +760,11 @@ static void update_file_flags(struct merge_options *o,
|
|
|
|
|
goto update_index; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
buf = read_sha1_file(sha, &type, &size); |
|
|
|
|
buf = read_sha1_file(oid->hash, &type, &size); |
|
|
|
|
if (!buf) |
|
|
|
|
die(_("cannot read object %s '%s'"), sha1_to_hex(sha), path); |
|
|
|
|
die(_("cannot read object %s '%s'"), oid_to_hex(oid), path); |
|
|
|
|
if (type != OBJ_BLOB) |
|
|
|
|
die(_("blob expected for %s '%s'"), sha1_to_hex(sha), path); |
|
|
|
|
die(_("blob expected for %s '%s'"), oid_to_hex(oid), path); |
|
|
|
|
if (S_ISREG(mode)) { |
|
|
|
|
struct strbuf strbuf = STRBUF_INIT; |
|
|
|
|
if (convert_to_working_tree(path, buf, size, &strbuf)) { |
|
|
|
@ -799,27 +799,27 @@ static void update_file_flags(struct merge_options *o,
@@ -799,27 +799,27 @@ static void update_file_flags(struct merge_options *o,
|
|
|
|
|
free(lnk); |
|
|
|
|
} else |
|
|
|
|
die(_("do not know what to do with %06o %s '%s'"), |
|
|
|
|
mode, sha1_to_hex(sha), path); |
|
|
|
|
mode, oid_to_hex(oid), path); |
|
|
|
|
free(buf); |
|
|
|
|
} |
|
|
|
|
update_index: |
|
|
|
|
if (update_cache) |
|
|
|
|
add_cacheinfo(mode, sha, path, 0, update_wd, ADD_CACHE_OK_TO_ADD); |
|
|
|
|
add_cacheinfo(mode, oid, path, 0, update_wd, ADD_CACHE_OK_TO_ADD); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void update_file(struct merge_options *o, |
|
|
|
|
int clean, |
|
|
|
|
const unsigned char *sha, |
|
|
|
|
const struct object_id *oid, |
|
|
|
|
unsigned mode, |
|
|
|
|
const char *path) |
|
|
|
|
{ |
|
|
|
|
update_file_flags(o, sha, mode, path, o->call_depth || clean, !o->call_depth); |
|
|
|
|
update_file_flags(o, oid, mode, path, o->call_depth || clean, !o->call_depth); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Low level file merging, update and removal */ |
|
|
|
|
|
|
|
|
|
struct merge_file_info { |
|
|
|
|
unsigned char sha[20]; |
|
|
|
|
struct object_id oid; |
|
|
|
|
unsigned mode; |
|
|
|
|
unsigned clean:1, |
|
|
|
|
merge:1; |
|
|
|
@ -871,9 +871,9 @@ static int merge_3way(struct merge_options *o,
@@ -871,9 +871,9 @@ static int merge_3way(struct merge_options *o,
|
|
|
|
|
name2 = mkpathdup("%s", branch2); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
read_mmblob(&orig, one->sha1); |
|
|
|
|
read_mmblob(&src1, a->sha1); |
|
|
|
|
read_mmblob(&src2, b->sha1); |
|
|
|
|
read_mmblob(&orig, one->oid.hash); |
|
|
|
|
read_mmblob(&src1, a->oid.hash); |
|
|
|
|
read_mmblob(&src2, b->oid.hash); |
|
|
|
|
|
|
|
|
|
merge_status = ll_merge(result_buf, a->path, &orig, base_name, |
|
|
|
|
&src1, name1, &src2, name2, &ll_opts); |
|
|
|
@ -902,13 +902,13 @@ static struct merge_file_info merge_file_1(struct merge_options *o,
@@ -902,13 +902,13 @@ static struct merge_file_info merge_file_1(struct merge_options *o,
|
|
|
|
|
result.clean = 0; |
|
|
|
|
if (S_ISREG(a->mode)) { |
|
|
|
|
result.mode = a->mode; |
|
|
|
|
hashcpy(result.sha, a->sha1); |
|
|
|
|
oidcpy(&result.oid, &a->oid); |
|
|
|
|
} else { |
|
|
|
|
result.mode = b->mode; |
|
|
|
|
hashcpy(result.sha, b->sha1); |
|
|
|
|
oidcpy(&result.oid, &b->oid); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
if (!sha_eq(a->sha1, one->sha1) && !sha_eq(b->sha1, one->sha1)) |
|
|
|
|
if (!oid_eq(&a->oid, &one->oid) && !oid_eq(&b->oid, &one->oid)) |
|
|
|
|
result.merge = 1; |
|
|
|
|
|
|
|
|
|
/* |
|
|
|
@ -924,10 +924,10 @@ static struct merge_file_info merge_file_1(struct merge_options *o,
@@ -924,10 +924,10 @@ static struct merge_file_info merge_file_1(struct merge_options *o,
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (sha_eq(a->sha1, b->sha1) || sha_eq(a->sha1, one->sha1)) |
|
|
|
|
hashcpy(result.sha, b->sha1); |
|
|
|
|
else if (sha_eq(b->sha1, one->sha1)) |
|
|
|
|
hashcpy(result.sha, a->sha1); |
|
|
|
|
if (oid_eq(&a->oid, &b->oid) || oid_eq(&a->oid, &one->oid)) |
|
|
|
|
oidcpy(&result.oid, &b->oid); |
|
|
|
|
else if (oid_eq(&b->oid, &one->oid)) |
|
|
|
|
oidcpy(&result.oid, &a->oid); |
|
|
|
|
else if (S_ISREG(a->mode)) { |
|
|
|
|
mmbuffer_t result_buf; |
|
|
|
|
int merge_status; |
|
|
|
@ -939,21 +939,23 @@ static struct merge_file_info merge_file_1(struct merge_options *o,
@@ -939,21 +939,23 @@ static struct merge_file_info merge_file_1(struct merge_options *o,
|
|
|
|
|
die(_("Failed to execute internal merge")); |
|
|
|
|
|
|
|
|
|
if (write_sha1_file(result_buf.ptr, result_buf.size, |
|
|
|
|
blob_type, result.sha)) |
|
|
|
|
blob_type, result.oid.hash)) |
|
|
|
|
die(_("Unable to add %s to database"), |
|
|
|
|
a->path); |
|
|
|
|
|
|
|
|
|
free(result_buf.ptr); |
|
|
|
|
result.clean = (merge_status == 0); |
|
|
|
|
} else if (S_ISGITLINK(a->mode)) { |
|
|
|
|
result.clean = merge_submodule(result.sha, |
|
|
|
|
one->path, one->sha1, |
|
|
|
|
a->sha1, b->sha1, |
|
|
|
|
result.clean = merge_submodule(result.oid.hash, |
|
|
|
|
one->path, |
|
|
|
|
one->oid.hash, |
|
|
|
|
a->oid.hash, |
|
|
|
|
b->oid.hash, |
|
|
|
|
!o->call_depth); |
|
|
|
|
} else if (S_ISLNK(a->mode)) { |
|
|
|
|
hashcpy(result.sha, a->sha1); |
|
|
|
|
oidcpy(&result.oid, &a->oid); |
|
|
|
|
|
|
|
|
|
if (!sha_eq(a->sha1, b->sha1)) |
|
|
|
|
if (!oid_eq(&a->oid, &b->oid)) |
|
|
|
|
result.clean = 0; |
|
|
|
|
} else { |
|
|
|
|
die(_("unsupported object type in the tree")); |
|
|
|
@ -991,34 +993,34 @@ merge_file_special_markers(struct merge_options *o,
@@ -991,34 +993,34 @@ merge_file_special_markers(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, |
|
|
|
|
const unsigned char *b_sha, int b_mode, |
|
|
|
|
const struct object_id *o_oid, int o_mode, |
|
|
|
|
const struct object_id *a_oid, int a_mode, |
|
|
|
|
const struct object_id *b_oid, int b_mode, |
|
|
|
|
const char *branch1, |
|
|
|
|
const char *branch2) |
|
|
|
|
{ |
|
|
|
|
struct diff_filespec one, a, b; |
|
|
|
|
|
|
|
|
|
one.path = a.path = b.path = (char *)path; |
|
|
|
|
hashcpy(one.sha1, o_sha); |
|
|
|
|
oidcpy(&one.oid, o_oid); |
|
|
|
|
one.mode = o_mode; |
|
|
|
|
hashcpy(a.sha1, a_sha); |
|
|
|
|
oidcpy(&a.oid, a_oid); |
|
|
|
|
a.mode = a_mode; |
|
|
|
|
hashcpy(b.sha1, b_sha); |
|
|
|
|
oidcpy(&b.oid, b_oid); |
|
|
|
|
b.mode = b_mode; |
|
|
|
|
return merge_file_1(o, &one, &a, &b, branch1, branch2); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void handle_change_delete(struct merge_options *o, |
|
|
|
|
const char *path, |
|
|
|
|
const unsigned char *o_sha, int o_mode, |
|
|
|
|
const unsigned char *a_sha, int a_mode, |
|
|
|
|
const unsigned char *b_sha, int b_mode, |
|
|
|
|
const struct object_id *o_oid, int o_mode, |
|
|
|
|
const struct object_id *a_oid, int a_mode, |
|
|
|
|
const struct object_id *b_oid, int b_mode, |
|
|
|
|
const char *change, const char *change_past) |
|
|
|
|
{ |
|
|
|
|
char *renamed = NULL; |
|
|
|
|
if (dir_in_way(path, !o->call_depth)) { |
|
|
|
|
renamed = unique_path(o, path, a_sha ? o->branch1 : o->branch2); |
|
|
|
|
renamed = unique_path(o, path, a_oid ? o->branch1 : o->branch2); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (o->call_depth) { |
|
|
|
@ -1028,20 +1030,20 @@ static void handle_change_delete(struct merge_options *o,
@@ -1028,20 +1030,20 @@ static void handle_change_delete(struct merge_options *o,
|
|
|
|
|
* them, simply reuse the base version for virtual merge base. |
|
|
|
|
*/ |
|
|
|
|
remove_file_from_cache(path); |
|
|
|
|
update_file(o, 0, o_sha, o_mode, renamed ? renamed : path); |
|
|
|
|
} else if (!a_sha) { |
|
|
|
|
update_file(o, 0, o_oid, o_mode, renamed ? renamed : path); |
|
|
|
|
} else if (!a_oid) { |
|
|
|
|
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); |
|
|
|
|
update_file(o, 0, b_oid, 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); |
|
|
|
|
update_file(o, 0, b_oid, b_mode, renamed); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
if (!renamed) { |
|
|
|
@ -1054,7 +1056,7 @@ static void handle_change_delete(struct merge_options *o,
@@ -1054,7 +1056,7 @@ static void handle_change_delete(struct merge_options *o,
|
|
|
|
|
"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); |
|
|
|
|
update_file(o, 0, a_oid, a_mode, renamed); |
|
|
|
|
} |
|
|
|
|
/* |
|
|
|
|
* No need to call update_file() on path when !renamed, since |
|
|
|
@ -1073,24 +1075,24 @@ static void conflict_rename_delete(struct merge_options *o,
@@ -1073,24 +1075,24 @@ static void conflict_rename_delete(struct merge_options *o,
|
|
|
|
|
{ |
|
|
|
|
const struct diff_filespec *orig = pair->one; |
|
|
|
|
const struct diff_filespec *dest = pair->two; |
|
|
|
|
const unsigned char *a_sha = NULL; |
|
|
|
|
const unsigned char *b_sha = NULL; |
|
|
|
|
const struct object_id *a_oid = NULL; |
|
|
|
|
const struct object_id *b_oid = NULL; |
|
|
|
|
int a_mode = 0; |
|
|
|
|
int b_mode = 0; |
|
|
|
|
|
|
|
|
|
if (rename_branch == o->branch1) { |
|
|
|
|
a_sha = dest->sha1; |
|
|
|
|
a_oid = &dest->oid; |
|
|
|
|
a_mode = dest->mode; |
|
|
|
|
} else { |
|
|
|
|
b_sha = dest->sha1; |
|
|
|
|
b_oid = &dest->oid; |
|
|
|
|
b_mode = dest->mode; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
handle_change_delete(o, |
|
|
|
|
o->call_depth ? orig->path : dest->path, |
|
|
|
|
orig->sha1, orig->mode, |
|
|
|
|
a_sha, a_mode, |
|
|
|
|
b_sha, b_mode, |
|
|
|
|
&orig->oid, orig->mode, |
|
|
|
|
a_oid, a_mode, |
|
|
|
|
b_oid, b_mode, |
|
|
|
|
_("rename"), _("renamed")); |
|
|
|
|
|
|
|
|
|
if (o->call_depth) { |
|
|
|
@ -1107,11 +1109,11 @@ static struct diff_filespec *filespec_from_entry(struct diff_filespec *target,
@@ -1107,11 +1109,11 @@ static struct diff_filespec *filespec_from_entry(struct diff_filespec *target,
|
|
|
|
|
struct stage_data *entry, |
|
|
|
|
int stage) |
|
|
|
|
{ |
|
|
|
|
unsigned char *sha = entry->stages[stage].sha; |
|
|
|
|
struct object_id *oid = &entry->stages[stage].oid; |
|
|
|
|
unsigned mode = entry->stages[stage].mode; |
|
|
|
|
if (mode == 0 || is_null_sha1(sha)) |
|
|
|
|
if (mode == 0 || is_null_oid(oid)) |
|
|
|
|
return NULL; |
|
|
|
|
hashcpy(target->sha1, sha); |
|
|
|
|
oidcpy(&target->oid, oid); |
|
|
|
|
target->mode = mode; |
|
|
|
|
return target; |
|
|
|
|
} |
|
|
|
@ -1140,7 +1142,7 @@ static void handle_file(struct merge_options *o,
@@ -1140,7 +1142,7 @@ static void handle_file(struct merge_options *o,
|
|
|
|
|
add = filespec_from_entry(&other, dst_entry, stage ^ 1); |
|
|
|
|
if (add) { |
|
|
|
|
char *add_name = unique_path(o, rename->path, other_branch); |
|
|
|
|
update_file(o, 0, add->sha1, add->mode, add_name); |
|
|
|
|
update_file(o, 0, &add->oid, add->mode, add_name); |
|
|
|
|
|
|
|
|
|
remove_file(o, 0, rename->path, 0); |
|
|
|
|
dst_name = unique_path(o, rename->path, cur_branch); |
|
|
|
@ -1151,7 +1153,7 @@ static void handle_file(struct merge_options *o,
@@ -1151,7 +1153,7 @@ static void handle_file(struct merge_options *o,
|
|
|
|
|
rename->path, other_branch, dst_name); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
update_file(o, 0, rename->sha1, rename->mode, dst_name); |
|
|
|
|
update_file(o, 0, &rename->oid, rename->mode, dst_name); |
|
|
|
|
if (stage == 2) |
|
|
|
|
update_stages(rename->path, NULL, rename, add); |
|
|
|
|
else |
|
|
|
@ -1180,9 +1182,9 @@ static void conflict_rename_rename_1to2(struct merge_options *o,
@@ -1180,9 +1182,9 @@ static void conflict_rename_rename_1to2(struct merge_options *o,
|
|
|
|
|
struct diff_filespec other; |
|
|
|
|
struct diff_filespec *add; |
|
|
|
|
mfi = merge_file_one(o, one->path, |
|
|
|
|
one->sha1, one->mode, |
|
|
|
|
a->sha1, a->mode, |
|
|
|
|
b->sha1, b->mode, |
|
|
|
|
&one->oid, one->mode, |
|
|
|
|
&a->oid, a->mode, |
|
|
|
|
&b->oid, b->mode, |
|
|
|
|
ci->branch1, ci->branch2); |
|
|
|
|
/* |
|
|
|
|
* FIXME: For rename/add-source conflicts (if we could detect |
|
|
|
@ -1190,7 +1192,7 @@ static void conflict_rename_rename_1to2(struct merge_options *o,
@@ -1190,7 +1192,7 @@ static void conflict_rename_rename_1to2(struct merge_options *o,
|
|
|
|
|
* pathname and then either rename the add-source file to that |
|
|
|
|
* unique path, or use that unique path instead of src here. |
|
|
|
|
*/ |
|
|
|
|
update_file(o, 0, mfi.sha, mfi.mode, one->path); |
|
|
|
|
update_file(o, 0, &mfi.oid, mfi.mode, one->path); |
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
* Above, we put the merged content at the merge-base's |
|
|
|
@ -1202,12 +1204,12 @@ static void conflict_rename_rename_1to2(struct merge_options *o,
@@ -1202,12 +1204,12 @@ static void conflict_rename_rename_1to2(struct merge_options *o,
|
|
|
|
|
*/ |
|
|
|
|
add = filespec_from_entry(&other, ci->dst_entry1, 2 ^ 1); |
|
|
|
|
if (add) |
|
|
|
|
update_file(o, 0, add->sha1, add->mode, a->path); |
|
|
|
|
update_file(o, 0, &add->oid, add->mode, a->path); |
|
|
|
|
else |
|
|
|
|
remove_file_from_cache(a->path); |
|
|
|
|
add = filespec_from_entry(&other, ci->dst_entry2, 3 ^ 1); |
|
|
|
|
if (add) |
|
|
|
|
update_file(o, 0, add->sha1, add->mode, b->path); |
|
|
|
|
update_file(o, 0, &add->oid, add->mode, b->path); |
|
|
|
|
else |
|
|
|
|
remove_file_from_cache(b->path); |
|
|
|
|
} else { |
|
|
|
@ -1253,16 +1255,16 @@ static void conflict_rename_rename_2to1(struct merge_options *o,
@@ -1253,16 +1255,16 @@ static void conflict_rename_rename_2to1(struct merge_options *o,
|
|
|
|
|
* again later for the non-recursive merge. |
|
|
|
|
*/ |
|
|
|
|
remove_file(o, 0, path, 0); |
|
|
|
|
update_file(o, 0, mfi_c1.sha, mfi_c1.mode, a->path); |
|
|
|
|
update_file(o, 0, mfi_c2.sha, mfi_c2.mode, b->path); |
|
|
|
|
update_file(o, 0, &mfi_c1.oid, mfi_c1.mode, a->path); |
|
|
|
|
update_file(o, 0, &mfi_c2.oid, mfi_c2.mode, b->path); |
|
|
|
|
} 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"), |
|
|
|
|
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); |
|
|
|
|
update_file(o, 0, mfi_c2.sha, mfi_c2.mode, new_path2); |
|
|
|
|
update_file(o, 0, &mfi_c1.oid, mfi_c1.mode, new_path1); |
|
|
|
|
update_file(o, 0, &mfi_c2.oid, mfi_c2.mode, new_path2); |
|
|
|
|
free(new_path2); |
|
|
|
|
free(new_path1); |
|
|
|
|
} |
|
|
|
@ -1421,13 +1423,15 @@ static int process_renames(struct merge_options *o,
@@ -1421,13 +1423,15 @@ static int process_renames(struct merge_options *o,
|
|
|
|
|
remove_file(o, 1, ren1_src, |
|
|
|
|
renamed_stage == 2 || !was_tracked(ren1_src)); |
|
|
|
|
|
|
|
|
|
hashcpy(src_other.sha1, ren1->src_entry->stages[other_stage].sha); |
|
|
|
|
oidcpy(&src_other.oid, |
|
|
|
|
&ren1->src_entry->stages[other_stage].oid); |
|
|
|
|
src_other.mode = ren1->src_entry->stages[other_stage].mode; |
|
|
|
|
hashcpy(dst_other.sha1, ren1->dst_entry->stages[other_stage].sha); |
|
|
|
|
oidcpy(&dst_other.oid, |
|
|
|
|
&ren1->dst_entry->stages[other_stage].oid); |
|
|
|
|
dst_other.mode = ren1->dst_entry->stages[other_stage].mode; |
|
|
|
|
try_merge = 0; |
|
|
|
|
|
|
|
|
|
if (sha_eq(src_other.sha1, null_sha1)) { |
|
|
|
|
if (oid_eq(&src_other.oid, &null_oid)) { |
|
|
|
|
setup_rename_conflict_info(RENAME_DELETE, |
|
|
|
|
ren1->pair, |
|
|
|
|
NULL, |
|
|
|
@ -1439,7 +1443,7 @@ static int process_renames(struct merge_options *o,
@@ -1439,7 +1443,7 @@ static int process_renames(struct merge_options *o,
|
|
|
|
|
NULL, |
|
|
|
|
NULL); |
|
|
|
|
} else if ((dst_other.mode == ren1->pair->two->mode) && |
|
|
|
|
sha_eq(dst_other.sha1, ren1->pair->two->sha1)) { |
|
|
|
|
oid_eq(&dst_other.oid, &ren1->pair->two->oid)) { |
|
|
|
|
/* |
|
|
|
|
* Added file on the other side identical to |
|
|
|
|
* the file being renamed: clean merge. |
|
|
|
@ -1449,12 +1453,12 @@ static int process_renames(struct merge_options *o,
@@ -1449,12 +1453,12 @@ static int process_renames(struct merge_options *o,
|
|
|
|
|
* update_file(). |
|
|
|
|
*/ |
|
|
|
|
update_file_flags(o, |
|
|
|
|
ren1->pair->two->sha1, |
|
|
|
|
&ren1->pair->two->oid, |
|
|
|
|
ren1->pair->two->mode, |
|
|
|
|
ren1_dst, |
|
|
|
|
1, /* update_cache */ |
|
|
|
|
0 /* update_wd */); |
|
|
|
|
} else if (!sha_eq(dst_other.sha1, null_sha1)) { |
|
|
|
|
} else if (!oid_eq(&dst_other.oid, &null_oid)) { |
|
|
|
|
clean_merge = 0; |
|
|
|
|
try_merge = 1; |
|
|
|
|
output(o, 1, _("CONFLICT (rename/add): Rename %s->%s in %s. " |
|
|
|
@ -1463,17 +1467,21 @@ static int process_renames(struct merge_options *o,
@@ -1463,17 +1467,21 @@ static int process_renames(struct merge_options *o,
|
|
|
|
|
ren1_dst, branch2); |
|
|
|
|
if (o->call_depth) { |
|
|
|
|
struct merge_file_info mfi; |
|
|
|
|
mfi = merge_file_one(o, ren1_dst, null_sha1, 0, |
|
|
|
|
ren1->pair->two->sha1, ren1->pair->two->mode, |
|
|
|
|
dst_other.sha1, dst_other.mode, |
|
|
|
|
mfi = merge_file_one(o, ren1_dst, &null_oid, 0, |
|
|
|
|
&ren1->pair->two->oid, |
|
|
|
|
ren1->pair->two->mode, |
|
|
|
|
&dst_other.oid, |
|
|
|
|
dst_other.mode, |
|
|
|
|
branch1, branch2); |
|
|
|
|
output(o, 1, _("Adding merged %s"), ren1_dst); |
|
|
|
|
update_file(o, 0, mfi.sha, mfi.mode, ren1_dst); |
|
|
|
|
update_file(o, 0, &mfi.oid, |
|
|
|
|
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); |
|
|
|
|
update_file(o, 0, dst_other.sha1, dst_other.mode, new_path); |
|
|
|
|
update_file(o, 0, &dst_other.oid, |
|
|
|
|
dst_other.mode, new_path); |
|
|
|
|
free(new_path); |
|
|
|
|
} |
|
|
|
|
} else |
|
|
|
@ -1511,30 +1519,30 @@ static int process_renames(struct merge_options *o,
@@ -1511,30 +1519,30 @@ static int process_renames(struct merge_options *o,
|
|
|
|
|
return clean_merge; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static unsigned char *stage_sha(const unsigned char *sha, unsigned mode) |
|
|
|
|
static struct object_id *stage_oid(const struct object_id *oid, unsigned mode) |
|
|
|
|
{ |
|
|
|
|
return (is_null_sha1(sha) || mode == 0) ? NULL: (unsigned char *)sha; |
|
|
|
|
return (is_null_oid(oid) || mode == 0) ? NULL: (struct object_id *)oid; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int read_sha1_strbuf(const unsigned char *sha1, struct strbuf *dst) |
|
|
|
|
static int read_oid_strbuf(const struct object_id *oid, struct strbuf *dst) |
|
|
|
|
{ |
|
|
|
|
void *buf; |
|
|
|
|
enum object_type type; |
|
|
|
|
unsigned long size; |
|
|
|
|
buf = read_sha1_file(sha1, &type, &size); |
|
|
|
|
buf = read_sha1_file(oid->hash, &type, &size); |
|
|
|
|
if (!buf) |
|
|
|
|
return error(_("cannot read object %s"), sha1_to_hex(sha1)); |
|
|
|
|
return error(_("cannot read object %s"), oid_to_hex(oid)); |
|
|
|
|
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"), oid_to_hex(oid)); |
|
|
|
|
} |
|
|
|
|
strbuf_attach(dst, buf, size, size + 1); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int blob_unchanged(const unsigned char *o_sha, |
|
|
|
|
static int blob_unchanged(const struct object_id *o_oid, |
|
|
|
|
unsigned o_mode, |
|
|
|
|
const unsigned char *a_sha, |
|
|
|
|
const struct object_id *a_oid, |
|
|
|
|
unsigned a_mode, |
|
|
|
|
int renormalize, const char *path) |
|
|
|
|
{ |
|
|
|
@ -1544,13 +1552,13 @@ static int blob_unchanged(const unsigned char *o_sha,
@@ -1544,13 +1552,13 @@ static int blob_unchanged(const unsigned char *o_sha,
|
|
|
|
|
|
|
|
|
|
if (a_mode != o_mode) |
|
|
|
|
return 0; |
|
|
|
|
if (sha_eq(o_sha, a_sha)) |
|
|
|
|
if (oid_eq(o_oid, a_oid)) |
|
|
|
|
return 1; |
|
|
|
|
if (!renormalize) |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
assert(o_sha && a_sha); |
|
|
|
|
if (read_sha1_strbuf(o_sha, &o) || read_sha1_strbuf(a_sha, &a)) |
|
|
|
|
assert(o_oid && a_oid); |
|
|
|
|
if (read_oid_strbuf(o_oid, &o) || read_oid_strbuf(a_oid, &a)) |
|
|
|
|
goto error_return; |
|
|
|
|
/* |
|
|
|
|
* Note: binary | is used so that both renormalizations are |
|
|
|
@ -1569,23 +1577,23 @@ error_return:
@@ -1569,23 +1577,23 @@ error_return:
|
|
|
|
|
|
|
|
|
|
static void handle_modify_delete(struct merge_options *o, |
|
|
|
|
const char *path, |
|
|
|
|
unsigned char *o_sha, int o_mode, |
|
|
|
|
unsigned char *a_sha, int a_mode, |
|
|
|
|
unsigned char *b_sha, int b_mode) |
|
|
|
|
struct object_id *o_oid, int o_mode, |
|
|
|
|
struct object_id *a_oid, int a_mode, |
|
|
|
|
struct object_id *b_oid, int b_mode) |
|
|
|
|
{ |
|
|
|
|
handle_change_delete(o, |
|
|
|
|
path, |
|
|
|
|
o_sha, o_mode, |
|
|
|
|
a_sha, a_mode, |
|
|
|
|
b_sha, b_mode, |
|
|
|
|
o_oid, o_mode, |
|
|
|
|
a_oid, a_mode, |
|
|
|
|
b_oid, b_mode, |
|
|
|
|
_("modify"), _("modified")); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int merge_content(struct merge_options *o, |
|
|
|
|
const char *path, |
|
|
|
|
unsigned char *o_sha, int o_mode, |
|
|
|
|
unsigned char *a_sha, int a_mode, |
|
|
|
|
unsigned char *b_sha, int b_mode, |
|
|
|
|
struct object_id *o_oid, int o_mode, |
|
|
|
|
struct object_id *a_oid, int a_mode, |
|
|
|
|
struct object_id *b_oid, int b_mode, |
|
|
|
|
struct rename_conflict_info *rename_conflict_info) |
|
|
|
|
{ |
|
|
|
|
const char *reason = _("content"); |
|
|
|
@ -1594,16 +1602,16 @@ static int merge_content(struct merge_options *o,
@@ -1594,16 +1602,16 @@ static int merge_content(struct merge_options *o,
|
|
|
|
|
struct diff_filespec one, a, b; |
|
|
|
|
unsigned df_conflict_remains = 0; |
|
|
|
|
|
|
|
|
|
if (!o_sha) { |
|
|
|
|
if (!o_oid) { |
|
|
|
|
reason = _("add/add"); |
|
|
|
|
o_sha = (unsigned char *)null_sha1; |
|
|
|
|
o_oid = (struct object_id *)&null_oid; |
|
|
|
|
} |
|
|
|
|
one.path = a.path = b.path = (char *)path; |
|
|
|
|
hashcpy(one.sha1, o_sha); |
|
|
|
|
oidcpy(&one.oid, o_oid); |
|
|
|
|
one.mode = o_mode; |
|
|
|
|
hashcpy(a.sha1, a_sha); |
|
|
|
|
oidcpy(&a.oid, a_oid); |
|
|
|
|
a.mode = a_mode; |
|
|
|
|
hashcpy(b.sha1, b_sha); |
|
|
|
|
oidcpy(&b.oid, b_oid); |
|
|
|
|
b.mode = b_mode; |
|
|
|
|
|
|
|
|
|
if (rename_conflict_info) { |
|
|
|
@ -1627,7 +1635,7 @@ static int merge_content(struct merge_options *o,
@@ -1627,7 +1635,7 @@ static int merge_content(struct merge_options *o,
|
|
|
|
|
o->branch2, path2); |
|
|
|
|
|
|
|
|
|
if (mfi.clean && !df_conflict_remains && |
|
|
|
|
sha_eq(mfi.sha, a_sha) && mfi.mode == a_mode) { |
|
|
|
|
oid_eq(&mfi.oid, a_oid) && mfi.mode == a_mode) { |
|
|
|
|
int path_renamed_outside_HEAD; |
|
|
|
|
output(o, 3, _("Skipped %s (merged same as existing)"), path); |
|
|
|
|
/* |
|
|
|
@ -1638,7 +1646,7 @@ static int merge_content(struct merge_options *o,
@@ -1638,7 +1646,7 @@ static int merge_content(struct merge_options *o,
|
|
|
|
|
*/ |
|
|
|
|
path_renamed_outside_HEAD = !path2 || !strcmp(path, path2); |
|
|
|
|
if (!path_renamed_outside_HEAD) { |
|
|
|
|
add_cacheinfo(mfi.mode, mfi.sha, path, |
|
|
|
|
add_cacheinfo(mfi.mode, &mfi.oid, path, |
|
|
|
|
0, (!o->call_depth), 0); |
|
|
|
|
return mfi.clean; |
|
|
|
|
} |
|
|
|
@ -1664,7 +1672,7 @@ static int merge_content(struct merge_options *o,
@@ -1664,7 +1672,7 @@ static int merge_content(struct merge_options *o,
|
|
|
|
|
else { |
|
|
|
|
int file_from_stage2 = was_tracked(path); |
|
|
|
|
struct diff_filespec merged; |
|
|
|
|
hashcpy(merged.sha1, mfi.sha); |
|
|
|
|
oidcpy(&merged.oid, &mfi.oid); |
|
|
|
|
merged.mode = mfi.mode; |
|
|
|
|
|
|
|
|
|
update_stages(path, NULL, |
|
|
|
@ -1675,11 +1683,11 @@ static int merge_content(struct merge_options *o,
@@ -1675,11 +1683,11 @@ 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); |
|
|
|
|
update_file(o, 0, mfi.sha, mfi.mode, new_path); |
|
|
|
|
update_file(o, 0, &mfi.oid, mfi.mode, new_path); |
|
|
|
|
free(new_path); |
|
|
|
|
mfi.clean = 0; |
|
|
|
|
} else { |
|
|
|
|
update_file(o, mfi.clean, mfi.sha, mfi.mode, path); |
|
|
|
|
update_file(o, mfi.clean, &mfi.oid, mfi.mode, path); |
|
|
|
|
} |
|
|
|
|
return mfi.clean; |
|
|
|
|
|
|
|
|
@ -1694,9 +1702,9 @@ static int process_entry(struct merge_options *o,
@@ -1694,9 +1702,9 @@ static int process_entry(struct merge_options *o,
|
|
|
|
|
unsigned o_mode = entry->stages[1].mode; |
|
|
|
|
unsigned a_mode = entry->stages[2].mode; |
|
|
|
|
unsigned b_mode = entry->stages[3].mode; |
|
|
|
|
unsigned char *o_sha = stage_sha(entry->stages[1].sha, o_mode); |
|
|
|
|
unsigned char *a_sha = stage_sha(entry->stages[2].sha, a_mode); |
|
|
|
|
unsigned char *b_sha = stage_sha(entry->stages[3].sha, b_mode); |
|
|
|
|
struct object_id *o_oid = stage_oid(&entry->stages[1].oid, o_mode); |
|
|
|
|
struct object_id *a_oid = stage_oid(&entry->stages[2].oid, a_mode); |
|
|
|
|
struct object_id *b_oid = stage_oid(&entry->stages[3].oid, b_mode); |
|
|
|
|
|
|
|
|
|
entry->processed = 1; |
|
|
|
|
if (entry->rename_conflict_info) { |
|
|
|
@ -1705,7 +1713,7 @@ static int process_entry(struct merge_options *o,
@@ -1705,7 +1713,7 @@ static int process_entry(struct merge_options *o,
|
|
|
|
|
case RENAME_NORMAL: |
|
|
|
|
case RENAME_ONE_FILE_TO_ONE: |
|
|
|
|
clean_merge = merge_content(o, path, |
|
|
|
|
o_sha, o_mode, a_sha, a_mode, b_sha, b_mode, |
|
|
|
|
o_oid, o_mode, a_oid, a_mode, b_oid, b_mode, |
|
|
|
|
conflict_info); |
|
|
|
|
break; |
|
|
|
|
case RENAME_DELETE: |
|
|
|
@ -1726,45 +1734,45 @@ static int process_entry(struct merge_options *o,
@@ -1726,45 +1734,45 @@ static int process_entry(struct merge_options *o,
|
|
|
|
|
entry->processed = 0; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} else if (o_sha && (!a_sha || !b_sha)) { |
|
|
|
|
} else if (o_oid && (!a_oid || !b_oid)) { |
|
|
|
|
/* Case A: Deleted in one */ |
|
|
|
|
if ((!a_sha && !b_sha) || |
|
|
|
|
(!b_sha && blob_unchanged(o_sha, o_mode, a_sha, a_mode, normalize, path)) || |
|
|
|
|
(!a_sha && blob_unchanged(o_sha, o_mode, b_sha, b_mode, normalize, path))) { |
|
|
|
|
if ((!a_oid && !b_oid) || |
|
|
|
|
(!b_oid && blob_unchanged(o_oid, o_mode, a_oid, a_mode, normalize, path)) || |
|
|
|
|
(!a_oid && blob_unchanged(o_oid, o_mode, b_oid, b_mode, normalize, path))) { |
|
|
|
|
/* Deleted in both or deleted in one and |
|
|
|
|
* unchanged in the other */ |
|
|
|
|
if (a_sha) |
|
|
|
|
if (a_oid) |
|
|
|
|
output(o, 2, _("Removing %s"), path); |
|
|
|
|
/* do not touch working file if it did not exist */ |
|
|
|
|
remove_file(o, 1, path, !a_sha); |
|
|
|
|
remove_file(o, 1, path, !a_oid); |
|
|
|
|
} else { |
|
|
|
|
/* Modify/delete; deleted side may have put a directory in the way */ |
|
|
|
|
clean_merge = 0; |
|
|
|
|
handle_modify_delete(o, path, o_sha, o_mode, |
|
|
|
|
a_sha, a_mode, b_sha, b_mode); |
|
|
|
|
handle_modify_delete(o, path, o_oid, o_mode, |
|
|
|
|
a_oid, a_mode, b_oid, b_mode); |
|
|
|
|
} |
|
|
|
|
} else if ((!o_sha && a_sha && !b_sha) || |
|
|
|
|
(!o_sha && !a_sha && b_sha)) { |
|
|
|
|
} else if ((!o_oid && a_oid && !b_oid) || |
|
|
|
|
(!o_oid && !a_oid && b_oid)) { |
|
|
|
|
/* Case B: Added in one. */ |
|
|
|
|
/* [nothing|directory] -> ([nothing|directory], file) */ |
|
|
|
|
|
|
|
|
|
const char *add_branch; |
|
|
|
|
const char *other_branch; |
|
|
|
|
unsigned mode; |
|
|
|
|
const unsigned char *sha; |
|
|
|
|
const struct object_id *oid; |
|
|
|
|
const char *conf; |
|
|
|
|
|
|
|
|
|
if (a_sha) { |
|
|
|
|
if (a_oid) { |
|
|
|
|
add_branch = o->branch1; |
|
|
|
|
other_branch = o->branch2; |
|
|
|
|
mode = a_mode; |
|
|
|
|
sha = a_sha; |
|
|
|
|
oid = a_oid; |
|
|
|
|
conf = _("file/directory"); |
|
|
|
|
} else { |
|
|
|
|
add_branch = o->branch2; |
|
|
|
|
other_branch = o->branch1; |
|
|
|
|
mode = b_mode; |
|
|
|
|
sha = b_sha; |
|
|
|
|
oid = b_oid; |
|
|
|
|
conf = _("directory/file"); |
|
|
|
|
} |
|
|
|
|
if (dir_in_way(path, !o->call_depth)) { |
|
|
|
@ -1773,22 +1781,22 @@ static int process_entry(struct merge_options *o,
@@ -1773,22 +1781,22 @@ static int process_entry(struct merge_options *o,
|
|
|
|
|
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); |
|
|
|
|
update_file(o, 0, sha, mode, new_path); |
|
|
|
|
update_file(o, 0, oid, mode, new_path); |
|
|
|
|
if (o->call_depth) |
|
|
|
|
remove_file_from_cache(path); |
|
|
|
|
free(new_path); |
|
|
|
|
} else { |
|
|
|
|
output(o, 2, _("Adding %s"), path); |
|
|
|
|
/* do not overwrite file if already present */ |
|
|
|
|
update_file_flags(o, sha, mode, path, 1, !a_sha); |
|
|
|
|
update_file_flags(o, oid, mode, path, 1, !a_oid); |
|
|
|
|
} |
|
|
|
|
} else if (a_sha && b_sha) { |
|
|
|
|
} else if (a_oid && b_oid) { |
|
|
|
|
/* Case C: Added in both (check for same permissions) and */ |
|
|
|
|
/* case D: Modified in both, but differently. */ |
|
|
|
|
clean_merge = merge_content(o, path, |
|
|
|
|
o_sha, o_mode, a_sha, a_mode, b_sha, b_mode, |
|
|
|
|
o_oid, o_mode, a_oid, a_mode, b_oid, b_mode, |
|
|
|
|
NULL); |
|
|
|
|
} else if (!o_sha && !a_sha && !b_sha) { |
|
|
|
|
} else if (!o_oid && !a_oid && !b_oid) { |
|
|
|
|
/* |
|
|
|
|
* this entry was deleted altogether. a_mode == 0 means |
|
|
|
|
* we had that path and want to actively remove it. |
|
|
|
@ -1813,7 +1821,7 @@ int merge_trees(struct merge_options *o,
@@ -1813,7 +1821,7 @@ int merge_trees(struct merge_options *o,
|
|
|
|
|
common = shift_tree_object(head, common, o->subtree_shift); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (sha_eq(common->object.oid.hash, merge->object.oid.hash)) { |
|
|
|
|
if (oid_eq(&common->object.oid, &merge->object.oid)) { |
|
|
|
|
output(o, 0, _("Already up-to-date!")); |
|
|
|
|
*result = head; |
|
|
|
|
return 1; |
|
|
|
@ -1974,11 +1982,11 @@ int merge_recursive(struct merge_options *o,
@@ -1974,11 +1982,11 @@ int merge_recursive(struct merge_options *o,
|
|
|
|
|
return clean; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static struct commit *get_ref(const unsigned char *sha1, const char *name) |
|
|
|
|
static struct commit *get_ref(const struct object_id *oid, const char *name) |
|
|
|
|
{ |
|
|
|
|
struct object *object; |
|
|
|
|
|
|
|
|
|
object = deref_tag(parse_object(sha1), name, strlen(name)); |
|
|
|
|
object = deref_tag(parse_object(oid->hash), name, strlen(name)); |
|
|
|
|
if (!object) |
|
|
|
|
return NULL; |
|
|
|
|
if (object->type == OBJ_TREE) |
|
|
|
@ -1991,10 +1999,10 @@ static struct commit *get_ref(const unsigned char *sha1, const char *name)
@@ -1991,10 +1999,10 @@ static struct commit *get_ref(const unsigned char *sha1, const char *name)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int merge_recursive_generic(struct merge_options *o, |
|
|
|
|
const unsigned char *head, |
|
|
|
|
const unsigned char *merge, |
|
|
|
|
const struct object_id *head, |
|
|
|
|
const struct object_id *merge, |
|
|
|
|
int num_base_list, |
|
|
|
|
const unsigned char **base_list, |
|
|
|
|
const struct object_id **base_list, |
|
|
|
|
struct commit **result) |
|
|
|
|
{ |
|
|
|
|
int clean; |
|
|
|
@ -2007,9 +2015,9 @@ int merge_recursive_generic(struct merge_options *o,
@@ -2007,9 +2015,9 @@ int merge_recursive_generic(struct merge_options *o,
|
|
|
|
|
int i; |
|
|
|
|
for (i = 0; i < num_base_list; ++i) { |
|
|
|
|
struct commit *base; |
|
|
|
|
if (!(base = get_ref(base_list[i], sha1_to_hex(base_list[i])))) |
|
|
|
|
if (!(base = get_ref(base_list[i], oid_to_hex(base_list[i])))) |
|
|
|
|
return error(_("Could not parse object '%s'"), |
|
|
|
|
sha1_to_hex(base_list[i])); |
|
|
|
|
oid_to_hex(base_list[i])); |
|
|
|
|
commit_list_insert(base, &ca); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|