builtin / blame.con commit builtin/blame: highlight recently changed lines (25d5f52)
   1/*
   2 * Blame
   3 *
   4 * Copyright (c) 2006, 2014 by its authors
   5 * See COPYING for licensing conditions
   6 */
   7
   8#include "cache.h"
   9#include "config.h"
  10#include "color.h"
  11#include "builtin.h"
  12#include "commit.h"
  13#include "diff.h"
  14#include "revision.h"
  15#include "quote.h"
  16#include "string-list.h"
  17#include "mailmap.h"
  18#include "parse-options.h"
  19#include "prio-queue.h"
  20#include "utf8.h"
  21#include "userdiff.h"
  22#include "line-range.h"
  23#include "line-log.h"
  24#include "dir.h"
  25#include "progress.h"
  26#include "blame.h"
  27#include "string-list.h"
  28
  29static char blame_usage[] = N_("git blame [<options>] [<rev-opts>] [<rev>] [--] <file>");
  30
  31static const char *blame_opt_usage[] = {
  32        blame_usage,
  33        "",
  34        N_("<rev-opts> are documented in git-rev-list(1)"),
  35        NULL
  36};
  37
  38static int longest_file;
  39static int longest_author;
  40static int max_orig_digits;
  41static int max_digits;
  42static int max_score_digits;
  43static int show_root;
  44static int reverse;
  45static int blank_boundary;
  46static int incremental;
  47static int xdl_opts;
  48static int abbrev = -1;
  49static int no_whole_file_rename;
  50static int show_progress;
  51static char repeated_meta_color[COLOR_MAXLEN];
  52
  53static struct date_mode blame_date_mode = { DATE_ISO8601 };
  54static size_t blame_date_width;
  55
  56static struct string_list mailmap = STRING_LIST_INIT_NODUP;
  57
  58#ifndef DEBUG
  59#define DEBUG 0
  60#endif
  61
  62static unsigned blame_move_score;
  63static unsigned blame_copy_score;
  64
  65/* Remember to update object flag allocation in object.h */
  66#define METAINFO_SHOWN          (1u<<12)
  67#define MORE_THAN_ONE_PATH      (1u<<13)
  68
  69struct progress_info {
  70        struct progress *progress;
  71        int blamed_lines;
  72};
  73
  74static const char *nth_line_cb(void *data, long lno)
  75{
  76        return blame_nth_line((struct blame_scoreboard *)data, lno);
  77}
  78
  79/*
  80 * Information on commits, used for output.
  81 */
  82struct commit_info {
  83        struct strbuf author;
  84        struct strbuf author_mail;
  85        timestamp_t author_time;
  86        struct strbuf author_tz;
  87
  88        /* filled only when asked for details */
  89        struct strbuf committer;
  90        struct strbuf committer_mail;
  91        timestamp_t committer_time;
  92        struct strbuf committer_tz;
  93
  94        struct strbuf summary;
  95};
  96
  97/*
  98 * Parse author/committer line in the commit object buffer
  99 */
 100static void get_ac_line(const char *inbuf, const char *what,
 101        struct strbuf *name, struct strbuf *mail,
 102        timestamp_t *time, struct strbuf *tz)
 103{
 104        struct ident_split ident;
 105        size_t len, maillen, namelen;
 106        char *tmp, *endp;
 107        const char *namebuf, *mailbuf;
 108
 109        tmp = strstr(inbuf, what);
 110        if (!tmp)
 111                goto error_out;
 112        tmp += strlen(what);
 113        endp = strchr(tmp, '\n');
 114        if (!endp)
 115                len = strlen(tmp);
 116        else
 117                len = endp - tmp;
 118
 119        if (split_ident_line(&ident, tmp, len)) {
 120        error_out:
 121                /* Ugh */
 122                tmp = "(unknown)";
 123                strbuf_addstr(name, tmp);
 124                strbuf_addstr(mail, tmp);
 125                strbuf_addstr(tz, tmp);
 126                *time = 0;
 127                return;
 128        }
 129
 130        namelen = ident.name_end - ident.name_begin;
 131        namebuf = ident.name_begin;
 132
 133        maillen = ident.mail_end - ident.mail_begin;
 134        mailbuf = ident.mail_begin;
 135
 136        if (ident.date_begin && ident.date_end)
 137                *time = strtoul(ident.date_begin, NULL, 10);
 138        else
 139                *time = 0;
 140
 141        if (ident.tz_begin && ident.tz_end)
 142                strbuf_add(tz, ident.tz_begin, ident.tz_end - ident.tz_begin);
 143        else
 144                strbuf_addstr(tz, "(unknown)");
 145
 146        /*
 147         * Now, convert both name and e-mail using mailmap
 148         */
 149        map_user(&mailmap, &mailbuf, &maillen,
 150                 &namebuf, &namelen);
 151
 152        strbuf_addf(mail, "<%.*s>", (int)maillen, mailbuf);
 153        strbuf_add(name, namebuf, namelen);
 154}
 155
 156static void commit_info_init(struct commit_info *ci)
 157{
 158
 159        strbuf_init(&ci->author, 0);
 160        strbuf_init(&ci->author_mail, 0);
 161        strbuf_init(&ci->author_tz, 0);
 162        strbuf_init(&ci->committer, 0);
 163        strbuf_init(&ci->committer_mail, 0);
 164        strbuf_init(&ci->committer_tz, 0);
 165        strbuf_init(&ci->summary, 0);
 166}
 167
 168static void commit_info_destroy(struct commit_info *ci)
 169{
 170
 171        strbuf_release(&ci->author);
 172        strbuf_release(&ci->author_mail);
 173        strbuf_release(&ci->author_tz);
 174        strbuf_release(&ci->committer);
 175        strbuf_release(&ci->committer_mail);
 176        strbuf_release(&ci->committer_tz);
 177        strbuf_release(&ci->summary);
 178}
 179
 180static void get_commit_info(struct commit *commit,
 181                            struct commit_info *ret,
 182                            int detailed)
 183{
 184        int len;
 185        const char *subject, *encoding;
 186        const char *message;
 187
 188        commit_info_init(ret);
 189
 190        encoding = get_log_output_encoding();
 191        message = logmsg_reencode(commit, NULL, encoding);
 192        get_ac_line(message, "\nauthor ",
 193                    &ret->author, &ret->author_mail,
 194                    &ret->author_time, &ret->author_tz);
 195
 196        if (!detailed) {
 197                unuse_commit_buffer(commit, message);
 198                return;
 199        }
 200
 201        get_ac_line(message, "\ncommitter ",
 202                    &ret->committer, &ret->committer_mail,
 203                    &ret->committer_time, &ret->committer_tz);
 204
 205        len = find_commit_subject(message, &subject);
 206        if (len)
 207                strbuf_add(&ret->summary, subject, len);
 208        else
 209                strbuf_addf(&ret->summary, "(%s)", oid_to_hex(&commit->object.oid));
 210
 211        unuse_commit_buffer(commit, message);
 212}
 213
 214/*
 215 * Write out any suspect information which depends on the path. This must be
 216 * handled separately from emit_one_suspect_detail(), because a given commit
 217 * may have changes in multiple paths. So this needs to appear each time
 218 * we mention a new group.
 219 *
 220 * To allow LF and other nonportable characters in pathnames,
 221 * they are c-style quoted as needed.
 222 */
 223static void write_filename_info(struct blame_origin *suspect)
 224{
 225        if (suspect->previous) {
 226                struct blame_origin *prev = suspect->previous;
 227                printf("previous %s ", oid_to_hex(&prev->commit->object.oid));
 228                write_name_quoted(prev->path, stdout, '\n');
 229        }
 230        printf("filename ");
 231        write_name_quoted(suspect->path, stdout, '\n');
 232}
 233
 234/*
 235 * Porcelain/Incremental format wants to show a lot of details per
 236 * commit.  Instead of repeating this every line, emit it only once,
 237 * the first time each commit appears in the output (unless the
 238 * user has specifically asked for us to repeat).
 239 */
 240static int emit_one_suspect_detail(struct blame_origin *suspect, int repeat)
 241{
 242        struct commit_info ci;
 243
 244        if (!repeat && (suspect->commit->object.flags & METAINFO_SHOWN))
 245                return 0;
 246
 247        suspect->commit->object.flags |= METAINFO_SHOWN;
 248        get_commit_info(suspect->commit, &ci, 1);
 249        printf("author %s\n", ci.author.buf);
 250        printf("author-mail %s\n", ci.author_mail.buf);
 251        printf("author-time %"PRItime"\n", ci.author_time);
 252        printf("author-tz %s\n", ci.author_tz.buf);
 253        printf("committer %s\n", ci.committer.buf);
 254        printf("committer-mail %s\n", ci.committer_mail.buf);
 255        printf("committer-time %"PRItime"\n", ci.committer_time);
 256        printf("committer-tz %s\n", ci.committer_tz.buf);
 257        printf("summary %s\n", ci.summary.buf);
 258        if (suspect->commit->object.flags & UNINTERESTING)
 259                printf("boundary\n");
 260
 261        commit_info_destroy(&ci);
 262
 263        return 1;
 264}
 265
 266/*
 267 * The blame_entry is found to be guilty for the range.
 268 * Show it in incremental output.
 269 */
 270static void found_guilty_entry(struct blame_entry *ent, void *data)
 271{
 272        struct progress_info *pi = (struct progress_info *)data;
 273
 274        if (incremental) {
 275                struct blame_origin *suspect = ent->suspect;
 276
 277                printf("%s %d %d %d\n",
 278                       oid_to_hex(&suspect->commit->object.oid),
 279                       ent->s_lno + 1, ent->lno + 1, ent->num_lines);
 280                emit_one_suspect_detail(suspect, 0);
 281                write_filename_info(suspect);
 282                maybe_flush_or_die(stdout, "stdout");
 283        }
 284        pi->blamed_lines += ent->num_lines;
 285        display_progress(pi->progress, pi->blamed_lines);
 286}
 287
 288static const char *format_time(timestamp_t time, const char *tz_str,
 289                               int show_raw_time)
 290{
 291        static struct strbuf time_buf = STRBUF_INIT;
 292
 293        strbuf_reset(&time_buf);
 294        if (show_raw_time) {
 295                strbuf_addf(&time_buf, "%"PRItime" %s", time, tz_str);
 296        }
 297        else {
 298                const char *time_str;
 299                size_t time_width;
 300                int tz;
 301                tz = atoi(tz_str);
 302                time_str = show_date(time, tz, &blame_date_mode);
 303                strbuf_addstr(&time_buf, time_str);
 304                /*
 305                 * Add space paddings to time_buf to display a fixed width
 306                 * string, and use time_width for display width calibration.
 307                 */
 308                for (time_width = utf8_strwidth(time_str);
 309                     time_width < blame_date_width;
 310                     time_width++)
 311                        strbuf_addch(&time_buf, ' ');
 312        }
 313        return time_buf.buf;
 314}
 315
 316#define OUTPUT_ANNOTATE_COMPAT  001
 317#define OUTPUT_LONG_OBJECT_NAME 002
 318#define OUTPUT_RAW_TIMESTAMP    004
 319#define OUTPUT_PORCELAIN        010
 320#define OUTPUT_SHOW_NAME        020
 321#define OUTPUT_SHOW_NUMBER      040
 322#define OUTPUT_SHOW_SCORE       0100
 323#define OUTPUT_NO_AUTHOR        0200
 324#define OUTPUT_SHOW_EMAIL       0400
 325#define OUTPUT_LINE_PORCELAIN   01000
 326#define OUTPUT_COLOR_LINE       02000
 327#define OUTPUT_SHOW_AGE_WITH_COLOR      04000
 328
 329static void emit_porcelain_details(struct blame_origin *suspect, int repeat)
 330{
 331        if (emit_one_suspect_detail(suspect, repeat) ||
 332            (suspect->commit->object.flags & MORE_THAN_ONE_PATH))
 333                write_filename_info(suspect);
 334}
 335
 336static void emit_porcelain(struct blame_scoreboard *sb, struct blame_entry *ent,
 337                           int opt)
 338{
 339        int repeat = opt & OUTPUT_LINE_PORCELAIN;
 340        int cnt;
 341        const char *cp;
 342        struct blame_origin *suspect = ent->suspect;
 343        char hex[GIT_MAX_HEXSZ + 1];
 344
 345        oid_to_hex_r(hex, &suspect->commit->object.oid);
 346        printf("%s %d %d %d\n",
 347               hex,
 348               ent->s_lno + 1,
 349               ent->lno + 1,
 350               ent->num_lines);
 351        emit_porcelain_details(suspect, repeat);
 352
 353        cp = blame_nth_line(sb, ent->lno);
 354        for (cnt = 0; cnt < ent->num_lines; cnt++) {
 355                char ch;
 356                if (cnt) {
 357                        printf("%s %d %d\n", hex,
 358                               ent->s_lno + 1 + cnt,
 359                               ent->lno + 1 + cnt);
 360                        if (repeat)
 361                                emit_porcelain_details(suspect, 1);
 362                }
 363                putchar('\t');
 364                do {
 365                        ch = *cp++;
 366                        putchar(ch);
 367                } while (ch != '\n' &&
 368                         cp < sb->final_buf + sb->final_buf_size);
 369        }
 370
 371        if (sb->final_buf_size && cp[-1] != '\n')
 372                putchar('\n');
 373}
 374
 375static struct color_field {
 376        timestamp_t hop;
 377        char col[COLOR_MAXLEN];
 378} *colorfield;
 379static int colorfield_nr, colorfield_alloc;
 380
 381static void parse_color_fields(const char *s)
 382{
 383        struct string_list l = STRING_LIST_INIT_DUP;
 384        struct string_list_item *item;
 385        enum { EXPECT_DATE, EXPECT_COLOR } next = EXPECT_COLOR;
 386
 387        colorfield_nr = 0;
 388
 389        /* Ideally this would be stripped and split at the same time? */
 390        string_list_split(&l, s, ',', -1);
 391        ALLOC_GROW(colorfield, colorfield_nr + 1, colorfield_alloc);
 392
 393        for_each_string_list_item(item, &l) {
 394                switch (next) {
 395                case EXPECT_DATE:
 396                        colorfield[colorfield_nr].hop = approxidate(item->string);
 397                        next = EXPECT_COLOR;
 398                        colorfield_nr++;
 399                        ALLOC_GROW(colorfield, colorfield_nr + 1, colorfield_alloc);
 400                        break;
 401                case EXPECT_COLOR:
 402                        if (color_parse(item->string, colorfield[colorfield_nr].col))
 403                                die(_("expecting a color: %s"), item->string);
 404                        next = EXPECT_DATE;
 405                        break;
 406                }
 407        }
 408
 409        if (next == EXPECT_COLOR)
 410                die (_("must end with a color"));
 411
 412        colorfield[colorfield_nr].hop = TIME_MAX;
 413}
 414
 415static void setup_default_color_by_age(void)
 416{
 417        parse_color_fields("blue,12 month ago,white,1 month ago,red");
 418}
 419
 420static void determine_line_heat(struct blame_entry *ent, const char **dest_color)
 421{
 422        int i = 0;
 423        struct commit_info ci;
 424        get_commit_info(ent->suspect->commit, &ci, 1);
 425
 426        while (i < colorfield_nr && ci.author_time > colorfield[i].hop)
 427                i++;
 428
 429        *dest_color = colorfield[i].col;
 430}
 431
 432static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int opt)
 433{
 434        int cnt;
 435        const char *cp;
 436        struct blame_origin *suspect = ent->suspect;
 437        struct commit_info ci;
 438        char hex[GIT_MAX_HEXSZ + 1];
 439        int show_raw_time = !!(opt & OUTPUT_RAW_TIMESTAMP);
 440        const char *default_color = NULL, *color = NULL, *reset = NULL;
 441
 442        get_commit_info(suspect->commit, &ci, 1);
 443        oid_to_hex_r(hex, &suspect->commit->object.oid);
 444
 445        cp = blame_nth_line(sb, ent->lno);
 446
 447        if (opt & OUTPUT_SHOW_AGE_WITH_COLOR) {
 448                determine_line_heat(ent, &default_color);
 449                color = default_color;
 450                reset = GIT_COLOR_RESET;
 451        }
 452
 453        for (cnt = 0; cnt < ent->num_lines; cnt++) {
 454                char ch;
 455                int length = (opt & OUTPUT_LONG_OBJECT_NAME) ? GIT_SHA1_HEXSZ : abbrev;
 456
 457                if (opt & OUTPUT_COLOR_LINE) {
 458                        if (cnt > 0) {
 459                                color = repeated_meta_color;
 460                                reset = GIT_COLOR_RESET;
 461                        } else  {
 462                                color = default_color ? default_color : NULL;
 463                                reset = default_color ? GIT_COLOR_RESET : NULL;
 464                        }
 465                }
 466                if (color)
 467                        fputs(color, stdout);
 468
 469                if (suspect->commit->object.flags & UNINTERESTING) {
 470                        if (blank_boundary)
 471                                memset(hex, ' ', length);
 472                        else if (!(opt & OUTPUT_ANNOTATE_COMPAT)) {
 473                                length--;
 474                                putchar('^');
 475                        }
 476                }
 477
 478                printf("%.*s", length, hex);
 479                if (opt & OUTPUT_ANNOTATE_COMPAT) {
 480                        const char *name;
 481                        if (opt & OUTPUT_SHOW_EMAIL)
 482                                name = ci.author_mail.buf;
 483                        else
 484                                name = ci.author.buf;
 485                        printf("\t(%10s\t%10s\t%d)", name,
 486                               format_time(ci.author_time, ci.author_tz.buf,
 487                                           show_raw_time),
 488                               ent->lno + 1 + cnt);
 489                } else {
 490                        if (opt & OUTPUT_SHOW_SCORE)
 491                                printf(" %*d %02d",
 492                                       max_score_digits, ent->score,
 493                                       ent->suspect->refcnt);
 494                        if (opt & OUTPUT_SHOW_NAME)
 495                                printf(" %-*.*s", longest_file, longest_file,
 496                                       suspect->path);
 497                        if (opt & OUTPUT_SHOW_NUMBER)
 498                                printf(" %*d", max_orig_digits,
 499                                       ent->s_lno + 1 + cnt);
 500
 501                        if (!(opt & OUTPUT_NO_AUTHOR)) {
 502                                const char *name;
 503                                int pad;
 504                                if (opt & OUTPUT_SHOW_EMAIL)
 505                                        name = ci.author_mail.buf;
 506                                else
 507                                        name = ci.author.buf;
 508                                pad = longest_author - utf8_strwidth(name);
 509                                printf(" (%s%*s %10s",
 510                                       name, pad, "",
 511                                       format_time(ci.author_time,
 512                                                   ci.author_tz.buf,
 513                                                   show_raw_time));
 514                        }
 515                        printf(" %*d) ",
 516                               max_digits, ent->lno + 1 + cnt);
 517                }
 518                if (reset)
 519                        fputs(reset, stdout);
 520                do {
 521                        ch = *cp++;
 522                        putchar(ch);
 523                } while (ch != '\n' &&
 524                         cp < sb->final_buf + sb->final_buf_size);
 525        }
 526
 527        if (sb->final_buf_size && cp[-1] != '\n')
 528                putchar('\n');
 529
 530        commit_info_destroy(&ci);
 531}
 532
 533static void output(struct blame_scoreboard *sb, int option)
 534{
 535        struct blame_entry *ent;
 536
 537        if (option & OUTPUT_PORCELAIN) {
 538                for (ent = sb->ent; ent; ent = ent->next) {
 539                        int count = 0;
 540                        struct blame_origin *suspect;
 541                        struct commit *commit = ent->suspect->commit;
 542                        if (commit->object.flags & MORE_THAN_ONE_PATH)
 543                                continue;
 544                        for (suspect = commit->util; suspect; suspect = suspect->next) {
 545                                if (suspect->guilty && count++) {
 546                                        commit->object.flags |= MORE_THAN_ONE_PATH;
 547                                        break;
 548                                }
 549                        }
 550                }
 551        }
 552
 553        for (ent = sb->ent; ent; ent = ent->next) {
 554                if (option & OUTPUT_PORCELAIN)
 555                        emit_porcelain(sb, ent, option);
 556                else {
 557                        emit_other(sb, ent, option);
 558                }
 559        }
 560}
 561
 562/*
 563 * Add phony grafts for use with -S; this is primarily to
 564 * support git's cvsserver that wants to give a linear history
 565 * to its clients.
 566 */
 567static int read_ancestry(const char *graft_file)
 568{
 569        FILE *fp = fopen_or_warn(graft_file, "r");
 570        struct strbuf buf = STRBUF_INIT;
 571        if (!fp)
 572                return -1;
 573        while (!strbuf_getwholeline(&buf, fp, '\n')) {
 574                /* The format is just "Commit Parent1 Parent2 ...\n" */
 575                struct commit_graft *graft = read_graft_line(&buf);
 576                if (graft)
 577                        register_commit_graft(graft, 0);
 578        }
 579        fclose(fp);
 580        strbuf_release(&buf);
 581        return 0;
 582}
 583
 584static int update_auto_abbrev(int auto_abbrev, struct blame_origin *suspect)
 585{
 586        const char *uniq = find_unique_abbrev(suspect->commit->object.oid.hash,
 587                                              auto_abbrev);
 588        int len = strlen(uniq);
 589        if (auto_abbrev < len)
 590                return len;
 591        return auto_abbrev;
 592}
 593
 594/*
 595 * How many columns do we need to show line numbers, authors,
 596 * and filenames?
 597 */
 598static void find_alignment(struct blame_scoreboard *sb, int *option)
 599{
 600        int longest_src_lines = 0;
 601        int longest_dst_lines = 0;
 602        unsigned largest_score = 0;
 603        struct blame_entry *e;
 604        int compute_auto_abbrev = (abbrev < 0);
 605        int auto_abbrev = DEFAULT_ABBREV;
 606
 607        for (e = sb->ent; e; e = e->next) {
 608                struct blame_origin *suspect = e->suspect;
 609                int num;
 610
 611                if (compute_auto_abbrev)
 612                        auto_abbrev = update_auto_abbrev(auto_abbrev, suspect);
 613                if (strcmp(suspect->path, sb->path))
 614                        *option |= OUTPUT_SHOW_NAME;
 615                num = strlen(suspect->path);
 616                if (longest_file < num)
 617                        longest_file = num;
 618                if (!(suspect->commit->object.flags & METAINFO_SHOWN)) {
 619                        struct commit_info ci;
 620                        suspect->commit->object.flags |= METAINFO_SHOWN;
 621                        get_commit_info(suspect->commit, &ci, 1);
 622                        if (*option & OUTPUT_SHOW_EMAIL)
 623                                num = utf8_strwidth(ci.author_mail.buf);
 624                        else
 625                                num = utf8_strwidth(ci.author.buf);
 626                        if (longest_author < num)
 627                                longest_author = num;
 628                        commit_info_destroy(&ci);
 629                }
 630                num = e->s_lno + e->num_lines;
 631                if (longest_src_lines < num)
 632                        longest_src_lines = num;
 633                num = e->lno + e->num_lines;
 634                if (longest_dst_lines < num)
 635                        longest_dst_lines = num;
 636                if (largest_score < blame_entry_score(sb, e))
 637                        largest_score = blame_entry_score(sb, e);
 638        }
 639        max_orig_digits = decimal_width(longest_src_lines);
 640        max_digits = decimal_width(longest_dst_lines);
 641        max_score_digits = decimal_width(largest_score);
 642
 643        if (compute_auto_abbrev)
 644                /* one more abbrev length is needed for the boundary commit */
 645                abbrev = auto_abbrev + 1;
 646}
 647
 648static void sanity_check_on_fail(struct blame_scoreboard *sb, int baa)
 649{
 650        int opt = OUTPUT_SHOW_SCORE | OUTPUT_SHOW_NUMBER | OUTPUT_SHOW_NAME;
 651        find_alignment(sb, &opt);
 652        output(sb, opt);
 653        die("Baa %d!", baa);
 654}
 655
 656static unsigned parse_score(const char *arg)
 657{
 658        char *end;
 659        unsigned long score = strtoul(arg, &end, 10);
 660        if (*end)
 661                return 0;
 662        return score;
 663}
 664
 665static const char *add_prefix(const char *prefix, const char *path)
 666{
 667        return prefix_path(prefix, prefix ? strlen(prefix) : 0, path);
 668}
 669
 670static int git_blame_config(const char *var, const char *value, void *cb)
 671{
 672        if (!strcmp(var, "blame.showroot")) {
 673                show_root = git_config_bool(var, value);
 674                return 0;
 675        }
 676        if (!strcmp(var, "blame.blankboundary")) {
 677                blank_boundary = git_config_bool(var, value);
 678                return 0;
 679        }
 680        if (!strcmp(var, "blame.showemail")) {
 681                int *output_option = cb;
 682                if (git_config_bool(var, value))
 683                        *output_option |= OUTPUT_SHOW_EMAIL;
 684                else
 685                        *output_option &= ~OUTPUT_SHOW_EMAIL;
 686                return 0;
 687        }
 688        if (!strcmp(var, "blame.date")) {
 689                if (!value)
 690                        return config_error_nonbool(var);
 691                parse_date_format(value, &blame_date_mode);
 692                return 0;
 693        }
 694        if (!strcmp(var, "color.blame.repeatedlines")) {
 695                if (color_parse_mem(value, strlen(value), repeated_meta_color))
 696                        warning(_("invalid color '%s' in color.blame.repeatedLines"),
 697                                value);
 698                return 0;
 699        }
 700        if (!strcmp(var, "color.blame.highlightrecent")) {
 701                parse_color_fields(value);
 702                return 0;
 703        }
 704
 705        if (git_diff_heuristic_config(var, value, cb) < 0)
 706                return -1;
 707        if (userdiff_config(var, value) < 0)
 708                return -1;
 709
 710        return git_default_config(var, value, cb);
 711}
 712
 713static int blame_copy_callback(const struct option *option, const char *arg, int unset)
 714{
 715        int *opt = option->value;
 716
 717        /*
 718         * -C enables copy from removed files;
 719         * -C -C enables copy from existing files, but only
 720         *       when blaming a new file;
 721         * -C -C -C enables copy from existing files for
 722         *          everybody
 723         */
 724        if (*opt & PICKAXE_BLAME_COPY_HARDER)
 725                *opt |= PICKAXE_BLAME_COPY_HARDEST;
 726        if (*opt & PICKAXE_BLAME_COPY)
 727                *opt |= PICKAXE_BLAME_COPY_HARDER;
 728        *opt |= PICKAXE_BLAME_COPY | PICKAXE_BLAME_MOVE;
 729
 730        if (arg)
 731                blame_copy_score = parse_score(arg);
 732        return 0;
 733}
 734
 735static int blame_move_callback(const struct option *option, const char *arg, int unset)
 736{
 737        int *opt = option->value;
 738
 739        *opt |= PICKAXE_BLAME_MOVE;
 740
 741        if (arg)
 742                blame_move_score = parse_score(arg);
 743        return 0;
 744}
 745
 746int cmd_blame(int argc, const char **argv, const char *prefix)
 747{
 748        struct rev_info revs;
 749        const char *path;
 750        struct blame_scoreboard sb;
 751        struct blame_origin *o;
 752        struct blame_entry *ent = NULL;
 753        long dashdash_pos, lno;
 754        struct progress_info pi = { NULL, 0 };
 755
 756        struct string_list range_list = STRING_LIST_INIT_NODUP;
 757        int output_option = 0, opt = 0;
 758        int show_stats = 0;
 759        const char *revs_file = NULL;
 760        const char *contents_from = NULL;
 761        const struct option options[] = {
 762                OPT_BOOL(0, "incremental", &incremental, N_("Show blame entries as we find them, incrementally")),
 763                OPT_BOOL('b', NULL, &blank_boundary, N_("Show blank SHA-1 for boundary commits (Default: off)")),
 764                OPT_BOOL(0, "root", &show_root, N_("Do not treat root commits as boundaries (Default: off)")),
 765                OPT_BOOL(0, "show-stats", &show_stats, N_("Show work cost statistics")),
 766                OPT_BOOL(0, "progress", &show_progress, N_("Force progress reporting")),
 767                OPT_BIT(0, "score-debug", &output_option, N_("Show output score for blame entries"), OUTPUT_SHOW_SCORE),
 768                OPT_BIT('f', "show-name", &output_option, N_("Show original filename (Default: auto)"), OUTPUT_SHOW_NAME),
 769                OPT_BIT('n', "show-number", &output_option, N_("Show original linenumber (Default: off)"), OUTPUT_SHOW_NUMBER),
 770                OPT_BIT('p', "porcelain", &output_option, N_("Show in a format designed for machine consumption"), OUTPUT_PORCELAIN),
 771                OPT_BIT(0, "line-porcelain", &output_option, N_("Show porcelain format with per-line commit information"), OUTPUT_PORCELAIN|OUTPUT_LINE_PORCELAIN),
 772                OPT_BIT('c', NULL, &output_option, N_("Use the same output mode as git-annotate (Default: off)"), OUTPUT_ANNOTATE_COMPAT),
 773                OPT_BIT('t', NULL, &output_option, N_("Show raw timestamp (Default: off)"), OUTPUT_RAW_TIMESTAMP),
 774                OPT_BIT('l', NULL, &output_option, N_("Show long commit SHA1 (Default: off)"), OUTPUT_LONG_OBJECT_NAME),
 775                OPT_BIT('s', NULL, &output_option, N_("Suppress author name and timestamp (Default: off)"), OUTPUT_NO_AUTHOR),
 776                OPT_BIT('e', "show-email", &output_option, N_("Show author email instead of name (Default: off)"), OUTPUT_SHOW_EMAIL),
 777                OPT_BIT('w', NULL, &xdl_opts, N_("Ignore whitespace differences"), XDF_IGNORE_WHITESPACE),
 778                OPT_BIT(0, "color-lines", &output_option, N_("color redundant metadata from previous line differently"), OUTPUT_COLOR_LINE),
 779                OPT_BIT(0, "color-by-age", &output_option, N_("color lines by age"), OUTPUT_SHOW_AGE_WITH_COLOR),
 780
 781                /*
 782                 * The following two options are parsed by parse_revision_opt()
 783                 * and are only included here to get included in the "-h"
 784                 * output:
 785                 */
 786                { OPTION_LOWLEVEL_CALLBACK, 0, "indent-heuristic", NULL, NULL, N_("Use an experimental heuristic to improve diffs"), PARSE_OPT_NOARG, parse_opt_unknown_cb },
 787
 788                OPT_BIT(0, "minimal", &xdl_opts, N_("Spend extra cycles to find better match"), XDF_NEED_MINIMAL),
 789                OPT_STRING('S', NULL, &revs_file, N_("file"), N_("Use revisions from <file> instead of calling git-rev-list")),
 790                OPT_STRING(0, "contents", &contents_from, N_("file"), N_("Use <file>'s contents as the final image")),
 791                { OPTION_CALLBACK, 'C', NULL, &opt, N_("score"), N_("Find line copies within and across files"), PARSE_OPT_OPTARG, blame_copy_callback },
 792                { OPTION_CALLBACK, 'M', NULL, &opt, N_("score"), N_("Find line movements within and across files"), PARSE_OPT_OPTARG, blame_move_callback },
 793                OPT_STRING_LIST('L', NULL, &range_list, N_("n,m"), N_("Process only line range n,m, counting from 1")),
 794                OPT__ABBREV(&abbrev),
 795                OPT_END()
 796        };
 797
 798        struct parse_opt_ctx_t ctx;
 799        int cmd_is_annotate = !strcmp(argv[0], "annotate");
 800        struct range_set ranges;
 801        unsigned int range_i;
 802        long anchor;
 803
 804        setup_default_color_by_age();
 805        git_config(git_blame_config, &output_option);
 806        init_revisions(&revs, NULL);
 807        revs.date_mode = blame_date_mode;
 808        revs.diffopt.flags.allow_textconv = 1;
 809        revs.diffopt.flags.follow_renames = 1;
 810
 811        save_commit_buffer = 0;
 812        dashdash_pos = 0;
 813        show_progress = -1;
 814
 815        parse_options_start(&ctx, argc, argv, prefix, options,
 816                            PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0);
 817        for (;;) {
 818                switch (parse_options_step(&ctx, options, blame_opt_usage)) {
 819                case PARSE_OPT_HELP:
 820                        exit(129);
 821                case PARSE_OPT_DONE:
 822                        if (ctx.argv[0])
 823                                dashdash_pos = ctx.cpidx;
 824                        goto parse_done;
 825                }
 826
 827                if (!strcmp(ctx.argv[0], "--reverse")) {
 828                        ctx.argv[0] = "--children";
 829                        reverse = 1;
 830                }
 831                parse_revision_opt(&revs, &ctx, options, blame_opt_usage);
 832        }
 833parse_done:
 834        no_whole_file_rename = !revs.diffopt.flags.follow_renames;
 835        xdl_opts |= revs.diffopt.xdl_opts & XDF_INDENT_HEURISTIC;
 836        revs.diffopt.flags.follow_renames = 0;
 837        argc = parse_options_end(&ctx);
 838
 839        if (incremental || (output_option & OUTPUT_PORCELAIN)) {
 840                if (show_progress > 0)
 841                        die(_("--progress can't be used with --incremental or porcelain formats"));
 842                show_progress = 0;
 843        } else if (show_progress < 0)
 844                show_progress = isatty(2);
 845
 846        if (0 < abbrev && abbrev < GIT_SHA1_HEXSZ)
 847                /* one more abbrev length is needed for the boundary commit */
 848                abbrev++;
 849        else if (!abbrev)
 850                abbrev = GIT_SHA1_HEXSZ;
 851
 852        if (revs_file && read_ancestry(revs_file))
 853                die_errno("reading graft file '%s' failed", revs_file);
 854
 855        if (cmd_is_annotate) {
 856                output_option |= OUTPUT_ANNOTATE_COMPAT;
 857                blame_date_mode.type = DATE_ISO8601;
 858        } else {
 859                blame_date_mode = revs.date_mode;
 860        }
 861
 862        /* The maximum width used to show the dates */
 863        switch (blame_date_mode.type) {
 864        case DATE_RFC2822:
 865                blame_date_width = sizeof("Thu, 19 Oct 2006 16:00:04 -0700");
 866                break;
 867        case DATE_ISO8601_STRICT:
 868                blame_date_width = sizeof("2006-10-19T16:00:04-07:00");
 869                break;
 870        case DATE_ISO8601:
 871                blame_date_width = sizeof("2006-10-19 16:00:04 -0700");
 872                break;
 873        case DATE_RAW:
 874                blame_date_width = sizeof("1161298804 -0700");
 875                break;
 876        case DATE_UNIX:
 877                blame_date_width = sizeof("1161298804");
 878                break;
 879        case DATE_SHORT:
 880                blame_date_width = sizeof("2006-10-19");
 881                break;
 882        case DATE_RELATIVE:
 883                /*
 884                 * TRANSLATORS: This string is used to tell us the
 885                 * maximum display width for a relative timestamp in
 886                 * "git blame" output.  For C locale, "4 years, 11
 887                 * months ago", which takes 22 places, is the longest
 888                 * among various forms of relative timestamps, but
 889                 * your language may need more or fewer display
 890                 * columns.
 891                 */
 892                blame_date_width = utf8_strwidth(_("4 years, 11 months ago")) + 1; /* add the null */
 893                break;
 894        case DATE_NORMAL:
 895                blame_date_width = sizeof("Thu Oct 19 16:00:04 2006 -0700");
 896                break;
 897        case DATE_STRFTIME:
 898                blame_date_width = strlen(show_date(0, 0, &blame_date_mode)) + 1; /* add the null */
 899                break;
 900        }
 901        blame_date_width -= 1; /* strip the null */
 902
 903        if (revs.diffopt.flags.find_copies_harder)
 904                opt |= (PICKAXE_BLAME_COPY | PICKAXE_BLAME_MOVE |
 905                        PICKAXE_BLAME_COPY_HARDER);
 906
 907        /*
 908         * We have collected options unknown to us in argv[1..unk]
 909         * which are to be passed to revision machinery if we are
 910         * going to do the "bottom" processing.
 911         *
 912         * The remaining are:
 913         *
 914         * (1) if dashdash_pos != 0, it is either
 915         *     "blame [revisions] -- <path>" or
 916         *     "blame -- <path> <rev>"
 917         *
 918         * (2) otherwise, it is one of the two:
 919         *     "blame [revisions] <path>"
 920         *     "blame <path> <rev>"
 921         *
 922         * Note that we must strip out <path> from the arguments: we do not
 923         * want the path pruning but we may want "bottom" processing.
 924         */
 925        if (dashdash_pos) {
 926                switch (argc - dashdash_pos - 1) {
 927                case 2: /* (1b) */
 928                        if (argc != 4)
 929                                usage_with_options(blame_opt_usage, options);
 930                        /* reorder for the new way: <rev> -- <path> */
 931                        argv[1] = argv[3];
 932                        argv[3] = argv[2];
 933                        argv[2] = "--";
 934                        /* FALLTHROUGH */
 935                case 1: /* (1a) */
 936                        path = add_prefix(prefix, argv[--argc]);
 937                        argv[argc] = NULL;
 938                        break;
 939                default:
 940                        usage_with_options(blame_opt_usage, options);
 941                }
 942        } else {
 943                if (argc < 2)
 944                        usage_with_options(blame_opt_usage, options);
 945                path = add_prefix(prefix, argv[argc - 1]);
 946                if (argc == 3 && !file_exists(path)) { /* (2b) */
 947                        path = add_prefix(prefix, argv[1]);
 948                        argv[1] = argv[2];
 949                }
 950                argv[argc - 1] = "--";
 951
 952                setup_work_tree();
 953                if (!file_exists(path))
 954                        die_errno("cannot stat path '%s'", path);
 955        }
 956
 957        revs.disable_stdin = 1;
 958        setup_revisions(argc, argv, &revs, NULL);
 959
 960        init_scoreboard(&sb);
 961        sb.revs = &revs;
 962        sb.contents_from = contents_from;
 963        sb.reverse = reverse;
 964        setup_scoreboard(&sb, path, &o);
 965        lno = sb.num_lines;
 966
 967        if (lno && !range_list.nr)
 968                string_list_append(&range_list, "1");
 969
 970        anchor = 1;
 971        range_set_init(&ranges, range_list.nr);
 972        for (range_i = 0; range_i < range_list.nr; ++range_i) {
 973                long bottom, top;
 974                if (parse_range_arg(range_list.items[range_i].string,
 975                                    nth_line_cb, &sb, lno, anchor,
 976                                    &bottom, &top, sb.path))
 977                        usage(blame_usage);
 978                if (lno < top || ((lno || bottom) && lno < bottom))
 979                        die(Q_("file %s has only %lu line",
 980                               "file %s has only %lu lines",
 981                               lno), path, lno);
 982                if (bottom < 1)
 983                        bottom = 1;
 984                if (top < 1)
 985                        top = lno;
 986                bottom--;
 987                range_set_append_unsafe(&ranges, bottom, top);
 988                anchor = top + 1;
 989        }
 990        sort_and_merge_range_set(&ranges);
 991
 992        for (range_i = ranges.nr; range_i > 0; --range_i) {
 993                const struct range *r = &ranges.ranges[range_i - 1];
 994                ent = blame_entry_prepend(ent, r->start, r->end, o);
 995        }
 996
 997        o->suspects = ent;
 998        prio_queue_put(&sb.commits, o->commit);
 999
1000        blame_origin_decref(o);
1001
1002        range_set_release(&ranges);
1003        string_list_clear(&range_list, 0);
1004
1005        sb.ent = NULL;
1006        sb.path = path;
1007
1008        if (blame_move_score)
1009                sb.move_score = blame_move_score;
1010        if (blame_copy_score)
1011                sb.copy_score = blame_copy_score;
1012
1013        sb.debug = DEBUG;
1014        sb.on_sanity_fail = &sanity_check_on_fail;
1015
1016        sb.show_root = show_root;
1017        sb.xdl_opts = xdl_opts;
1018        sb.no_whole_file_rename = no_whole_file_rename;
1019
1020        read_mailmap(&mailmap, NULL);
1021
1022        sb.found_guilty_entry = &found_guilty_entry;
1023        sb.found_guilty_entry_data = &pi;
1024        if (show_progress)
1025                pi.progress = start_delayed_progress(_("Blaming lines"), sb.num_lines);
1026
1027        assign_blame(&sb, opt);
1028
1029        stop_progress(&pi.progress);
1030
1031        if (!incremental)
1032                setup_pager();
1033        else
1034                return 0;
1035
1036        blame_sort_final(&sb);
1037
1038        blame_coalesce(&sb);
1039
1040        if (!(output_option & OUTPUT_PORCELAIN)) {
1041                find_alignment(&sb, &output_option);
1042                if (!*repeated_meta_color &&
1043                    (output_option & OUTPUT_COLOR_LINE))
1044                        strcpy(repeated_meta_color, GIT_COLOR_CYAN);
1045        }
1046        if (output_option & OUTPUT_ANNOTATE_COMPAT)
1047                output_option &= ~(OUTPUT_COLOR_LINE | OUTPUT_SHOW_AGE_WITH_COLOR);
1048
1049        output(&sb, output_option);
1050        free((void *)sb.final_buf);
1051        for (ent = sb.ent; ent; ) {
1052                struct blame_entry *e = ent->next;
1053                free(ent);
1054                ent = e;
1055        }
1056
1057        if (show_stats) {
1058                printf("num read blob: %d\n", sb.num_read_blob);
1059                printf("num get patch: %d\n", sb.num_get_patch);
1060                printf("num commits: %d\n", sb.num_commits);
1061        }
1062        return 0;
1063}