{"thread":{"id":"3846","subject":"[PATCH] Support printing diffs in the raw and patch format at once","startedAt":"2006-04-10T23:55:39Z","lastAt":"2006-04-10T23:55:39Z","messageCount":1,"participants":["Petr Baudis"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"18550","messageId":"20060410235539.2690.45543.stgit@machine.or.cz","threadId":"3846","inReplyTo":null,"subject":"[PATCH] Support printing diffs in the raw and patch format at once","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-04-10T23:55:39Z","receivedAt":"2006-04-10T23:55:39Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"This is required when using cg-Xfollowrenames as a backend for\na tool which wants to show the end-user patches; parsing patches\nproperly is a nightmare, so we need to receive the diff in the\nraw diff format from git-diff-tree, while also receiving the diff\nin the patch format for further processing by the frontend.\n\nThis patch adds a -P option which is similar to the -p option\nand achieves this. First the raw diff format is printed, then\na line terminator and then the patch.\n\nIt is fairly simple and should be straightforward, so it would be\ngreat if this could yet make it to 1.3.0, or cg-log patch output\nwould have to stay with broken rename detection until the next Git\nmajor release. :-(\n\nSigned-off-by: Petr Baudis <pasky@suse.cz>\n---\n\n Documentation/diff-options.txt |    3 +++\n combine-diff.c                 |   32 ++++++++++++++++++++++++++------\n diff-files.c                   |    2 +-\n diff-index.c                   |    2 +-\n diff-stages.c                  |    2 +-\n diff-tree.c                    |    4 ++--\n diff.c                         |   29 +++++++++++++++++++++--------\n diff.h                         |    3 ++-\n 8 files changed, 57 insertions(+), 20 deletions(-)\n\ndiff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt\nindex ec6811c..67c8867 100644\n--- a/Documentation/diff-options.txt\n+++ b/Documentation/diff-options.txt\n@@ -4,6 +4,9 @@\n -u::\n \tSynonym for \"-p\".\n \n+-P::\n+\tGenerate patch but keep also the default raw diff output.\n+\n -z::\n \t\\0 line termination on output\n \ndiff --git a/combine-diff.c b/combine-diff.c\nindex eb0d757..65e110e 100644\n--- a/combine-diff.c\n+++ b/combine-diff.c\n@@ -816,10 +816,33 @@ int show_combined_diff(struct combine_di\n \n \tdefault:\n \tcase DIFF_FORMAT_PATCH:\n+\tcase DIFF_FORMAT_RAW_PATCH:\n \t\treturn show_patch_diff(p, num_parent, dense, header, opt);\n \t}\n }\n \n+const char *show_combined_diffs(struct combine_diff_path *paths,\n+                                int num_parent, int dense,\n+\t\t\t\tconst char *header, struct diff_options *opt)\n+{\n+\tstruct combine_diff_path *p;\n+\n+\tif (opt->output_format == DIFF_FORMAT_RAW_PATCH) {\n+\t\topt->output_format = DIFF_FORMAT_RAW;\n+\t\theader = show_combined_diffs(paths, num_parent, dense,\n+\t\t                             header, opt);\n+\t\tputchar(opt->line_termination);\n+\t\topt->output_format = DIFF_FORMAT_RAW_PATCH;\n+\t}\n+\n+\tfor (p = paths; p; p = p->next) {\n+\t\tif (show_combined_diff(p, num_parent, dense,\n+\t\t\t\t       header, opt))\n+\t\t\theader = NULL;\n+\t}\n+\treturn header;\n+}\n+\n const char *diff_tree_combined_merge(const unsigned char *sha1,\n \t\t\t     const char *header, int dense,\n \t\t\t     struct diff_options *opt)\n@@ -849,7 +872,7 @@ const char *diff_tree_combined_merge(con\n \t\t\t       &diffopts);\n \t\tdiffcore_std(&diffopts);\n \t\tpaths = intersect_paths(paths, i, num_parent);\n-\t\tdiff_flush(&diffopts);\n+\t\tdiff_flush(&diffopts, 1);\n \t}\n \n \t/* find out surviving paths */\n@@ -858,11 +881,8 @@ const char *diff_tree_combined_merge(con\n \t\t\tnum_paths++;\n \t}\n \tif (num_paths) {\n-\t\tfor (p = paths; p; p = p->next) {\n-\t\t\tif (show_combined_diff(p, num_parent, dense,\n-\t\t\t\t\t       header, opt))\n-\t\t\t\theader = NULL;\n-\t\t}\n+\t\theader = show_combined_diffs(paths, num_parent, dense,\n+\t\t                             header, opt);\n \t}\n \n \t/* Clean things up */\ndiff --git a/diff-files.c b/diff-files.c\nindex 3e7f5f1..4e2e5cb 100644\n--- a/diff-files.c\n+++ b/diff-files.c\n@@ -208,6 +208,6 @@ int main(int argc, const char **argv)\n \t\t\t      ce->name);\n \t}\n \tdiffcore_std(&diff_options);\n-\tdiff_flush(&diff_options);\n+\tdiff_flush(&diff_options, 1);\n \treturn 0;\n }\ndiff --git a/diff-index.c b/diff-index.c\nindex e376d65..dade539 100644\n--- a/diff-index.c\n+++ b/diff-index.c\n@@ -248,6 +248,6 @@ int main(int argc, const char **argv)\n \tret = diff_cache(active_cache, active_nr, pathspec);\n \n \tdiffcore_std(&diff_options);\n-\tdiff_flush(&diff_options);\n+\tdiff_flush(&diff_options, 1);\n \treturn ret;\n }\ndiff --git a/diff-stages.c b/diff-stages.c\nindex dcd20e7..fa146a9 100644\n--- a/diff-stages.c\n+++ b/diff-stages.c\n@@ -99,6 +99,6 @@ int main(int ac, const char **av)\n \n \tdiff_stages(stage1, stage2, pathspec);\n \tdiffcore_std(&diff_options);\n-\tdiff_flush(&diff_options);\n+\tdiff_flush(&diff_options, 1);\n \treturn 0;\n }\ndiff --git a/diff-tree.c b/diff-tree.c\nindex d1265d7..5327df8 100644\n--- a/diff-tree.c\n+++ b/diff-tree.c\n@@ -23,7 +23,7 @@ static int call_diff_flush(void)\n \tif (diff_queue_is_empty()) {\n \t\tint saved_fmt = diff_options.output_format;\n \t\tdiff_options.output_format = DIFF_FORMAT_NO_OUTPUT;\n-\t\tdiff_flush(&diff_options);\n+\t\tdiff_flush(&diff_options, 1);\n \t\tdiff_options.output_format = saved_fmt;\n \t\treturn 0;\n \t}\n@@ -32,7 +32,7 @@ static int call_diff_flush(void)\n \t\t\tprintf(\"%s%c\", header, diff_options.line_termination);\n \t\theader = NULL;\n \t}\n-\tdiff_flush(&diff_options);\n+\tdiff_flush(&diff_options, 1);\n \treturn 1;\n }\n \ndiff --git a/diff.c b/diff.c\nindex 2fa285a..f57d82e 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -862,6 +862,8 @@ int diff_opt_parse(struct diff_options *\n \tconst char *arg = av[0];\n \tif (!strcmp(arg, \"-p\") || !strcmp(arg, \"-u\"))\n \t\toptions->output_format = DIFF_FORMAT_PATCH;\n+\telse if (!strcmp(arg, \"-P\"))\n+\t\toptions->output_format = DIFF_FORMAT_RAW_PATCH;\n \telse if (!strcmp(arg, \"-z\"))\n \t\toptions->line_termination = 0;\n \telse if (!strncmp(arg, \"-l\", 2))\n@@ -1270,7 +1272,7 @@ static void diff_resolve_rename_copy(voi\n \tdiff_debug_queue(\"resolve-rename-copy done\", q);\n }\n \n-void diff_flush(struct diff_options *options)\n+void diff_flush(struct diff_options *options, int shall_free)\n {\n \tstruct diff_queue_struct *q = &diff_queued_diff;\n \tint i;\n@@ -1278,6 +1280,13 @@ void diff_flush(struct diff_options *opt\n \tint diff_output_format = options->output_format;\n \tint line_termination = options->line_termination;\n \n+\tif (diff_output_format == DIFF_FORMAT_RAW_PATCH) {\n+\t\toptions->output_format = DIFF_FORMAT_RAW;\n+\t\tdiff_flush(options, 0);\n+\t\tputchar(options->line_termination);\n+\t\toptions->output_format = DIFF_FORMAT_RAW_PATCH;\n+\t}\n+\n \tif (!line_termination)\n \t\tinter_name_termination = 0;\n \n@@ -1292,15 +1301,16 @@ void diff_flush(struct diff_options *opt\n \t\t\tbreak;\n \t\tdefault:\n \t\t\tswitch (diff_output_format) {\n-\t\t\tcase DIFF_FORMAT_PATCH:\n-\t\t\t\tdiff_flush_patch(p, options);\n-\t\t\t\tbreak;\n \t\t\tcase DIFF_FORMAT_RAW:\n \t\t\tcase DIFF_FORMAT_NAME_STATUS:\n \t\t\t\tdiff_flush_raw(p, line_termination,\n \t\t\t\t\t       inter_name_termination,\n \t\t\t\t\t       options);\n \t\t\t\tbreak;\n+\t\t\tcase DIFF_FORMAT_PATCH:\n+\t\t\tcase DIFF_FORMAT_RAW_PATCH:\n+\t\t\t\tdiff_flush_patch(p, options);\n+\t\t\t\tbreak;\n \t\t\tcase DIFF_FORMAT_NAME:\n \t\t\t\tdiff_flush_name(p,\n \t\t\t\t\t\tinter_name_termination,\n@@ -1310,11 +1320,14 @@ void diff_flush(struct diff_options *opt\n \t\t\t\tbreak;\n \t\t\t}\n \t\t}\n-\t\tdiff_free_filepair(p);\n+\t\tif (shall_free)\n+\t\t\tdiff_free_filepair(p);\n \t}\n-\tfree(q->queue);\n-\tq->queue = NULL;\n-\tq->nr = q->alloc = 0;\n+\tif (shall_free) {\n+\t\tfree(q->queue);\n+\t\tq->queue = NULL;\n+\t\tq->nr = q->alloc = 0;\n+\t}\n }\n \n static void diffcore_apply_filter(const char *filter)\ndiff --git a/diff.h b/diff.h\nindex a02ef28..a2dacac 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -135,8 +135,9 @@ #define DIFF_FORMAT_PATCH\t2\n #define DIFF_FORMAT_NO_OUTPUT\t3\n #define DIFF_FORMAT_NAME\t4\n #define DIFF_FORMAT_NAME_STATUS\t5\n+#define DIFF_FORMAT_RAW_PATCH\t6\n \n-extern void diff_flush(struct diff_options*);\n+extern void diff_flush(struct diff_options *, int shall_free);\n \n /* diff-raw status letters */\n #define DIFF_STATUS_ADDED\t\t'A'\n"}]}