{"thread":{"id":"45790","subject":"[PATCH 1/2] fast-export: deletion action first","startedAt":"2017-04-25T00:04:47Z","lastAt":"2017-04-25T00:04:48Z","messageCount":2,"participants":["Miguel Torroja"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"317741","messageId":"1493078668-1354-1-git-send-email-miguel.torroja@gmail.com","threadId":"45790","inReplyTo":null,"subject":"[PATCH 1/2] fast-export: deletion action first","fromName":"Miguel Torroja","fromEmail":"miguel.torroja@gmail.com","sentAt":"2017-04-25T00:04:27Z","receivedAt":"2017-04-25T00:04:47Z","isPatch":true,"sender":{"key":"miguel.torroja@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5366212?v=4"},"body":"The delete operations of the fast-export output should precede any addition\nbelonging to the same commit, Addition and deletion with the same name\nentry could happen in case of file to directory and viceversa.\n\nThe fast-export sorting was added in 060df62 (fast-export: Fix output\norder of D/F changes). That change was made in order to fix the case of\ndirectory to file in the same commit, but it broke the reverse case\n(File to directory).\n\nSigned-off-by: Miguel Torroja <miguel.torroja@gmail.com>\n---\n builtin/fast-export.c | 25 +++++++++----------------\n 1 file changed, 9 insertions(+), 16 deletions(-)\n\ndiff --git a/builtin/fast-export.c b/builtin/fast-export.c\nindex e022063..a3ab7da 100644\n--- a/builtin/fast-export.c\n+++ b/builtin/fast-export.c\n@@ -260,26 +260,19 @@ static void export_blob(const struct object_id *oid)\n \t\tfree(buf);\n }\n \n-static int depth_first(const void *a_, const void *b_)\n+/*\n+ * Compares two diff types to order based on output priorities.\n+ */\n+static int diff_type_cmp(const void *a_, const void *b_)\n {\n \tconst struct diff_filepair *a = *((const struct diff_filepair **)a_);\n \tconst struct diff_filepair *b = *((const struct diff_filepair **)b_);\n-\tconst char *name_a, *name_b;\n-\tint len_a, len_b, len;\n \tint cmp;\n \n-\tname_a = a->one ? a->one->path : a->two->path;\n-\tname_b = b->one ? b->one->path : b->two->path;\n-\n-\tlen_a = strlen(name_a);\n-\tlen_b = strlen(name_b);\n-\tlen = (len_a < len_b) ? len_a : len_b;\n-\n-\t/* strcmp will sort 'd' before 'd/e', we want 'd/e' before 'd' */\n-\tcmp = memcmp(name_a, name_b, len);\n-\tif (cmp)\n-\t\treturn cmp;\n-\tcmp = len_b - len_a;\n+\t/*\n+\t * Move Delete entries first so that an addition is always reported after\n+\t */\n+\tcmp = (b->status == DIFF_STATUS_DELETED) - (a->status == DIFF_STATUS_DELETED);\n \tif (cmp)\n \t\treturn cmp;\n \t/*\n@@ -347,7 +340,7 @@ static void show_filemodify(struct diff_queue_struct *q,\n \t * Handle files below a directory first, in case they are all deleted\n \t * and the directory changes to a file or symlink.\n \t */\n-\tQSORT(q->queue, q->nr, depth_first);\n+\tQSORT(q->queue, q->nr, diff_type_cmp);\n \n \tfor (i = 0; i < q->nr; i++) {\n \t\tstruct diff_filespec *ospec = q->queue[i]->one;\n-- \n2.1.4\n\n"},{"id":"317742","messageId":"1493078668-1354-2-git-send-email-miguel.torroja@gmail.com","threadId":"45790","inReplyTo":"1493078668-1354-1-git-send-email-miguel.torroja@gmail.com","subject":"[PATCH 2/2] fast-export: DIFF_STATUS_RENAMED instead of 'R'","fromName":"Miguel Torroja","fromEmail":"miguel.torroja@gmail.com","sentAt":"2017-04-25T00:04:28Z","receivedAt":"2017-04-25T00:04:48Z","isPatch":true,"sender":{"key":"miguel.torroja@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5366212?v=4"},"body":"Minor change to be consistent with the rest of the fast-export code.\nDIFF_STATUS_RENAMED is defined as 'R'.\n\nSigned-off-by: Miguel Torroja <miguel.torroja@gmail.com>\n---\n builtin/fast-export.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/builtin/fast-export.c b/builtin/fast-export.c\nindex a3ab7da..4d39324 100644\n--- a/builtin/fast-export.c\n+++ b/builtin/fast-export.c\n@@ -280,7 +280,7 @@ static int diff_type_cmp(const void *a_, const void *b_)\n \t * appear in the output before it is renamed (e.g., when a file\n \t * was copied and renamed in the same commit).\n \t */\n-\treturn (a->status == 'R') - (b->status == 'R');\n+\treturn (a->status == DIFF_STATUS_RENAMED) - (b->status == DIFF_STATUS_RENAMED);\n }\n \n static void print_path_1(const char *path)\n-- \n2.1.4\n\n"}]}