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