From 2d6bad918d584bd6bfeb134790cc3233c2283884 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Sat, 9 Jun 2018 21:16:11 -0700 Subject: [PATCH 1/6] merge-recursive: fix miscellaneous grammar error in comment Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- merge-recursive.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/merge-recursive.c b/merge-recursive.c index ac27abbd4c..921f8e2d2d 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -539,7 +539,7 @@ static void record_df_conflict_files(struct merge_options *o, struct string_list *entries) { /* If there is a D/F conflict and the file for such a conflict - * currently exist in the working tree, we want to allow it to be + * currently exists in the working tree, we want to allow it to be * removed to make room for the corresponding directory if needed. * The files underneath the directories of such D/F conflicts will * be processed before the corresponding file involved in the D/F From d90e759fd5d8c30ab37ecccbaa3a00c85682eaf9 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Sat, 9 Jun 2018 21:16:12 -0700 Subject: [PATCH 2/6] merge-recursive: fix numerous argument alignment issues Various refactorings throughout the code have left lots of alignment issues that were driving me crazy; fix them. Acked-by: Johannes Schindelin Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- merge-recursive.c | 75 ++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index 921f8e2d2d..09c249b93e 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -309,8 +309,8 @@ static void output_commit_title(struct merge_options *o, struct commit *commit) } static int add_cacheinfo(struct merge_options *o, - unsigned int mode, const struct object_id *oid, - const char *path, int stage, int refresh, int options) + unsigned int mode, const struct object_id *oid, + const char *path, int stage, int refresh, int options) { struct cache_entry *ce; int ret; @@ -417,8 +417,8 @@ struct tree *write_tree_from_memory(struct merge_options *o) } static int save_files_dirs(const struct object_id *oid, - struct strbuf *base, const char *path, - unsigned int mode, int stage, void *context) + struct strbuf *base, const char *path, + unsigned int mode, int stage, void *context) { struct path_hashmap_entry *entry; int baselen = base->len; @@ -913,7 +913,7 @@ static int make_room_for_path(struct merge_options *o, const char *path) */ if (would_lose_untracked(path)) return err(o, _("refusing to lose untracked file at '%s'"), - path); + path); /* Successful unlink is good.. */ if (!unlink(path)) @@ -992,7 +992,7 @@ static int update_file_flags(struct merge_options *o, unlink(path); if (symlink(lnk, path)) ret = err(o, _("failed to symlink '%s': %s"), - path, strerror(errno)); + path, strerror(errno)); free(lnk); } else ret = err(o, @@ -1090,7 +1090,7 @@ static int merge_3way(struct merge_options *o, } static int find_first_merges(struct object_array *result, const char *path, - struct commit *a, struct commit *b) + struct commit *a, struct commit *b) { int i, j; struct object_array merges = OBJECT_ARRAY_INIT; @@ -1108,7 +1108,7 @@ static int find_first_merges(struct object_array *result, const char *path, /* get all revisions that merge commit a */ xsnprintf(merged_revision, sizeof(merged_revision), "^%s", - oid_to_hex(&a->object.oid)); + oid_to_hex(&a->object.oid)); init_revisions(&revs, NULL); rev_opts.submodule = path; /* FIXME: can't handle linked worktrees in submodules yet */ @@ -1250,12 +1250,12 @@ static int merge_submodule(struct merge_options *o, output(o, 2, _("Found a possible merge resolution for the submodule:\n")); print_commit((struct commit *) merges.objects[0].item); output(o, 2, _( - "If this is correct simply add it to the index " - "for example\n" - "by using:\n\n" - " git update-index --cacheinfo 160000 %s \"%s\"\n\n" - "which will accept this suggestion.\n"), - oid_to_hex(&merges.objects[0].item->oid), path); + "If this is correct simply add it to the index " + "for example\n" + "by using:\n\n" + " git update-index --cacheinfo 160000 %s \"%s\"\n\n" + "which will accept this suggestion.\n"), + oid_to_hex(&merges.objects[0].item->oid), path); break; default: @@ -1332,10 +1332,10 @@ static int merge_file_1(struct merge_options *o, result->clean = (merge_status == 0); } else if (S_ISGITLINK(a->mode)) { result->clean = merge_submodule(o, &result->oid, - one->path, - &one->oid, - &a->oid, - &b->oid); + one->path, + &one->oid, + &a->oid, + &b->oid); } else if (S_ISLNK(a->mode)) { switch (o->recursive_variant) { case MERGE_RECURSIVE_NORMAL: @@ -1443,13 +1443,13 @@ static int conflict_rename_dir(struct merge_options *o, } static int handle_change_delete(struct merge_options *o, - const char *path, const char *old_path, - const struct object_id *o_oid, int o_mode, - const struct object_id *changed_oid, - int changed_mode, - const char *change_branch, - const char *delete_branch, - const char *change, const char *change_past) + const char *path, const char *old_path, + const struct object_id *o_oid, int o_mode, + const struct object_id *changed_oid, + int changed_mode, + const char *change_branch, + const char *delete_branch, + const char *change, const char *change_past) { char *alt_path = NULL; const char *update_path = path; @@ -1510,9 +1510,9 @@ static int handle_change_delete(struct merge_options *o, } static int conflict_rename_delete(struct merge_options *o, - struct diff_filepair *pair, - const char *rename_branch, - const char *delete_branch) + struct diff_filepair *pair, + const char *rename_branch, + const char *delete_branch) { const struct diff_filespec *orig = pair->one; const struct diff_filespec *dest = pair->two; @@ -1615,7 +1615,7 @@ static int handle_file(struct merge_options *o, } static int conflict_rename_rename_1to2(struct merge_options *o, - struct rename_conflict_info *ci) + struct rename_conflict_info *ci) { /* One file was renamed in both branches, but to different names. */ struct diff_filespec *one = ci->pair1->one; @@ -1677,7 +1677,7 @@ static int conflict_rename_rename_1to2(struct merge_options *o, } static int conflict_rename_rename_2to1(struct merge_options *o, - struct rename_conflict_info *ci) + struct rename_conflict_info *ci) { /* Two files, a & b, were renamed to the same thing, c. */ struct diff_filespec *a = ci->pair1->one; @@ -2904,7 +2904,8 @@ static struct object_id *stage_oid(const struct object_id *oid, unsigned mode) } static int read_oid_strbuf(struct merge_options *o, - const struct object_id *oid, struct strbuf *dst) + const struct object_id *oid, + struct strbuf *dst) { void *buf; enum object_type type; @@ -2957,10 +2958,10 @@ static int blob_unchanged(struct merge_options *opt, } static int handle_modify_delete(struct merge_options *o, - const char *path, - struct object_id *o_oid, int o_mode, - struct object_id *a_oid, int a_mode, - struct object_id *b_oid, int b_mode) + const char *path, + struct object_id *o_oid, int o_mode, + struct object_id *a_oid, int a_mode, + struct object_id *b_oid, int b_mode) { const char *modify_branch, *delete_branch; struct object_id *changed_oid; @@ -3493,14 +3494,14 @@ int merge_recursive_generic(struct merge_options *o, struct commit *base; if (!(base = get_ref(base_list[i], oid_to_hex(base_list[i])))) return err(o, _("Could not parse object '%s'"), - oid_to_hex(base_list[i])); + oid_to_hex(base_list[i])); commit_list_insert(base, &ca); } } hold_locked_index(&lock, LOCK_DIE_ON_ERROR); clean = merge_recursive(o, head_commit, next_commit, ca, - result); + result); if (clean < 0) { rollback_lock_file(&lock); return clean; From 9366536583a101b4e02c2cd047c03d91dc62827d Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Sat, 9 Jun 2018 21:16:13 -0700 Subject: [PATCH 3/6] merge-recursive: align labels with their respective code blocks Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- merge-recursive.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index 09c249b93e..5538038178 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -998,10 +998,10 @@ static int update_file_flags(struct merge_options *o, ret = err(o, _("do not know what to do with %06o %s '%s'"), mode, oid_to_hex(oid), path); - free_buf: + free_buf: free(buf); } - update_index: +update_index: if (!ret && update_cache) if (add_cacheinfo(o, mode, oid, path, 0, update_wd, ADD_CACHE_OK_TO_ADD)) @@ -3326,7 +3326,7 @@ int merge_trees(struct merge_options *o, entries->items[i].string); } -cleanup: + cleanup: final_cleanup_renames(&re_info); string_list_clear(entries, 1); From 5455c33839c6c5d248007ad2b49e8a225e9f47fa Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Sat, 9 Jun 2018 21:16:14 -0700 Subject: [PATCH 4/6] merge-recursive: clarify the rename_dir/RENAME_DIR meaning We had an enum of rename types which included RENAME_DIR; this name felt misleading since it was not about an entire directory but was a status for each individual file add that occurred within a renamed directory. Since this type is for signifying that the files in question were being renamed due to directory rename detection, rename this enum value to RENAME_VIA_DIR. Make a similar change to the conflict_rename_dir() function, and add a comment to the top of that function explaining its purpose (it may not be quite as obvious as for the other conflict_rename_*() functions). Acked-by: Johannes Schindelin Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- merge-recursive.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index 5538038178..910f0b70f0 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -181,7 +181,7 @@ static int oid_eq(const struct object_id *a, const struct object_id *b) enum rename_type { RENAME_NORMAL = 0, - RENAME_DIR, + RENAME_VIA_DIR, RENAME_DELETE, RENAME_ONE_FILE_TO_ONE, RENAME_ONE_FILE_TO_TWO, @@ -1410,11 +1410,17 @@ static int merge_file_one(struct merge_options *o, return merge_file_1(o, &one, &a, &b, path, branch1, branch2, mfi); } -static int conflict_rename_dir(struct merge_options *o, - struct diff_filepair *pair, - const char *rename_branch, - const char *other_branch) +static int conflict_rename_via_dir(struct merge_options *o, + struct diff_filepair *pair, + const char *rename_branch, + const char *other_branch) { + /* + * Handle file adds that need to be renamed due to directory rename + * detection. This differs from handle_rename_normal, because + * there is no content merge to do; just move the file into the + * desired final location. + */ const struct diff_filespec *dest = pair->two; if (!o->call_depth && would_lose_untracked(dest->path)) { @@ -2692,7 +2698,7 @@ static int process_renames(struct merge_options *o, if (oid_eq(&src_other.oid, &null_oid) && ren1->add_turned_into_rename) { - setup_rename_conflict_info(RENAME_DIR, + setup_rename_conflict_info(RENAME_VIA_DIR, ren1->pair, NULL, branch1, @@ -3138,12 +3144,12 @@ static int process_entry(struct merge_options *o, b_oid, b_mode, conflict_info); break; - case RENAME_DIR: + case RENAME_VIA_DIR: clean_merge = 1; - if (conflict_rename_dir(o, - conflict_info->pair1, - conflict_info->branch1, - conflict_info->branch2)) + if (conflict_rename_via_dir(o, + conflict_info->pair1, + conflict_info->branch1, + conflict_info->branch2)) clean_merge = -1; break; case RENAME_DELETE: From 8ebe7b057ad866e027365526782cd2e42a0bd106 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Sat, 9 Jun 2018 21:16:15 -0700 Subject: [PATCH 5/6] merge-recursive: rename conflict_rename_*() family of functions These functions were added because processing of these conflicts needed to be deferred until process_entry() in order to get D/F conflicts and such right. The number of these has grown over time, and now include some whose name is misleading: * conflict_rename_normal() is for handling normal file renames; a typical rename may need content merging, but we expect conflicts from that to be more the exception than the rule. * conflict_rename_via_dir() will not be a conflict; it was just an add that turned into a move due to directory rename detection. (If there was a file in the way of the move, that would have been detected and reported earlier.) * conflict_rename_rename_2to1 and conflict_rename_add (the latter of which doesn't exist yet but has been submitted before and I intend to resend) technically might not be conflicts if the colliding paths happen to match exactly. Rename this family of functions to handle_rename_*(). Also rename handle_renames() to detect_and_process_renames() both to make it clearer what it does, and to differentiate it as a pre-processing step from all the handle_rename_*() functions which are called from process_entry(). Acked-by: Johannes Schindelin Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- merge-recursive.c | 86 +++++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index 910f0b70f0..7cf11dc04c 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -1410,10 +1410,10 @@ static int merge_file_one(struct merge_options *o, return merge_file_1(o, &one, &a, &b, path, branch1, branch2, mfi); } -static int conflict_rename_via_dir(struct merge_options *o, - struct diff_filepair *pair, - const char *rename_branch, - const char *other_branch) +static int handle_rename_via_dir(struct merge_options *o, + struct diff_filepair *pair, + const char *rename_branch, + const char *other_branch) { /* * Handle file adds that need to be renamed due to directory rename @@ -1515,10 +1515,10 @@ static int handle_change_delete(struct merge_options *o, return ret; } -static int conflict_rename_delete(struct merge_options *o, - struct diff_filepair *pair, - const char *rename_branch, - const char *delete_branch) +static int handle_rename_delete(struct merge_options *o, + struct diff_filepair *pair, + const char *rename_branch, + const char *delete_branch) { const struct diff_filespec *orig = pair->one; const struct diff_filespec *dest = pair->two; @@ -1620,8 +1620,8 @@ static int handle_file(struct merge_options *o, return ret; } -static int conflict_rename_rename_1to2(struct merge_options *o, - struct rename_conflict_info *ci) +static int handle_rename_rename_1to2(struct merge_options *o, + struct rename_conflict_info *ci) { /* One file was renamed in both branches, but to different names. */ struct diff_filespec *one = ci->pair1->one; @@ -1682,8 +1682,8 @@ static int conflict_rename_rename_1to2(struct merge_options *o, return 0; } -static int conflict_rename_rename_2to1(struct merge_options *o, - struct rename_conflict_info *ci) +static int handle_rename_rename_2to1(struct merge_options *o, + struct rename_conflict_info *ci) { /* Two files, a & b, were renamed to the same thing, c. */ struct diff_filespec *a = ci->pair1->one; @@ -2425,7 +2425,7 @@ static void apply_directory_rename_modifications(struct merge_options *o, * "NOTE" in update_stages(), doing so will modify the current * in-memory index which will break calls to would_lose_untracked() * that we need to make. Instead, we need to just make sure that - * the various conflict_rename_*() functions update the index + * the various handle_rename_*() functions update the index * explicitly rather than relying on unpack_trees() to have done it. */ get_tree_entry(&tree->object.oid, @@ -2829,12 +2829,12 @@ static void initial_cleanup_rename(struct diff_queue_struct *pairs, free(pairs); } -static int handle_renames(struct merge_options *o, - struct tree *common, - struct tree *head, - struct tree *merge, - struct string_list *entries, - struct rename_info *ri) +static int detect_and_process_renames(struct merge_options *o, + struct tree *common, + struct tree *head, + struct tree *merge, + struct string_list *entries, + struct rename_info *ri) { struct diff_queue_struct *head_pairs, *merge_pairs; struct hashmap *dir_re_head, *dir_re_merge; @@ -3105,12 +3105,12 @@ static int merge_content(struct merge_options *o, return !is_dirty && mfi.clean; } -static int conflict_rename_normal(struct merge_options *o, - const char *path, - struct object_id *o_oid, unsigned int o_mode, - struct object_id *a_oid, unsigned int a_mode, - struct object_id *b_oid, unsigned int b_mode, - struct rename_conflict_info *ci) +static int handle_rename_normal(struct merge_options *o, + const char *path, + struct object_id *o_oid, unsigned int o_mode, + struct object_id *a_oid, unsigned int a_mode, + struct object_id *b_oid, unsigned int b_mode, + struct rename_conflict_info *ci) { /* Merge the content and write it out */ return merge_content(o, path, was_dirty(o, path), @@ -3137,37 +3137,37 @@ static int process_entry(struct merge_options *o, switch (conflict_info->rename_type) { case RENAME_NORMAL: case RENAME_ONE_FILE_TO_ONE: - clean_merge = conflict_rename_normal(o, - path, - o_oid, o_mode, - a_oid, a_mode, - b_oid, b_mode, - conflict_info); + clean_merge = handle_rename_normal(o, + path, + o_oid, o_mode, + a_oid, a_mode, + b_oid, b_mode, + conflict_info); break; case RENAME_VIA_DIR: clean_merge = 1; - if (conflict_rename_via_dir(o, - conflict_info->pair1, - conflict_info->branch1, - conflict_info->branch2)) + if (handle_rename_via_dir(o, + conflict_info->pair1, + conflict_info->branch1, + conflict_info->branch2)) clean_merge = -1; break; case RENAME_DELETE: clean_merge = 0; - if (conflict_rename_delete(o, - conflict_info->pair1, - conflict_info->branch1, - conflict_info->branch2)) + if (handle_rename_delete(o, + conflict_info->pair1, + conflict_info->branch1, + conflict_info->branch2)) clean_merge = -1; break; case RENAME_ONE_FILE_TO_TWO: clean_merge = 0; - if (conflict_rename_rename_1to2(o, conflict_info)) + if (handle_rename_rename_1to2(o, conflict_info)) clean_merge = -1; break; case RENAME_TWO_FILES_TO_ONE: clean_merge = 0; - if (conflict_rename_rename_2to1(o, conflict_info)) + if (handle_rename_rename_2to1(o, conflict_info)) clean_merge = -1; break; default: @@ -3307,8 +3307,8 @@ int merge_trees(struct merge_options *o, get_files_dirs(o, merge); entries = get_unmerged(); - clean = handle_renames(o, common, head, merge, entries, - &re_info); + clean = detect_and_process_renames(o, common, head, merge, + entries, &re_info); record_df_conflict_files(o, entries); if (clean < 0) goto cleanup; From 5b26c3c941d3c7cd96be668e1778ba22cc4829d5 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Sat, 9 Jun 2018 21:16:16 -0700 Subject: [PATCH 6/6] merge-recursive: add pointer about unduly complex looking code handle_change_delete() has a block of code displaying one of four nearly identical messages. Each contains about half a dozen variable interpolations, which use nearly identical variables as well. Someone trying to parse this may be slowed down trying to parse the differences and why they are here; help them out by adding a comment explaining the differences. Further, point out that this code structure isn't collapsed into something more concise and readable for the programmer, because we want to keep full messages intact in order to make translators' jobs much easier. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- merge-recursive.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/merge-recursive.c b/merge-recursive.c index 7cf11dc04c..284b27d895 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -1476,6 +1476,21 @@ static int handle_change_delete(struct merge_options *o, if (!ret) ret = update_file(o, 0, o_oid, o_mode, update_path); } else { + /* + * Despite the four nearly duplicate messages and argument + * lists below and the ugliness of the nested if-statements, + * having complete messages makes the job easier for + * translators. + * + * The slight variance among the cases is due to the fact + * that: + * 1) directory/file conflicts (in effect if + * !alt_path) could cause us to need to write the + * file to a different path. + * 2) renames (in effect if !old_path) could mean that + * there are two names for the path that the user + * may know the file by. + */ if (!alt_path) { if (!old_path) { output(o, 1, _("CONFLICT (%s/delete): %s deleted in %s "