{"thread":{"id":"4715","subject":"[PATCH 3/4] use detachable filepairs and an attempt to cleanup","startedAt":"2006-06-30T00:27:50Z","lastAt":"2006-06-30T00:27:50Z","messageCount":1,"participants":["Alex Riesen"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"22864","messageId":"20060630002750.GC22618@steel.home","threadId":"4715","inReplyTo":null,"subject":"[PATCH 3/4] use detachable filepairs and an attempt to cleanup","fromName":"Alex Riesen","fromEmail":"fork0@t-online.de","sentAt":"2006-06-30T00:27:50Z","receivedAt":"2006-06-30T00:27:50Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"---\n merge-recursive.c |  295 +++++++++++++++++++++++++++++------------------------\n 1 files changed, 162 insertions(+), 133 deletions(-)\n\ndiff --git a/merge-recursive.c b/merge-recursive.c\nindex abceb30..9a18e06 100644\n--- a/merge-recursive.c\n+++ b/merge-recursive.c\n@@ -579,26 +579,17 @@ struct rename_entry\n {\n \tstruct rename_entry *next;\n \n-\tunsigned char src_sha[20];\n-\tunsigned src_mode;\n+\tstruct diff_filepair *pair;\n \tstruct index_entry *src_entry;\n-\n-\tunsigned char dst_sha[20];\n-\tunsigned dst_mode;\n \tstruct index_entry *dst_entry;\n-\n-\tunsigned score:16,\n-\t\t processed:1;\n-\n-\tchar *src; /* dst + strlen(dst) + 1 */\n-\tchar dst[1];\n+\tunsigned processed:1;\n };\n \n static struct rename_entry *find_rename_bysrc(struct rename_entry *e,\n \t\t\t\t\t      const char *name)\n {\n \twhile ( e ) {\n-\t\tif ( strcmp(e->src, name) == 0 )\n+\t\tif ( strcmp(e->pair->one->path, name) == 0 )\n \t\t\tbreak;\n \t\te = e->next;\n \t}\n@@ -609,7 +600,7 @@ static struct rename_entry *find_rename_\n \t\t\t\t\t      const char *name)\n {\n \twhile ( e ) {\n-\t\tif ( strcmp(e->dst, name) == 0 )\n+\t\tif ( strcmp(e->pair->two->path, name) == 0 )\n \t\t\tbreak;\n \t\te = e->next;\n \t}\n@@ -620,6 +611,7 @@ static void free_rename_entries(struct r\n {\n \twhile (*list) {\n \t\tstruct rename_entry *next = (*list)->next;\n+\t\tdiff_free_filepair((*list)->pair);\n \t\tfree(*list);\n \t\t*list = next;\n \t}\n@@ -656,29 +648,23 @@ static struct rename_entry *get_renames(\n \t\tstruct diff_filepair *pair = diff_queued_diff.queue[i];\n \t\tif (pair->status != 'R')\n \t\t\tcontinue;\n-\t\tsize_t l1 = strlen(pair->one->path);\n-\t\tsize_t l2 = strlen(pair->two->path);\n-\t\tre = xmalloc(sizeof(*re) + l1 + l2 + 2);\n-\t\tre->src = re->dst + l2;\n+\t\tdiff_queued_diff.queue[i] = NULL;\n+\t\tre = xmalloc(sizeof(*re));\n \t\tre->next = NULL;\n \t\tre->processed = 0;\n-\t\tre->score = pair->score;\n-\t\tmemcpy(re->src_sha, pair->one->sha1, 20);\n-\t\tmemcpy(re->src, pair->one->path, ++l1);\n-\t\tre->src_mode = pair->one->mode;\n-\t\tmemcpy(re->dst_sha, pair->two->sha1, 20);\n-\t\tmemcpy(re->dst, pair->two->path, ++l2);\n-\t\tre->dst_mode = pair->two->mode;\n+\t\tre->pair = pair;\n \t\t// TODO: optimize index_entry_find\n-\t\tre->src_entry = index_entry_find(*entries, re->src);\n+\t\tre->src_entry = index_entry_find(*entries, re->pair->one->path);\n \t\tif ( !re->src_entry ) {\n-\t\t\tre->src_entry = index_entry_from_db(re->src, oTree, aTree, bTree);\n+\t\t\tre->src_entry = index_entry_from_db(re->pair->one->path,\n+\t\t\t\t\t\t\t    oTree, aTree, bTree);\n \t\t\tre->src_entry->next = *entries;\n \t\t\t*entries = re->src_entry;\n \t\t}\n-\t\tre->dst_entry = index_entry_find(*entries, re->dst);\n+\t\tre->dst_entry = index_entry_find(*entries, re->pair->two->path);\n \t\tif ( !re->dst_entry ) {\n-\t\t\tre->dst_entry = index_entry_from_db(re->dst, oTree, aTree, bTree);\n+\t\t\tre->dst_entry = index_entry_from_db(re->pair->two->path,\n+\t\t\t\t\t\t\t    oTree, aTree, bTree);\n \t\t\tre->dst_entry->next = *entries;\n \t\t\t*entries = re->dst_entry;\n \t\t}\n@@ -688,7 +674,6 @@ static struct rename_entry *get_renames(\n \topts.output_format = DIFF_FORMAT_NO_OUTPUT;\n \tdiff_flush(&opts);\n \tdebug(\"  getRenames done in %ld\\n\", time(0)-t);\n-\tdie(\"PROFILING\");\n \treturn renames;\n }\n \n@@ -979,12 +964,9 @@ static struct merge_file_info merge_file\n \t\t\t\tNULL\n \t\t\t};\n \t\t\tchar *la, *lb, *lo;\n-\t\t\targv[2] = la = malloc(strlen(branch1Name) + 2 + strlen(aPath));\n-\t\t\tstrcat(strcat(strcpy(la, branch1Name), \"/\"), aPath);\n-\t\t\targv[6] = lb = malloc(strlen(branch2Name) + 2 + strlen(bPath));\n-\t\t\tstrcat(strcat(strcpy(lb, branch2Name), \"/\"), bPath);\n-\t\t\targv[4] = lo = malloc(7 + strlen(oPath));\n-\t\t\tstrcat(strcpy(lo, \"orig/\"), oPath);\n+\t\t\targv[2] = la = strdup(mkpath(\"%s/%s\", branch1Name, aPath));\n+\t\t\targv[6] = lb = strdup(mkpath(\"%s/%s\", branch2Name, bPath));\n+\t\t\targv[4] = lo = strdup(mkpath(\"orig/%s\", oPath));\n \n #if 0\n \t\t\tprintf(\"%s %s %s %s %s %s %s %s %s %s\\n\",\n@@ -1029,6 +1011,75 @@ #endif\n \treturn result;\n }\n \n+static void conflict_rename_rename(FILE *up_index,\n+\t\t\t\t   struct rename_entry *ren1,\n+\t\t\t\t   const char *branch1,\n+\t\t\t\t   struct rename_entry *ren2,\n+\t\t\t\t   const char *branch2)\n+{\n+\tchar *del[2];\n+\tint delp = 0;\n+\tconst char *ren1_dst = ren1->pair->two->path;\n+\tconst char *ren2_dst = ren2->pair->two->path;\n+\tconst char *dstName1 = ren1_dst;\n+\tconst char *dstName2 = ren2_dst;\n+\tif (path_list_has_path(&currentDirectorySet, ren1_dst)) {\n+\t\tdstName1 = del[delp++] = unique_path(ren1_dst, branch1);\n+\t\toutput(\"%s is a directory in %s adding as %s instead\",\n+\t\t       ren1_dst, branch2, dstName1);\n+\t\tremove_file(up_index, 0, ren1_dst);\n+\t}\n+\tif (path_list_has_path(&currentDirectorySet, ren2_dst)) {\n+\t\tdstName2 = del[delp++] = unique_path(ren2_dst, branch2);\n+\t\toutput(\"%s is a directory in %s adding as %s instead\",\n+\t\t       ren2_dst, branch1, dstName2);\n+\t\tremove_file(up_index, 0, ren2_dst);\n+\t}\n+\tupdate_stages(up_index, dstName1,\n+\t\t      NULL, 0,\n+\t\t      ren1->pair->two->sha1, ren1->pair->two->mode,\n+\t\t      NULL, 0,\n+\t\t      1 /* clear */);\n+\tupdate_stages(up_index, dstName2,\n+\t\t      NULL, 0,\n+\t\t      NULL, 0,\n+\t\t      ren2->pair->two->sha1, ren2->pair->two->mode,\n+\t\t      1 /* clear */);\n+\twhile ( delp-- )\n+\t\tfree(del[delp]);\n+}\n+\n+static void conflict_rename_dir(FILE *up_index,\n+\t\t\t\tstruct rename_entry *ren1,\n+\t\t\t\tconst char *branch1)\n+{\n+\tchar *newPath = unique_path(ren1->pair->two->path, branch1);\n+\toutput(\"Renaming %s to %s instead\", ren1->pair->one->path, newPath);\n+\tremove_file(up_index, 0, ren1->pair->two->path);\n+\tupdate_file(up_index, 0, ren1->pair->two->sha1, ren1->pair->two->mode, newPath);\n+\tfree(newPath);\n+}\n+\n+static void conflict_rename_rename_2(FILE *up_index,\n+\t\t\t\t     struct rename_entry *ren1,\n+\t\t\t\t     const char *branch1,\n+\t\t\t\t     struct rename_entry *ren2,\n+\t\t\t\t     const char *branch2)\n+{\n+\tchar *newPath1 = unique_path(ren1->pair->two->path, branch1);\n+\tchar *newPath2 = unique_path(ren2->pair->two->path, branch2);\n+\toutput(\"Renaming %s to %s and %s to %s instead\",\n+\t       ren1->pair->one->path, newPath1,\n+\t       ren2->pair->one->path, newPath2);\n+\tremove_file(up_index, 0, ren1->pair->two->path);\n+\tupdate_file(up_index, 0,\n+\t\t    ren1->pair->two->sha1, ren1->pair->two->mode, newPath1);\n+\tupdate_file(up_index, 0,\n+\t\t    ren2->pair->two->sha1, ren2->pair->two->mode, newPath2);\n+\tfree(newPath2);\n+\tfree(newPath1);\n+}\n+\n static int process_renames(struct rename_entry *renamesA,\n \t\t\t   struct rename_entry *renamesB,\n \t\t\t   const char *branchNameA,\n@@ -1042,9 +1093,9 @@ static int process_renames(struct rename\n \tchar **src;\n \n \tfor (sre = renamesA; sre; sre = sre->next)\n-\t\tpath_list_insert(sre->src, &srcNames);\n+\t\tpath_list_insert(sre->pair->one->path, &srcNames);\n \tfor (sre = renamesB; sre; sre = sre->next)\n-\t\tpath_list_insert(sre->src, &srcNames);\n+\t\tpath_list_insert(sre->pair->one->path, &srcNames);\n \n \tFILE *fp = git_update_index_pipe();\n \tfor_each_path(src,&srcNames) {\n@@ -1074,80 +1125,66 @@ static int process_renames(struct rename\n \t\t\tcontinue;\n \t\tren1->processed = 1;\n \n+\t\tconst char *ren1_src = ren1->pair->one->path;\n+\t\tconst char *ren1_dst = ren1->pair->two->path;\n+\n \t\tif ( ren2 ) {\n+\t\t\tconst char *ren2_src = ren2->pair->one->path;\n+\t\t\tconst char *ren2_dst = ren2->pair->two->path;\n \t\t\t/* Renamed in 1 and renamed in 2 */\n-\t\t\tif ( strcmp(ren1->src, ren2->src) != 0 )\n-\t\t\t\tdie(\"ren1.srcName != ren2.srcName\");\n+\t\t\tif (strcmp(ren1_src, ren2_src) != 0)\n+\t\t\t\tdie(\"ren1.src != ren2.src\");\n \t\t\tren2->dst_entry->processed = 1;\n \t\t\tren2->processed = 1;\n-\t\t\tif ( strcmp(ren1->dst, ren2->dst) != 0 ) {\n+\t\t\tif (strcmp(ren1_dst, ren2_dst) != 0) {\n+\t\t\t\tcleanMerge = 0;\n \t\t\t\toutput(\"CONFLICT (rename/rename): \"\n \t\t\t\t       \"Rename %s->%s in branch %s \"\n \t\t\t\t       \"rename %s->%s in %s\",\n-\t\t\t\t       *src, ren1->dst, branchName1,\n-\t\t\t\t       *src, ren2->dst, branchName2);\n-\t\t\t\tcleanMerge = 0;\n-\t\t\t\tchar *dstName1 = ren1->dst, *dstName2 = ren2->dst;\n-\t\t\t\tif ( path_list_has_path(&currentDirectorySet, ren1->dst) ) {\n-\t\t\t\t\tdstName1 = unique_path(ren1->dst, branchName1);\n-\t\t\t\t\toutput(\"%s is a directory in %s adding as %s instead\",\n-\t\t\t\t\t       ren1->dst, branchName2, dstName1);\n-\t\t\t\t\tremove_file(fp, 0, ren1->dst);\n-\t\t\t\t}\n-\t\t\t\tif ( path_list_has_path(&currentDirectorySet, ren2->dst) ) {\n-\t\t\t\t\tdstName2 = unique_path(ren2->dst, branchName2);\n-\t\t\t\t\toutput(\"%s is a directory in %s adding as %s instead\",\n-\t\t\t\t\t       ren2->dst, branchName1, dstName2);\n-\t\t\t\t\tremove_file(fp, 0, ren2->dst);\n-\t\t\t\t}\n-\t\t\t\tupdate_stages(fp, dstName1,\n-\t\t\t\t\t       NULL, 0,\n-\t\t\t\t\t       ren1->dst_sha, ren1->dst_mode,\n-\t\t\t\t\t       NULL, 0,\n-\t\t\t\t\t       1 /* clear */);\n-\t\t\t\tupdate_stages(fp, dstName2,\n-\t\t\t\t\t       NULL, 0,\n-\t\t\t\t\t       NULL, 0,\n-\t\t\t\t\t       ren2->dst_sha, ren2->dst_mode,\n-\t\t\t\t\t       1 /* clear */);\n+\t\t\t\t       *src, ren1_dst, branchName1,\n+\t\t\t\t       *src, ren2_dst, branchName2);\n+\t\t\t\tconflict_rename_rename(fp, ren1, branchName1, ren2, branchName2);\n \t\t\t} else {\n-\t\t\t\tremove_file(fp, 1, ren1->src);\n+\t\t\t\tremove_file(fp, 1, ren1_src);\n \t\t\t\tstruct merge_file_info mfi;\n-\t\t\t\tmfi = merge_file(ren1->src,\n-\t\t\t\t\t\t ren1->src_sha,\n-\t\t\t\t\t\t ren1->src_mode,\n-\t\t\t\t\t\t ren1->dst,\n-\t\t\t\t\t\t ren1->dst_sha,\n-\t\t\t\t\t\t ren1->dst_mode,\n-\t\t\t\t\t\t ren2->dst,\n-\t\t\t\t\t\t ren2->dst_sha,\n-\t\t\t\t\t\t ren2->dst_mode,\n+\t\t\t\tmfi = merge_file(ren1_src,\n+\t\t\t\t\t\t ren1->pair->one->sha1,\n+\t\t\t\t\t\t ren1->pair->one->mode,\n+\t\t\t\t\t\t ren1_dst,\n+\t\t\t\t\t\t ren1->pair->two->sha1,\n+\t\t\t\t\t\t ren1->pair->two->mode,\n+\t\t\t\t\t\t ren2_dst,\n+\t\t\t\t\t\t ren2->pair->two->sha1,\n+\t\t\t\t\t\t ren2->pair->two->mode,\n \t\t\t\t\t\t branchName1,\n \t\t\t\t\t\t branchName2);\n \t\t\t\tif ( mfi.merge || !mfi.clean )\n-\t\t\t\t\toutput(\"Renaming %s->%s\", *src, ren1->dst);\n+\t\t\t\t\toutput(\"Renaming %s->%s\", *src, ren1_dst);\n \n \t\t\t\tif ( mfi.merge )\n-\t\t\t\t\toutput(\"Auto-merging %s\", ren1->dst);\n+\t\t\t\t\toutput(\"Auto-merging %s\", ren1_dst);\n \n \t\t\t\tif ( !mfi.clean ) {\n \t\t\t\t\toutput(\"CONFLICT (content): merge conflict in %s\",\n-\t\t\t\t\t       ren1->dst);\n+\t\t\t\t\t       ren1_dst);\n \t\t\t\t\tcleanMerge = 0;\n \n \t\t\t\t\tif ( !index_only )\n \t\t\t\t\t\tupdate_stages(fp,\n-\t\t\t\t\t\t\t       ren1->dst,\n-\t\t\t\t\t\t\t       ren1->src_sha, ren1->src_mode,\n-\t\t\t\t\t\t\t       ren1->dst_sha, ren1->dst_mode,\n-\t\t\t\t\t\t\t       ren2->dst_sha, ren2->dst_mode,\n-\t\t\t\t\t\t\t       1 /* clear */);\n+\t\t\t\t\t\t\t      ren1_dst,\n+\t\t\t\t\t\t\t      ren1->pair->one->sha1,\n+\t\t\t\t\t\t\t      ren1->pair->one->mode,\n+\t\t\t\t\t\t\t      ren1->pair->two->sha1,\n+\t\t\t\t\t\t\t      ren1->pair->two->mode,\n+\t\t\t\t\t\t\t      ren2->pair->two->sha1,\n+\t\t\t\t\t\t\t      ren2->pair->two->mode,\n+\t\t\t\t\t\t\t      1 /* clear */);\n \t\t\t\t}\n-\t\t\t\tupdate_file(fp, mfi.clean, mfi.sha, mfi.mode, ren1->dst);\n+\t\t\t\tupdate_file(fp, mfi.clean, mfi.sha, mfi.mode, ren1_dst);\n \t\t\t}\n \t\t} else {\n \t\t\t/* Renamed in 1, maybe changed in 2 */\n-\t\t\tremove_file(fp, 1, ren1->src);\n+\t\t\tremove_file(fp, 1, ren1_src);\n \n \t\t\tunsigned char srcShaOtherBranch[20], dstShaOtherBranch[20];\n \t\t\tunsigned srcModeOtherBranch, dstModeOtherBranch;\n@@ -1162,62 +1199,52 @@ static int process_renames(struct rename\n \n \t\t\tint tryMerge = 0;\n \t\t\tchar *newPath;\n-\t\t\tstruct rename_entry *dst2;\n \n-\t\t\tif ( path_list_has_path(&currentDirectorySet, ren1->dst) ) {\n-\t\t\t\tnewPath = unique_path(ren1->dst, branchName1);\n+\t\t\tif (path_list_has_path(&currentDirectorySet, ren1_dst)) {\n+\t\t\t\tcleanMerge = 0;\n \t\t\t\toutput(\"CONFLICT (rename/directory): Rename %s->%s in %s \"\n \t\t\t\t       \" directory %s added in %s\",\n-\t\t\t\t       ren1->src, ren1->dst, branchName1,\n-\t\t\t\t       ren1->dst, branchName2);\n-\t\t\t\toutput(\"Renaming %s to %s instead\", ren1->src, newPath);\n-\t\t\t\tcleanMerge = 0;\n-\t\t\t\tremove_file(fp, 0, ren1->dst);\n-\t\t\t\tupdate_file(fp, 0, ren1->dst_sha, ren1->dst_mode, newPath);\n+\t\t\t\t       ren1_src, ren1_dst, branchName1,\n+\t\t\t\t       ren1_dst, branchName2);\n+\t\t\t\tconflict_rename_dir(fp, ren1, branchName1);\n \t\t\t} else if ( memcmp(srcShaOtherBranch, null_sha1, 20) == 0 ) {\n+\t\t\t\tcleanMerge = 0;\n \t\t\t\toutput(\"CONFLICT (rename/delete): Rename %s->%s in %s \"\n \t\t\t\t       \"and deleted in %s\",\n-\t\t\t\t       ren1->src, ren1->dst, branchName1,\n+\t\t\t\t       ren1_src, ren1_dst, branchName1,\n \t\t\t\t       branchName2);\n-\t\t\t\tcleanMerge = 0;\n-\t\t\t\tupdate_file(fp, 0, ren1->dst_sha, ren1->dst_mode, ren1->dst);\n+\t\t\t\tupdate_file(fp, 0, ren1->pair->two->sha1, ren1->pair->two->mode, ren1_dst);\n \t\t\t} else if ( memcmp(dstShaOtherBranch, null_sha1, 20) != 0 ) {\n-\t\t\t\tnewPath = unique_path(ren1->dst, branchName2);\n+\t\t\t\tcleanMerge = 0;\n+\t\t\t\ttryMerge = 1;\n \t\t\t\toutput(\"CONFLICT (rename/add): Rename %s->%s in %s. \"\n \t\t\t\t       \"%s added in %s\",\n-\t\t\t\t       ren1->src, ren1->dst, branchName1,\n-\t\t\t\t       ren1->dst, branchName2);\n+\t\t\t\t       ren1_src, ren1_dst, branchName1,\n+\t\t\t\t       ren1_dst, branchName2);\n+\t\t\t\tnewPath = unique_path(ren1_dst, branchName2);\n \t\t\t\toutput(\"Adding as %s instead\", newPath);\n \t\t\t\tupdate_file(fp, 0, dstShaOtherBranch, dstModeOtherBranch, newPath);\n+\t\t\t} else if ( (ren2 = find_rename_bydst(renames2, ren1_dst)) ) {\n \t\t\t\tcleanMerge = 0;\n-\t\t\t\ttryMerge = 1;\n-\t\t\t} else if ( (dst2 = find_rename_bydst(renames2, ren1->dst)) ) {\n-\t\t\t\tchar *newPath1 = unique_path(ren1->dst, branchName1);\n-\t\t\t\tchar *newPath2 = unique_path(dst2->dst, branchName2);\n+\t\t\t\tren2->processed = 1;\n \t\t\t\toutput(\"CONFLICT (rename/rename): Rename %s->%s in %s. \"\n \t\t\t\t       \"Rename %s->%s in %s\",\n-\t\t\t\t       ren1->src, ren1->dst, branchName1,\n-\t\t\t\t       dst2->src, dst2->dst, branchName2);\n-\t\t\t\toutput(\"Renaming %s to %s and %s to %s instead\",\n-\t\t\t\t       ren1->src, newPath1, dst2->src, newPath2);\n-\t\t\t\tremove_file(fp, 0, ren1->dst);\n-\t\t\t\tupdate_file(fp, 0, ren1->dst_sha, ren1->dst_mode, newPath1);\n-\t\t\t\tupdate_file(fp, 0, dst2->dst_sha, dst2->dst_mode, newPath2);\n-\t\t\t\tdst2->processed = 1;\n-\t\t\t\tcleanMerge = 0;\n+\t\t\t\t       ren1_src, ren1_dst, branchName1,\n+\t\t\t\t       ren2->pair->one->path, ren2->pair->two->path, branchName2);\n+\t\t\t\tconflict_rename_rename_2(fp, ren1, branchName1, ren2, branchName2);\n \t\t\t} else\n \t\t\t\ttryMerge = 1;\n \n \t\t\tif ( tryMerge ) {\n-\t\t\t\tchar *oname = ren1->src;\n-\t\t\t\tchar *aname = ren1->dst;\n-\t\t\t\tchar *bname = ren1->src;\n+\t\t\t\tconst char *oname = ren1_src;\n+\t\t\t\tconst char *aname = ren1_dst;\n+\t\t\t\tconst char *bname = ren1_src;\n \t\t\t\tunsigned char osha[20], asha[20], bsha[20];\n-\t\t\t\tunsigned omode = ren1->src_mode;\n-\t\t\t\tunsigned amode = ren1->dst_mode;\n+\t\t\t\tunsigned omode = ren1->pair->one->mode;\n+\t\t\t\tunsigned amode = ren1->pair->two->mode;\n \t\t\t\tunsigned bmode = srcModeOtherBranch;\n-\t\t\t\tmemcpy(osha, ren1->src_sha, 20);\n-\t\t\t\tmemcpy(asha, ren1->dst_sha, 20);\n+\t\t\t\tmemcpy(osha, ren1->pair->one->sha1, 20);\n+\t\t\t\tmemcpy(asha, ren1->pair->two->sha1, 20);\n \t\t\t\tmemcpy(bsha, srcShaOtherBranch, 20);\n \t\t\t\tconst char *aBranch = branchName1;\n \t\t\t\tconst char *bBranch = branchName2;\n@@ -1234,23 +1261,23 @@ static int process_renames(struct rename\n \t\t\t\t\t\t aBranch, bBranch);\n \n \t\t\t\tif ( mfi.merge || !mfi.clean )\n-\t\t\t\t\toutput(\"Renaming %s => %s\", ren1->src, ren1->dst);\n+\t\t\t\t\toutput(\"Renaming %s => %s\", ren1_src, ren1_dst);\n \t\t\t\tif ( mfi.merge )\n-\t\t\t\t\toutput(\"Auto-merging %s\", ren1->dst);\n+\t\t\t\t\toutput(\"Auto-merging %s\", ren1_dst);\n \t\t\t\tif ( !mfi.clean ) {\n \t\t\t\t\toutput(\"CONFLICT (rename/modify): Merge conflict in %s\",\n-\t\t\t\t\t       ren1->dst);\n+\t\t\t\t\t       ren1_dst);\n \t\t\t\t\tcleanMerge = 0;\n \n \t\t\t\t\tif ( !index_only )\n \t\t\t\t\t\tupdate_stages(fp,\n-\t\t\t\t\t\t\t       ren1->dst,\n-\t\t\t\t\t\t\t       osha, omode,\n-\t\t\t\t\t\t\t       asha, amode,\n-\t\t\t\t\t\t\t       bsha, bmode,\n-\t\t\t\t\t\t\t       1 /* clear */);\n+\t\t\t\t\t\t\t      ren1_dst,\n+\t\t\t\t\t\t\t      osha, omode,\n+\t\t\t\t\t\t\t      asha, amode,\n+\t\t\t\t\t\t\t      bsha, bmode,\n+\t\t\t\t\t\t\t      1 /* clear */);\n \t\t\t\t}\n-\t\t\t\tupdate_file(fp, mfi.clean, mfi.sha, mfi.mode, ren1->dst);\n+\t\t\t\tupdate_file(fp, mfi.clean, mfi.sha, mfi.mode, ren1_dst);\n \t\t\t}\n \t\t}\n \t}\n@@ -1451,16 +1478,18 @@ static struct merge_tree_result merge_tr\n \t\t\tif (!process_entry(fp, e, branch1Name, branch2Name))\n \t\t\t\tresult.clean = 0;\n \t\t}\n+\t\tfree_rename_entries(&re_merge);\n+\t\tfree_rename_entries(&re_head);\n+\t\tfree_index_entries(&entries);\n+\n \t\tif (pclose(fp))\n \t\t\tdie(\"updating entry failed in git update-index\");\n+\n \t\tif (result.clean || index_only)\n \t\t\tresult.tree = git_write_tree();\n \t\telse\n \t\t\tresult.tree = NULL;\n \t\tdebug(\"\\t  processing entries done\\n\");\n-\t\tfree_rename_entries(&re_merge);\n-\t\tfree_rename_entries(&re_head);\n-\t\tfree_index_entries(&entries);\n \t} else {\n \t\tresult.clean = 1;\n \t\tprintf(\"merging of trees %s and %s resulted in %s\\n\",\n-- \n1.4.1.rc1.g17dc\n"}]}