Merge branch 'jn/merge-renormalize'
* jn/merge-renormalize: merge-recursive --renormalize rerere: never renormalize rerere: migrate to parse-options API t4200 (rerere): modernize style ll-merge: let caller decide whether to renormalize ll-merge: make flag easier to populate Documentation/technical: document ll_merge merge-trees: let caller decide whether to renormalize merge-trees: push choice to renormalize away from low level t6038 (merge.renormalize): check that it can be turned off t6038 (merge.renormalize): try checkout -m and cherry-pick t6038 (merge.renormalize): style nitpicks Don't expand CRLFs when normalizing text during merge Try normalizing files to avoid delete/modify conflicts when merging Avoid conflicts when merging branches with mixed normalization Conflicts: builtin/rerere.c t/t4200-rerere.sh
This commit is contained in:
@ -644,7 +644,9 @@ static int merge_3way(struct merge_options *o,
|
||||
|
||||
merge_status = ll_merge(result_buf, a->path, &orig, base_name,
|
||||
&src1, name1, &src2, name2,
|
||||
(!!o->call_depth) | (favor << 1));
|
||||
((o->call_depth ? LL_OPT_VIRTUAL_ANCESTOR : 0) |
|
||||
(o->renormalize ? LL_OPT_RENORMALIZE : 0) |
|
||||
create_ll_flag(favor)));
|
||||
|
||||
free(name1);
|
||||
free(name2);
|
||||
@ -1062,6 +1064,53 @@ static unsigned char *stage_sha(const unsigned char *sha, unsigned mode)
|
||||
return (is_null_sha1(sha) || mode == 0) ? NULL: (unsigned char *)sha;
|
||||
}
|
||||
|
||||
static int read_sha1_strbuf(const unsigned char *sha1, struct strbuf *dst)
|
||||
{
|
||||
void *buf;
|
||||
enum object_type type;
|
||||
unsigned long size;
|
||||
buf = read_sha1_file(sha1, &type, &size);
|
||||
if (!buf)
|
||||
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));
|
||||
}
|
||||
strbuf_attach(dst, buf, size, size + 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int blob_unchanged(const unsigned char *o_sha,
|
||||
const unsigned char *a_sha,
|
||||
int renormalize, const char *path)
|
||||
{
|
||||
struct strbuf o = STRBUF_INIT;
|
||||
struct strbuf a = STRBUF_INIT;
|
||||
int ret = 0; /* assume changed for safety */
|
||||
|
||||
if (sha_eq(o_sha, a_sha))
|
||||
return 1;
|
||||
if (!renormalize)
|
||||
return 0;
|
||||
|
||||
assert(o_sha && a_sha);
|
||||
if (read_sha1_strbuf(o_sha, &o) || read_sha1_strbuf(a_sha, &a))
|
||||
goto error_return;
|
||||
/*
|
||||
* Note: binary | is used so that both renormalizations are
|
||||
* performed. Comparison can be skipped if both files are
|
||||
* unchanged since their sha1s have already been compared.
|
||||
*/
|
||||
if (renormalize_buffer(path, o.buf, o.len, &o) |
|
||||
renormalize_buffer(path, a.buf, o.len, &a))
|
||||
ret = (o.len == a.len && !memcmp(o.buf, a.buf, o.len));
|
||||
|
||||
error_return:
|
||||
strbuf_release(&o);
|
||||
strbuf_release(&a);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Per entry merge function */
|
||||
static int process_entry(struct merge_options *o,
|
||||
const char *path, struct stage_data *entry)
|
||||
@ -1071,6 +1120,7 @@ static int process_entry(struct merge_options *o,
|
||||
print_index_entry("\tpath: ", entry);
|
||||
*/
|
||||
int clean_merge = 1;
|
||||
int normalize = o->renormalize;
|
||||
unsigned o_mode = entry->stages[1].mode;
|
||||
unsigned a_mode = entry->stages[2].mode;
|
||||
unsigned b_mode = entry->stages[3].mode;
|
||||
@ -1082,8 +1132,8 @@ static int process_entry(struct merge_options *o,
|
||||
if (o_sha && (!a_sha || !b_sha)) {
|
||||
/* Case A: Deleted in one */
|
||||
if ((!a_sha && !b_sha) ||
|
||||
(sha_eq(a_sha, o_sha) && !b_sha) ||
|
||||
(!a_sha && sha_eq(b_sha, o_sha))) {
|
||||
(!b_sha && blob_unchanged(o_sha, a_sha, normalize, path)) ||
|
||||
(!a_sha && blob_unchanged(o_sha, b_sha, normalize, path))) {
|
||||
/* Deleted in both or deleted in one and
|
||||
* unchanged in the other */
|
||||
if (a_sha)
|
||||
@ -1525,6 +1575,7 @@ void init_merge_options(struct merge_options *o)
|
||||
o->buffer_output = 1;
|
||||
o->diff_rename_limit = -1;
|
||||
o->merge_rename_limit = -1;
|
||||
o->renormalize = 0;
|
||||
git_config(merge_recursive_config, o);
|
||||
if (getenv("GIT_MERGE_VERBOSITY"))
|
||||
o->verbosity =
|
||||
|
Reference in New Issue
Block a user