blame.con commit Merge branch 'lj/refs' (58a1e0e)
   1/*
   2 * Copyright (C) 2006, Fredrik Kuivinen <freku045@student.liu.se>
   3 */
   4
   5#include <assert.h>
   6#include <time.h>
   7#include <sys/time.h>
   8#include <math.h>
   9
  10#include "cache.h"
  11#include "refs.h"
  12#include "tag.h"
  13#include "commit.h"
  14#include "tree.h"
  15#include "blob.h"
  16#include "diff.h"
  17#include "diffcore.h"
  18#include "revision.h"
  19#include "xdiff-interface.h"
  20#include "quote.h"
  21
  22#ifndef DEBUG
  23#define DEBUG 0
  24#endif
  25
  26static const char blame_usage[] =
  27"git-blame [-c] [-l] [-t] [-f] [-n] [-p] [-S <revs-file>] [--] file [commit]\n"
  28"  -c, --compatibility Use the same output mode as git-annotate (Default: off)\n"
  29"  -l, --long          Show long commit SHA1 (Default: off)\n"
  30"  -t, --time          Show raw timestamp (Default: off)\n"
  31"  -f, --show-name     Show original filename (Default: auto)\n"
  32"  -n, --show-number   Show original linenumber (Default: off)\n"
  33"  -p, --porcelain     Show in a format designed for machine consumption\n"
  34"  -S revs-file        Use revisions from revs-file instead of calling git-rev-list\n"
  35"  -h, --help          This message";
  36
  37static struct commit **blame_lines;
  38static int num_blame_lines;
  39static char *blame_contents;
  40static int blame_len;
  41
  42struct util_info {
  43        int *line_map;
  44        unsigned char sha1[20]; /* blob sha, not commit! */
  45        char *buf;
  46        unsigned long size;
  47        int num_lines;
  48        const char *pathname;
  49        unsigned meta_given:1;
  50
  51        void *topo_data;
  52};
  53
  54struct chunk {
  55        int off1, len1; /* --- */
  56        int off2, len2; /* +++ */
  57};
  58
  59struct patch {
  60        struct chunk *chunks;
  61        int num;
  62};
  63
  64static void get_blob(struct commit *commit);
  65
  66/* Only used for statistics */
  67static int num_get_patch;
  68static int num_commits;
  69static int patch_time;
  70
  71struct blame_diff_state {
  72        struct xdiff_emit_state xm;
  73        struct patch *ret;
  74};
  75
  76static void process_u0_diff(void *state_, char *line, unsigned long len)
  77{
  78        struct blame_diff_state *state = state_;
  79        struct chunk *chunk;
  80
  81        if (len < 4 || line[0] != '@' || line[1] != '@')
  82                return;
  83
  84        if (DEBUG)
  85                printf("chunk line: %.*s", (int)len, line);
  86        state->ret->num++;
  87        state->ret->chunks = xrealloc(state->ret->chunks,
  88                                      sizeof(struct chunk) * state->ret->num);
  89        chunk = &state->ret->chunks[state->ret->num - 1];
  90
  91        assert(!strncmp(line, "@@ -", 4));
  92
  93        if (parse_hunk_header(line, len,
  94                              &chunk->off1, &chunk->len1,
  95                              &chunk->off2, &chunk->len2)) {
  96                state->ret->num--;
  97                return;
  98        }
  99
 100        if (chunk->len1 == 0)
 101                chunk->off1++;
 102        if (chunk->len2 == 0)
 103                chunk->off2++;
 104
 105        if (chunk->off1 > 0)
 106                chunk->off1--;
 107        if (chunk->off2 > 0)
 108                chunk->off2--;
 109
 110        assert(chunk->off1 >= 0);
 111        assert(chunk->off2 >= 0);
 112}
 113
 114static struct patch *get_patch(struct commit *commit, struct commit *other)
 115{
 116        struct blame_diff_state state;
 117        xpparam_t xpp;
 118        xdemitconf_t xecfg;
 119        mmfile_t file_c, file_o;
 120        xdemitcb_t ecb;
 121        struct util_info *info_c = (struct util_info *)commit->util;
 122        struct util_info *info_o = (struct util_info *)other->util;
 123        struct timeval tv_start, tv_end;
 124
 125        get_blob(commit);
 126        file_c.ptr = info_c->buf;
 127        file_c.size = info_c->size;
 128
 129        get_blob(other);
 130        file_o.ptr = info_o->buf;
 131        file_o.size = info_o->size;
 132
 133        gettimeofday(&tv_start, NULL);
 134
 135        xpp.flags = XDF_NEED_MINIMAL;
 136        xecfg.ctxlen = 0;
 137        xecfg.flags = 0;
 138        ecb.outf = xdiff_outf;
 139        ecb.priv = &state;
 140        memset(&state, 0, sizeof(state));
 141        state.xm.consume = process_u0_diff;
 142        state.ret = xmalloc(sizeof(struct patch));
 143        state.ret->chunks = NULL;
 144        state.ret->num = 0;
 145
 146        xdl_diff(&file_c, &file_o, &xpp, &xecfg, &ecb);
 147
 148        gettimeofday(&tv_end, NULL);
 149        patch_time += 1000000 * (tv_end.tv_sec - tv_start.tv_sec) +
 150                tv_end.tv_usec - tv_start.tv_usec;
 151
 152        num_get_patch++;
 153        return state.ret;
 154}
 155
 156static void free_patch(struct patch *p)
 157{
 158        free(p->chunks);
 159        free(p);
 160}
 161
 162static int get_blob_sha1_internal(const unsigned char *sha1, const char *base,
 163                                  int baselen, const char *pathname,
 164                                  unsigned mode, int stage);
 165
 166static unsigned char blob_sha1[20];
 167static const char *blame_file;
 168static int get_blob_sha1(struct tree *t, const char *pathname,
 169                         unsigned char *sha1)
 170{
 171        const char *pathspec[2];
 172        blame_file = pathname;
 173        pathspec[0] = pathname;
 174        pathspec[1] = NULL;
 175        hashclr(blob_sha1);
 176        read_tree_recursive(t, "", 0, 0, pathspec, get_blob_sha1_internal);
 177
 178        if (is_null_sha1(blob_sha1))
 179                return -1;
 180
 181        hashcpy(sha1, blob_sha1);
 182        return 0;
 183}
 184
 185static int get_blob_sha1_internal(const unsigned char *sha1, const char *base,
 186                                  int baselen, const char *pathname,
 187                                  unsigned mode, int stage)
 188{
 189        if (S_ISDIR(mode))
 190                return READ_TREE_RECURSIVE;
 191
 192        if (strncmp(blame_file, base, baselen) ||
 193            strcmp(blame_file + baselen, pathname))
 194                return -1;
 195
 196        hashcpy(blob_sha1, sha1);
 197        return -1;
 198}
 199
 200static void get_blob(struct commit *commit)
 201{
 202        struct util_info *info = commit->util;
 203        char type[20];
 204
 205        if (info->buf)
 206                return;
 207
 208        info->buf = read_sha1_file(info->sha1, type, &info->size);
 209
 210        assert(!strcmp(type, blob_type));
 211}
 212
 213/* For debugging only */
 214static void print_patch(struct patch *p)
 215{
 216        int i;
 217        printf("Num chunks: %d\n", p->num);
 218        for (i = 0; i < p->num; i++) {
 219                printf("%d,%d %d,%d\n", p->chunks[i].off1, p->chunks[i].len1,
 220                       p->chunks[i].off2, p->chunks[i].len2);
 221        }
 222}
 223
 224#if DEBUG
 225/* For debugging only */
 226static void print_map(struct commit *cmit, struct commit *other)
 227{
 228        struct util_info *util = cmit->util;
 229        struct util_info *util2 = other->util;
 230
 231        int i;
 232        int max =
 233            util->num_lines >
 234            util2->num_lines ? util->num_lines : util2->num_lines;
 235        int num;
 236
 237        if (print_map == NULL)
 238                ; /* to avoid "unused function" warning */
 239
 240        for (i = 0; i < max; i++) {
 241                printf("i: %d ", i);
 242                num = -1;
 243
 244                if (i < util->num_lines) {
 245                        num = util->line_map[i];
 246                        printf("%d\t", num);
 247                }
 248                else
 249                        printf("\t");
 250
 251                if (i < util2->num_lines) {
 252                        int num2 = util2->line_map[i];
 253                        printf("%d\t", num2);
 254                        if (num != -1 && num2 != num)
 255                                printf("---");
 256                }
 257                else
 258                        printf("\t");
 259
 260                printf("\n");
 261        }
 262}
 263#endif
 264
 265/* p is a patch from commit to other. */
 266static void fill_line_map(struct commit *commit, struct commit *other,
 267                          struct patch *p)
 268{
 269        struct util_info *util = commit->util;
 270        struct util_info *util2 = other->util;
 271        int *map = util->line_map;
 272        int *map2 = util2->line_map;
 273        int cur_chunk = 0;
 274        int i1, i2;
 275
 276        if (DEBUG) {
 277                if (p->num)
 278                        print_patch(p);
 279                printf("num lines 1: %d num lines 2: %d\n", util->num_lines,
 280                       util2->num_lines);
 281        }
 282
 283        for (i1 = 0, i2 = 0; i1 < util->num_lines; i1++, i2++) {
 284                struct chunk *chunk = NULL;
 285                if (cur_chunk < p->num)
 286                        chunk = &p->chunks[cur_chunk];
 287
 288                if (chunk && chunk->off1 == i1) {
 289                        if (DEBUG && i2 != chunk->off2)
 290                                printf("i2: %d off2: %d\n", i2, chunk->off2);
 291
 292                        assert(i2 == chunk->off2);
 293
 294                        i1--;
 295                        i2--;
 296                        if (chunk->len1 > 0)
 297                                i1 += chunk->len1;
 298
 299                        if (chunk->len2 > 0)
 300                                i2 += chunk->len2;
 301
 302                        cur_chunk++;
 303                }
 304                else {
 305                        if (i2 >= util2->num_lines)
 306                                break;
 307
 308                        if (map[i1] != map2[i2] && map[i1] != -1) {
 309                                if (DEBUG)
 310                                        printf("map: i1: %d %d %p i2: %d %d %p\n",
 311                                               i1, map[i1],
 312                                               (void *) (i1 != -1 ? blame_lines[map[i1]] : NULL),
 313                                               i2, map2[i2],
 314                                               (void *) (i2 != -1 ? blame_lines[map2[i2]] : NULL));
 315                                if (map2[i2] != -1 &&
 316                                    blame_lines[map[i1]] &&
 317                                    !blame_lines[map2[i2]])
 318                                        map[i1] = map2[i2];
 319                        }
 320
 321                        if (map[i1] == -1 && map2[i2] != -1)
 322                                map[i1] = map2[i2];
 323                }
 324
 325                if (DEBUG > 1)
 326                        printf("l1: %d l2: %d i1: %d i2: %d\n",
 327                               map[i1], map2[i2], i1, i2);
 328        }
 329}
 330
 331static int map_line(struct commit *commit, int line)
 332{
 333        struct util_info *info = commit->util;
 334        assert(line >= 0 && line < info->num_lines);
 335        return info->line_map[line];
 336}
 337
 338static struct util_info *get_util(struct commit *commit)
 339{
 340        struct util_info *util = commit->util;
 341
 342        if (util)
 343                return util;
 344
 345        util = xcalloc(1, sizeof(struct util_info));
 346        util->num_lines = -1;
 347        commit->util = util;
 348        return util;
 349}
 350
 351static int fill_util_info(struct commit *commit)
 352{
 353        struct util_info *util = commit->util;
 354
 355        assert(util);
 356        assert(util->pathname);
 357
 358        return !!get_blob_sha1(commit->tree, util->pathname, util->sha1);
 359}
 360
 361static void alloc_line_map(struct commit *commit)
 362{
 363        struct util_info *util = commit->util;
 364        int i;
 365
 366        if (util->line_map)
 367                return;
 368
 369        get_blob(commit);
 370
 371        util->num_lines = 0;
 372        for (i = 0; i < util->size; i++) {
 373                if (util->buf[i] == '\n')
 374                        util->num_lines++;
 375        }
 376        if (util->buf[util->size - 1] != '\n')
 377                util->num_lines++;
 378
 379        util->line_map = xmalloc(sizeof(int) * util->num_lines);
 380
 381        for (i = 0; i < util->num_lines; i++)
 382                util->line_map[i] = -1;
 383}
 384
 385static void init_first_commit(struct commit *commit, const char *filename)
 386{
 387        struct util_info *util = commit->util;
 388        int i;
 389
 390        util->pathname = filename;
 391        if (fill_util_info(commit))
 392                die("fill_util_info failed");
 393
 394        alloc_line_map(commit);
 395
 396        util = commit->util;
 397
 398        for (i = 0; i < util->num_lines; i++)
 399                util->line_map[i] = i;
 400}
 401
 402static void process_commits(struct rev_info *rev, const char *path,
 403                            struct commit **initial)
 404{
 405        int i;
 406        struct util_info *util;
 407        int lines_left;
 408        int *blame_p;
 409        int *new_lines;
 410        int new_lines_len;
 411
 412        struct commit *commit = get_revision(rev);
 413        assert(commit);
 414        init_first_commit(commit, path);
 415
 416        util = commit->util;
 417        num_blame_lines = util->num_lines;
 418        blame_lines = xmalloc(sizeof(struct commit *) * num_blame_lines);
 419        blame_contents = util->buf;
 420        blame_len = util->size;
 421
 422        for (i = 0; i < num_blame_lines; i++)
 423                blame_lines[i] = NULL;
 424
 425        lines_left = num_blame_lines;
 426        blame_p = xmalloc(sizeof(int) * num_blame_lines);
 427        new_lines = xmalloc(sizeof(int) * num_blame_lines);
 428        do {
 429                struct commit_list *parents;
 430                int num_parents;
 431                struct util_info *util;
 432
 433                if (DEBUG)
 434                        printf("\nProcessing commit: %d %s\n", num_commits,
 435                               sha1_to_hex(commit->object.sha1));
 436
 437                if (lines_left == 0)
 438                        return;
 439
 440                num_commits++;
 441                memset(blame_p, 0, sizeof(int) * num_blame_lines);
 442                new_lines_len = 0;
 443                num_parents = 0;
 444                for (parents = commit->parents;
 445                     parents != NULL; parents = parents->next)
 446                        num_parents++;
 447
 448                if (num_parents == 0)
 449                        *initial = commit;
 450
 451                if (fill_util_info(commit))
 452                        continue;
 453
 454                alloc_line_map(commit);
 455                util = commit->util;
 456
 457                for (parents = commit->parents;
 458                     parents != NULL; parents = parents->next) {
 459                        struct commit *parent = parents->item;
 460                        struct patch *patch;
 461
 462                        if (parse_commit(parent) < 0)
 463                                die("parse_commit error");
 464
 465                        if (DEBUG)
 466                                printf("parent: %s\n",
 467                                       sha1_to_hex(parent->object.sha1));
 468
 469                        if (fill_util_info(parent)) {
 470                                num_parents--;
 471                                continue;
 472                        }
 473
 474                        patch = get_patch(parent, commit);
 475                        alloc_line_map(parent);
 476                        fill_line_map(parent, commit, patch);
 477
 478                        for (i = 0; i < patch->num; i++) {
 479                            int l;
 480                            for (l = 0; l < patch->chunks[i].len2; l++) {
 481                                int mapped_line =
 482                                    map_line(commit, patch->chunks[i].off2 + l);
 483                                if (mapped_line != -1) {
 484                                    blame_p[mapped_line]++;
 485                                    if (blame_p[mapped_line] == num_parents)
 486                                        new_lines[new_lines_len++] = mapped_line;
 487                                }
 488                            }
 489                        }
 490                        free_patch(patch);
 491                }
 492
 493                if (DEBUG)
 494                        printf("parents: %d\n", num_parents);
 495
 496                for (i = 0; i < new_lines_len; i++) {
 497                        int mapped_line = new_lines[i];
 498                        if (blame_lines[mapped_line] == NULL) {
 499                                blame_lines[mapped_line] = commit;
 500                                lines_left--;
 501                                if (DEBUG)
 502                                        printf("blame: mapped: %d i: %d\n",
 503                                               mapped_line, i);
 504                        }
 505                }
 506        } while ((commit = get_revision(rev)) != NULL);
 507}
 508
 509static int compare_tree_path(struct rev_info *revs,
 510                             struct commit *c1, struct commit *c2)
 511{
 512        int ret;
 513        const char *paths[2];
 514        struct util_info *util = c2->util;
 515        paths[0] = util->pathname;
 516        paths[1] = NULL;
 517
 518        diff_tree_setup_paths(get_pathspec(revs->prefix, paths),
 519                              &revs->pruning);
 520        ret = rev_compare_tree(revs, c1->tree, c2->tree);
 521        diff_tree_release_paths(&revs->pruning);
 522        return ret;
 523}
 524
 525static int same_tree_as_empty_path(struct rev_info *revs, struct tree *t1,
 526                                   const char *path)
 527{
 528        int ret;
 529        const char *paths[2];
 530        paths[0] = path;
 531        paths[1] = NULL;
 532
 533        diff_tree_setup_paths(get_pathspec(revs->prefix, paths),
 534                              &revs->pruning);
 535        ret = rev_same_tree_as_empty(revs, t1);
 536        diff_tree_release_paths(&revs->pruning);
 537        return ret;
 538}
 539
 540static const char *find_rename(struct commit *commit, struct commit *parent)
 541{
 542        struct util_info *cutil = commit->util;
 543        struct diff_options diff_opts;
 544        const char *paths[1];
 545        int i;
 546
 547        if (DEBUG) {
 548                printf("find_rename commit: %s ",
 549                       sha1_to_hex(commit->object.sha1));
 550                puts(sha1_to_hex(parent->object.sha1));
 551        }
 552
 553        diff_setup(&diff_opts);
 554        diff_opts.recursive = 1;
 555        diff_opts.detect_rename = DIFF_DETECT_RENAME;
 556        paths[0] = NULL;
 557        diff_tree_setup_paths(paths, &diff_opts);
 558        if (diff_setup_done(&diff_opts) < 0)
 559                die("diff_setup_done failed");
 560
 561        diff_tree_sha1(commit->tree->object.sha1, parent->tree->object.sha1,
 562                       "", &diff_opts);
 563        diffcore_std(&diff_opts);
 564
 565        for (i = 0; i < diff_queued_diff.nr; i++) {
 566                struct diff_filepair *p = diff_queued_diff.queue[i];
 567
 568                if (p->status == 'R' &&
 569                    !strcmp(p->one->path, cutil->pathname)) {
 570                        if (DEBUG)
 571                                printf("rename %s -> %s\n",
 572                                       p->one->path, p->two->path);
 573                        return p->two->path;
 574                }
 575        }
 576
 577        return 0;
 578}
 579
 580static void simplify_commit(struct rev_info *revs, struct commit *commit)
 581{
 582        struct commit_list **pp, *parent;
 583
 584        if (!commit->tree)
 585                return;
 586
 587        if (!commit->parents) {
 588                struct util_info *util = commit->util;
 589                if (!same_tree_as_empty_path(revs, commit->tree,
 590                                             util->pathname))
 591                        commit->object.flags |= TREECHANGE;
 592                return;
 593        }
 594
 595        pp = &commit->parents;
 596        while ((parent = *pp) != NULL) {
 597                struct commit *p = parent->item;
 598
 599                if (p->object.flags & UNINTERESTING) {
 600                        pp = &parent->next;
 601                        continue;
 602                }
 603
 604                parse_commit(p);
 605                switch (compare_tree_path(revs, p, commit)) {
 606                case REV_TREE_SAME:
 607                        parent->next = NULL;
 608                        commit->parents = parent;
 609                        get_util(p)->pathname = get_util(commit)->pathname;
 610                        return;
 611
 612                case REV_TREE_NEW:
 613                {
 614                        struct util_info *util = commit->util;
 615                        if (revs->remove_empty_trees &&
 616                            same_tree_as_empty_path(revs, p->tree,
 617                                                    util->pathname)) {
 618                                const char *new_name = find_rename(commit, p);
 619                                if (new_name) {
 620                                        struct util_info *putil = get_util(p);
 621                                        if (!putil->pathname)
 622                                                putil->pathname = xstrdup(new_name);
 623                                }
 624                                else {
 625                                        *pp = parent->next;
 626                                        continue;
 627                                }
 628                        }
 629                }
 630
 631                /* fallthrough */
 632                case REV_TREE_DIFFERENT:
 633                        pp = &parent->next;
 634                        if (!get_util(p)->pathname)
 635                                get_util(p)->pathname =
 636                                        get_util(commit)->pathname;
 637                        continue;
 638                }
 639                die("bad tree compare for commit %s",
 640                    sha1_to_hex(commit->object.sha1));
 641        }
 642        commit->object.flags |= TREECHANGE;
 643}
 644
 645struct commit_info
 646{
 647        char *author;
 648        char *author_mail;
 649        unsigned long author_time;
 650        char *author_tz;
 651
 652        /* filled only when asked for details */
 653        char *committer;
 654        char *committer_mail;
 655        unsigned long committer_time;
 656        char *committer_tz;
 657
 658        char *summary;
 659};
 660
 661static void get_ac_line(const char *inbuf, const char *what,
 662                        int bufsz, char *person, char **mail,
 663                        unsigned long *time, char **tz)
 664{
 665        int len;
 666        char *tmp, *endp;
 667
 668        tmp = strstr(inbuf, what);
 669        if (!tmp)
 670                goto error_out;
 671        tmp += strlen(what);
 672        endp = strchr(tmp, '\n');
 673        if (!endp)
 674                len = strlen(tmp);
 675        else
 676                len = endp - tmp;
 677        if (bufsz <= len) {
 678        error_out:
 679                /* Ugh */
 680                person = *mail = *tz = "(unknown)";
 681                *time = 0;
 682                return;
 683        }
 684        memcpy(person, tmp, len);
 685
 686        tmp = person;
 687        tmp += len;
 688        *tmp = 0;
 689        while (*tmp != ' ')
 690                tmp--;
 691        *tz = tmp+1;
 692
 693        *tmp = 0;
 694        while (*tmp != ' ')
 695                tmp--;
 696        *time = strtoul(tmp, NULL, 10);
 697
 698        *tmp = 0;
 699        while (*tmp != ' ')
 700                tmp--;
 701        *mail = tmp + 1;
 702        *tmp = 0;
 703}
 704
 705static void get_commit_info(struct commit *commit, struct commit_info *ret, int detailed)
 706{
 707        int len;
 708        char *tmp, *endp;
 709        static char author_buf[1024];
 710        static char committer_buf[1024];
 711        static char summary_buf[1024];
 712
 713        ret->author = author_buf;
 714        get_ac_line(commit->buffer, "\nauthor ",
 715                    sizeof(author_buf), author_buf, &ret->author_mail,
 716                    &ret->author_time, &ret->author_tz);
 717
 718        if (!detailed)
 719                return;
 720
 721        ret->committer = committer_buf;
 722        get_ac_line(commit->buffer, "\ncommitter ",
 723                    sizeof(committer_buf), committer_buf, &ret->committer_mail,
 724                    &ret->committer_time, &ret->committer_tz);
 725
 726        ret->summary = summary_buf;
 727        tmp = strstr(commit->buffer, "\n\n");
 728        if (!tmp) {
 729        error_out:
 730                sprintf(summary_buf, "(%s)", sha1_to_hex(commit->object.sha1));
 731                return;
 732        }
 733        tmp += 2;
 734        endp = strchr(tmp, '\n');
 735        if (!endp)
 736                goto error_out;
 737        len = endp - tmp;
 738        if (len >= sizeof(summary_buf))
 739                goto error_out;
 740        memcpy(summary_buf, tmp, len);
 741        summary_buf[len] = 0;
 742}
 743
 744static const char *format_time(unsigned long time, const char *tz_str,
 745                               int show_raw_time)
 746{
 747        static char time_buf[128];
 748        time_t t = time;
 749        int minutes, tz;
 750        struct tm *tm;
 751
 752        if (show_raw_time) {
 753                sprintf(time_buf, "%lu %s", time, tz_str);
 754                return time_buf;
 755        }
 756
 757        tz = atoi(tz_str);
 758        minutes = tz < 0 ? -tz : tz;
 759        minutes = (minutes / 100)*60 + (minutes % 100);
 760        minutes = tz < 0 ? -minutes : minutes;
 761        t = time + minutes * 60;
 762        tm = gmtime(&t);
 763
 764        strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S ", tm);
 765        strcat(time_buf, tz_str);
 766        return time_buf;
 767}
 768
 769static void topo_setter(struct commit *c, void *data)
 770{
 771        struct util_info *util = c->util;
 772        util->topo_data = data;
 773}
 774
 775static void *topo_getter(struct commit *c)
 776{
 777        struct util_info *util = c->util;
 778        return util->topo_data;
 779}
 780
 781static int read_ancestry(const char *graft_file,
 782                         unsigned char **start_sha1)
 783{
 784        FILE *fp = fopen(graft_file, "r");
 785        char buf[1024];
 786        if (!fp)
 787                return -1;
 788        while (fgets(buf, sizeof(buf), fp)) {
 789                /* The format is just "Commit Parent1 Parent2 ...\n" */
 790                int len = strlen(buf);
 791                struct commit_graft *graft = read_graft_line(buf, len);
 792                register_commit_graft(graft, 0);
 793                if (!*start_sha1)
 794                        *start_sha1 = graft->sha1;
 795        }
 796        fclose(fp);
 797        return 0;
 798}
 799
 800static int lineno_width(int lines)
 801{
 802        int i, width;
 803
 804        for (width = 1, i = 10; i <= lines + 1; width++)
 805                i *= 10;
 806        return width;
 807}
 808
 809static int find_orig_linenum(struct util_info *u, int lineno)
 810{
 811        int i;
 812
 813        for (i = 0; i < u->num_lines; i++)
 814                if (lineno == u->line_map[i])
 815                        return i + 1;
 816        return 0;
 817}
 818
 819static void emit_meta(struct commit *c, int lno,
 820                      int sha1_len, int compatibility, int porcelain,
 821                      int show_name, int show_number, int show_raw_time,
 822                      int longest_file, int longest_author,
 823                      int max_digits, int max_orig_digits)
 824{
 825        struct util_info *u;
 826        int lineno;
 827        struct commit_info ci;
 828
 829        u = c->util;
 830        lineno = find_orig_linenum(u, lno);
 831
 832        if (porcelain) {
 833                int group_size = -1;
 834                struct commit *cc = (lno == 0) ? NULL : blame_lines[lno-1];
 835                if (cc != c) {
 836                        /* This is the beginning of this group */
 837                        int i;
 838                        for (i = lno + 1; i < num_blame_lines; i++)
 839                                if (blame_lines[i] != c)
 840                                        break;
 841                        group_size = i - lno;
 842                }
 843                if (0 < group_size)
 844                        printf("%s %d %d %d\n", sha1_to_hex(c->object.sha1),
 845                               lineno, lno + 1, group_size);
 846                else
 847                        printf("%s %d %d\n", sha1_to_hex(c->object.sha1),
 848                               lineno, lno + 1);
 849                if (!u->meta_given) {
 850                        get_commit_info(c, &ci, 1);
 851                        printf("author %s\n", ci.author);
 852                        printf("author-mail %s\n", ci.author_mail);
 853                        printf("author-time %lu\n", ci.author_time);
 854                        printf("author-tz %s\n", ci.author_tz);
 855                        printf("committer %s\n", ci.committer);
 856                        printf("committer-mail %s\n", ci.committer_mail);
 857                        printf("committer-time %lu\n", ci.committer_time);
 858                        printf("committer-tz %s\n", ci.committer_tz);
 859                        printf("filename ");
 860                        if (quote_c_style(u->pathname, NULL, NULL, 0))
 861                                quote_c_style(u->pathname, NULL, stdout, 0);
 862                        else
 863                                fputs(u->pathname, stdout);
 864                        printf("\nsummary %s\n", ci.summary);
 865
 866                        u->meta_given = 1;
 867                }
 868                putchar('\t');
 869                return;
 870        }
 871
 872        get_commit_info(c, &ci, 0);
 873        fwrite(sha1_to_hex(c->object.sha1), sha1_len, 1, stdout);
 874        if (compatibility) {
 875                printf("\t(%10s\t%10s\t%d)", ci.author,
 876                       format_time(ci.author_time, ci.author_tz,
 877                                   show_raw_time),
 878                       lno + 1);
 879        }
 880        else {
 881                if (show_name)
 882                        printf(" %-*.*s", longest_file, longest_file,
 883                               u->pathname);
 884                if (show_number)
 885                        printf(" %*d", max_orig_digits,
 886                               lineno);
 887                printf(" (%-*.*s %10s %*d) ",
 888                       longest_author, longest_author, ci.author,
 889                       format_time(ci.author_time, ci.author_tz,
 890                                   show_raw_time),
 891                       max_digits, lno + 1);
 892        }
 893}
 894
 895int main(int argc, const char **argv)
 896{
 897        int i;
 898        struct commit *initial = NULL;
 899        unsigned char sha1[20], *sha1_p = NULL;
 900
 901        const char *filename = NULL, *commit = NULL;
 902        char filename_buf[256];
 903        int sha1_len = 8;
 904        int compatibility = 0;
 905        int show_raw_time = 0;
 906        int options = 1;
 907        struct commit *start_commit;
 908
 909        const char *args[10];
 910        struct rev_info rev;
 911
 912        struct commit_info ci;
 913        const char *buf;
 914        int max_digits, max_orig_digits;
 915        int longest_file, longest_author, longest_file_lines;
 916        int show_name = 0;
 917        int show_number = 0;
 918        int porcelain = 0;
 919
 920        const char *prefix = setup_git_directory();
 921        git_config(git_default_config);
 922
 923        for (i = 1; i < argc; i++) {
 924                if (options) {
 925                        if (!strcmp(argv[i], "-h") ||
 926                           !strcmp(argv[i], "--help"))
 927                                usage(blame_usage);
 928                        if (!strcmp(argv[i], "-l") ||
 929                            !strcmp(argv[i], "--long")) {
 930                                sha1_len = 40;
 931                                continue;
 932                        }
 933                        if (!strcmp(argv[i], "-c") ||
 934                            !strcmp(argv[i], "--compatibility")) {
 935                                compatibility = 1;
 936                                continue;
 937                        }
 938                        if (!strcmp(argv[i], "-t") ||
 939                            !strcmp(argv[i], "--time")) {
 940                                show_raw_time = 1;
 941                                continue;
 942                        }
 943                        if (!strcmp(argv[i], "-S")) {
 944                                if (i + 1 < argc &&
 945                                    !read_ancestry(argv[i + 1], &sha1_p)) {
 946                                        compatibility = 1;
 947                                        i++;
 948                                        continue;
 949                                }
 950                                usage(blame_usage);
 951                        }
 952                        if (!strcmp(argv[i], "-f") ||
 953                            !strcmp(argv[i], "--show-name")) {
 954                                show_name = 1;
 955                                continue;
 956                        }
 957                        if (!strcmp(argv[i], "-n") ||
 958                            !strcmp(argv[i], "--show-number")) {
 959                                show_number = 1;
 960                                continue;
 961                        }
 962                        if (!strcmp(argv[i], "-p") ||
 963                            !strcmp(argv[i], "--porcelain")) {
 964                                porcelain = 1;
 965                                sha1_len = 40;
 966                                show_raw_time = 1;
 967                                continue;
 968                        }
 969                        if (!strcmp(argv[i], "--")) {
 970                                options = 0;
 971                                continue;
 972                        }
 973                        if (argv[i][0] == '-')
 974                                usage(blame_usage);
 975                        options = 0;
 976                }
 977
 978                if (!options) {
 979                        if (!filename)
 980                                filename = argv[i];
 981                        else if (!commit)
 982                                commit = argv[i];
 983                        else
 984                                usage(blame_usage);
 985                }
 986        }
 987
 988        if (!filename)
 989                usage(blame_usage);
 990        if (commit && sha1_p)
 991                usage(blame_usage);
 992        else if (!commit)
 993                commit = "HEAD";
 994
 995        if (prefix)
 996                sprintf(filename_buf, "%s%s", prefix, filename);
 997        else
 998                strcpy(filename_buf, filename);
 999        filename = filename_buf;
1000
1001        if (!sha1_p) {
1002                if (get_sha1(commit, sha1))
1003                        die("get_sha1 failed, commit '%s' not found", commit);
1004                sha1_p = sha1;
1005        }
1006        start_commit = lookup_commit_reference(sha1_p);
1007        get_util(start_commit)->pathname = filename;
1008        if (fill_util_info(start_commit)) {
1009                printf("%s not found in %s\n", filename, commit);
1010                return 1;
1011        }
1012
1013        init_revisions(&rev, setup_git_directory());
1014        rev.remove_empty_trees = 1;
1015        rev.topo_order = 1;
1016        rev.prune_fn = simplify_commit;
1017        rev.topo_setter = topo_setter;
1018        rev.topo_getter = topo_getter;
1019        rev.parents = 1;
1020        rev.limited = 1;
1021
1022        commit_list_insert(start_commit, &rev.commits);
1023
1024        args[0] = filename;
1025        args[1] = NULL;
1026        diff_tree_setup_paths(args, &rev.pruning);
1027        prepare_revision_walk(&rev);
1028        process_commits(&rev, filename, &initial);
1029
1030        for (i = 0; i < num_blame_lines; i++)
1031                if (!blame_lines[i])
1032                        blame_lines[i] = initial;
1033
1034        buf = blame_contents;
1035        max_digits = lineno_width(num_blame_lines);
1036
1037        longest_file = 0;
1038        longest_author = 0;
1039        longest_file_lines = 0;
1040        for (i = 0; i < num_blame_lines; i++) {
1041                struct commit *c = blame_lines[i];
1042                struct util_info *u;
1043                u = c->util;
1044
1045                if (!show_name && strcmp(filename, u->pathname))
1046                        show_name = 1;
1047                if (longest_file < strlen(u->pathname))
1048                        longest_file = strlen(u->pathname);
1049                if (longest_file_lines < u->num_lines)
1050                        longest_file_lines = u->num_lines;
1051                get_commit_info(c, &ci, 0);
1052                if (longest_author < strlen(ci.author))
1053                        longest_author = strlen(ci.author);
1054        }
1055
1056        max_orig_digits = lineno_width(longest_file_lines);
1057
1058        for (i = 0; i < num_blame_lines; i++) {
1059                emit_meta(blame_lines[i], i,
1060                          sha1_len, compatibility, porcelain,
1061                          show_name, show_number, show_raw_time,
1062                          longest_file, longest_author,
1063                          max_digits, max_orig_digits);
1064
1065                if (i == num_blame_lines - 1) {
1066                        fwrite(buf, blame_len - (buf - blame_contents),
1067                               1, stdout);
1068                        if (blame_contents[blame_len-1] != '\n')
1069                                putc('\n', stdout);
1070                }
1071                else {
1072                        char *next_buf = strchr(buf, '\n') + 1;
1073                        fwrite(buf, next_buf - buf, 1, stdout);
1074                        buf = next_buf;
1075                }
1076        }
1077
1078        if (DEBUG) {
1079                printf("num get patch: %d\n", num_get_patch);
1080                printf("num commits: %d\n", num_commits);
1081                printf("patch time: %f\n", patch_time / 1000000.0);
1082                printf("initial: %s\n", sha1_to_hex(initial->object.sha1));
1083        }
1084
1085        return 0;
1086}