diff options
-rw-r--r-- | Documentation/diff-options.txt | 4 | ||||
-rw-r--r-- | diff.c | 88 | ||||
-rw-r--r-- | diff.h | 3 | ||||
-rwxr-xr-x | git-format-patch.sh | 2 | ||||
-rwxr-xr-x | git-merge.sh | 3 | ||||
-rwxr-xr-x | git-request-pull.sh | 2 |
6 files changed, 96 insertions, 6 deletions
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index c183dc9da0..f523ec2fbe 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -10,6 +10,10 @@ --stat:: Generate a diffstat instead of a patch. +--summary:: + Output a condensed summary of extended header information + such as creations, renames and mode changes. + --patch-with-stat:: Generate patch and prepend its diffstat. @@ -1283,6 +1283,8 @@ 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, "--summary")) + options->summary = 1; else if (!strcmp(arg, "--patch-with-stat")) { options->output_format = DIFF_FORMAT_PATCH; options->with_stat = 1; @@ -1753,6 +1755,85 @@ static void flush_one_pair(struct diff_filepair *p, } } +static void show_file_mode_name(const char *newdelete, struct diff_filespec *fs) +{ + if (fs->mode) + printf(" %s mode %06o %s\n", newdelete, fs->mode, fs->path); + else + printf(" %s %s\n", newdelete, fs->path); +} + + +static void show_mode_change(struct diff_filepair *p, int show_name) +{ + if (p->one->mode && p->two->mode && p->one->mode != p->two->mode) { + if (show_name) + printf(" mode change %06o => %06o %s\n", + p->one->mode, p->two->mode, p->two->path); + else + printf(" mode change %06o => %06o\n", + p->one->mode, p->two->mode); + } +} + +static void show_rename_copy(const char *renamecopy, struct diff_filepair *p) +{ + const char *old, *new; + + /* Find common prefix */ + old = p->one->path; + new = p->two->path; + while (1) { + const char *slash_old, *slash_new; + slash_old = strchr(old, '/'); + slash_new = strchr(new, '/'); + if (!slash_old || + !slash_new || + slash_old - old != slash_new - new || + memcmp(old, new, slash_new - new)) + break; + old = slash_old + 1; + new = slash_new + 1; + } + /* p->one->path thru old is the common prefix, and old and new + * through the end of names are renames + */ + if (old != p->one->path) + printf(" %s %.*s{%s => %s} (%d%%)\n", renamecopy, + (int)(old - p->one->path), p->one->path, + old, new, (int)(0.5 + p->score * 100.0/MAX_SCORE)); + else + printf(" %s %s => %s (%d%%)\n", renamecopy, + p->one->path, p->two->path, + (int)(0.5 + p->score * 100.0/MAX_SCORE)); + show_mode_change(p, 0); +} + +static void diff_summary(struct diff_filepair *p) +{ + switch(p->status) { + case DIFF_STATUS_DELETED: + show_file_mode_name("delete", p->one); + break; + case DIFF_STATUS_ADDED: + show_file_mode_name("create", p->two); + break; + case DIFF_STATUS_COPIED: + show_rename_copy("copy", p); + break; + case DIFF_STATUS_RENAMED: + show_rename_copy("rename", p); + break; + default: + if (p->score) { + printf(" rewrite %s (%d%%)\n", p->two->path, + (int)(0.5 + p->score * 100.0/MAX_SCORE)); + show_mode_change(p, 0); + } else show_mode_change(p, 1); + break; + } +} + void diff_flush(struct diff_options *options) { struct diff_queue_struct *q = &diff_queued_diff; @@ -1786,7 +1867,6 @@ void diff_flush(struct diff_options *options) for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; flush_one_pair(p, diff_output_format, options, diffstat); - diff_free_filepair(p); } if (diffstat) { @@ -1794,6 +1874,12 @@ void diff_flush(struct diff_options *options) free(diffstat); } + for (i = 0; i < q->nr; i++) { + if (options->summary) + diff_summary(q->queue[i]); + diff_free_filepair(q->queue[i]); + } + free(q->queue); q->queue = NULL; q->nr = q->alloc = 0; @@ -31,7 +31,8 @@ struct diff_options { binary:1, full_index:1, silent_on_remove:1, - find_copies_harder:1; + find_copies_harder:1, + summary:1; int context; int break_opt; int detect_rename; diff --git a/git-format-patch.sh b/git-format-patch.sh index c077f44ca1..8a16eadfbd 100755 --- a/git-format-patch.sh +++ b/git-format-patch.sh @@ -274,7 +274,7 @@ print "\n---\n\n"; close FH or die "close $commsg pipe"; ' "$keep_subject" "$num" "$signoff" "$headers" "$mimemagic" $commsg - git-diff-tree -p $diff_opts "$commit" | git-apply --stat --summary + git-diff-tree -p --stat --summary $diff_opts "$commit" echo case "$mimemagic" in '');; diff --git a/git-merge.sh b/git-merge.sh index b834e79c98..af1f25b3c5 100755 --- a/git-merge.sh +++ b/git-merge.sh @@ -55,8 +55,7 @@ finish () { case "$no_summary" in '') - git-diff-tree -p -M "$head" "$1" | - git-apply --stat --summary + git-diff-tree -p --stat --summary -M "$head" "$1" ;; esac } diff --git a/git-request-pull.sh b/git-request-pull.sh index 2c48bfb299..4319e35c62 100755 --- a/git-request-pull.sh +++ b/git-request-pull.sh @@ -30,4 +30,4 @@ echo " $url" echo git log $baserev..$headrev | git-shortlog ; -git diff $baserev..$headrev | git-apply --stat --summary +git diff --stat --summary $baserev..$headrev |