From 6f4780f9dfd3bc6b23f9ea66b3d49577e0a0c2f9 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 15 Apr 2006 14:02:10 -0700 Subject: [PATCH 1/4] diff --stat: do not do its own three-dashes. I missed that "git-diff-* --stat" spits out three-dash separator on its own without being asked. Remove it. When we output commit log followed by diff, perhaps --patch-with-stat, for downstream consumer, we _would_ want the three-dash between the message and the diff material, but that logic belongs to the caller, not diff generator. Signed-off-by: Junio C Hamano --- diff.c | 2 -- git.c | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/diff.c b/diff.c index f1b672d2dc..cda8d2069e 100644 --- a/diff.c +++ b/diff.c @@ -245,8 +245,6 @@ static void show_stats(struct diffstat_t* data) if (data->nr == 0) return; - printf("---\n"); - for (i = 0; i < data->nr; i++) { struct diffstat_file *file = data->files[i]; diff --git a/git.c b/git.c index 78ed403ed1..61265a8566 100644 --- a/git.c +++ b/git.c @@ -388,8 +388,10 @@ static int cmd_log(int argc, const char **argv, char **envp) pretty_print_commit(commit_format, commit, ~0, buf, LOGSIZE, abbrev); printf("%s\n", buf); - if (do_diff) + if (do_diff) { + printf("---\n"); log_tree_commit(&opt, commit); + } shown = 1; free(commit->buffer); commit->buffer = NULL; From 1cd95087c331e17c44a8b62f0614d55e621dcfd4 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 15 Apr 2006 11:13:49 -0700 Subject: [PATCH 2/4] Support "git cmd --help" syntax The "--help" argument is special, in that it is (along with "--version") in that is taken by the "git" program itself rather than the sub-command, and thus we've had the syntax "git --help cmd". However, as anybody who has ever used CVS or some similar devil-spawn program, it's confusing as h*ll when options before the sub-command act differently from options after the sub-command, so this quick hack just makes it acceptable to do "git cmd --help" instead, and get the exact same result. It may be hacky, but it's simple and does the trick. Of course, this does not help if you use one of the non-builtin commands without using the "git" helper. Ie you won't be getting a man-page just because you do "git-rev-list --help". Don't expect us to be quite _that_ helpful. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- git.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/git.c b/git.c index 61265a8566..140ed1873d 100644 --- a/git.c +++ b/git.c @@ -413,6 +413,12 @@ static void handle_internal_command(int argc, const char **argv, char **envp) }; int i; + /* Turn "git cmd --help" into "git help cmd" */ + if (argc > 1 && !strcmp(argv[1], "--help")) { + argv[1] = argv[0]; + argv[0] = cmd = "help"; + } + for (i = 0; i < ARRAY_SIZE(commands); i++) { struct cmd_struct *p = commands+i; if (strcmp(p->cmd, cmd)) From cbdda024049947366804d60bdc5e5fc3ab3ee3a5 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 15 Apr 2006 18:38:32 -0700 Subject: [PATCH 3/4] diff-files --stat: do not dump core with unmerged index. Signed-off-by: Junio C Hamano --- diff.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/diff.c b/diff.c index cda8d2069e..46e8529a64 100644 --- a/diff.c +++ b/diff.c @@ -202,6 +202,8 @@ struct diffstat_t { int alloc; struct diffstat_file { char *name; + unsigned is_unmerged:1; + unsigned is_binary:1; unsigned int added, deleted; } **files; }; @@ -248,6 +250,8 @@ static void show_stats(struct diffstat_t* data) for (i = 0; i < data->nr; i++) { struct diffstat_file *file = data->files[i]; + if (file->is_binary || file->is_unmerged) + continue; if (max_change < file->added + file->deleted) max_change = file->added + file->deleted; len = strlen(file->name); @@ -292,11 +296,15 @@ static void show_stats(struct diffstat_t* data) if (max + len > 70) max = 70 - len; - if (added < 0) { - /* binary file */ + if (data->files[i]->is_binary) { printf(" %s%-*s | Bin\n", prefix, len, name); goto free_diffstat_file; - } else if (added + deleted == 0) { + } + else if (data->files[i]->is_unmerged) { + printf(" %s%-*s | Unmerged\n", prefix, len, name); + goto free_diffstat_file; + } + else if (added + deleted == 0) { total_files--; goto free_diffstat_file; } @@ -424,11 +432,16 @@ static void builtin_diffstat(const char *name_a, const char *name_b, data = diffstat_add(diffstat, name_a ? name_a : name_b); + if (!one || !two) { + data->is_unmerged = 1; + return; + } + if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0) die("unable to read files to diff"); if (mmfile_is_binary(&mf1) || mmfile_is_binary(&mf2)) - data->added = -1; + data->is_binary = 1; else { /* Crazy xdl interfaces.. */ xpparam_t xpp; From 293532739415d287786a312ec10849723383796e Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sat, 15 Apr 2006 13:41:18 +0200 Subject: [PATCH 4/4] diff-options: add --patch-with-stat With this option, git prepends a diffstat in front of the patch. Since I really, really do not know what a diffstat of a combined diff ("merge diff") should look like, the diffstat is not generated for these. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/diff-options.txt | 3 +++ diff.c | 17 ++++++++++++++++- diff.h | 3 +++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index 447e522a7b..c183dc9da0 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -10,6 +10,9 @@ --stat:: Generate a diffstat instead of a patch. +--patch-with-stat:: + Generate patch and prepend its diffstat. + -z:: \0 line termination on output diff --git a/diff.c b/diff.c index 46e8529a64..b54bbfa627 100644 --- a/diff.c +++ b/diff.c @@ -1060,6 +1060,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) } else if (!strcmp(arg, "--stat")) options->output_format = DIFF_FORMAT_DIFFSTAT; + else if (!strcmp(arg, "--patch-with-stat")) { + options->output_format = DIFF_FORMAT_PATCH; + options->with_stat = 1; + } else if (!strcmp(arg, "-z")) options->line_termination = 0; else if (!strncmp(arg, "-l", 2)) @@ -1529,7 +1533,7 @@ void diff_flush(struct diff_options *options) int diff_output_format = options->output_format; struct diffstat_t *diffstat = NULL; - if (diff_output_format == DIFF_FORMAT_DIFFSTAT) { + if (diff_output_format == DIFF_FORMAT_DIFFSTAT || options->with_stat) { diffstat = xcalloc(sizeof (struct diffstat_t), 1); diffstat->xm.consume = diffstat_consume; } @@ -1541,6 +1545,17 @@ void diff_flush(struct diff_options *options) } putchar(options->line_termination); } + if (options->with_stat) { + for (i = 0; i < q->nr; i++) { + struct diff_filepair *p = q->queue[i]; + flush_one_pair(p, DIFF_FORMAT_DIFFSTAT, options, + diffstat); + } + show_stats(diffstat); + free(diffstat); + diffstat = NULL; + putchar(options->line_termination); + } for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; flush_one_pair(p, diff_output_format, options, diffstat); diff --git a/diff.h b/diff.h index 2f8aff2cd4..f783baef14 100644 --- a/diff.h +++ b/diff.h @@ -25,6 +25,7 @@ struct diff_options { const char *pickaxe; unsigned recursive:1, with_raw:1, + with_stat:1, tree_in_recursive:1, full_index:1; int break_opt; @@ -120,6 +121,8 @@ extern void diffcore_std_no_resolve(struct diff_options *); " --patch-with-raw\n" \ " output both a patch and the diff-raw format.\n" \ " --stat show diffstat instead of patch.\n" \ +" --patch-with-stat\n" \ +" output a patch and prepend its diffstat.\n" \ " --name-only show only names of changed files.\n" \ " --name-status show names and status of changed files.\n" \ " --full-index show full object name on index lines.\n" \