diff-helper.con commit Start implementing "git-apply" (c1bb935)
   1/*
   2 * Copyright (C) 2005 Junio C Hamano
   3 */
   4#include "cache.h"
   5#include "strbuf.h"
   6#include "diff.h"
   7
   8static int detect_rename = 0;
   9static int diff_score_opt = 0;
  10static const char *pickaxe = NULL;
  11static int diff_output_style = DIFF_FORMAT_PATCH;
  12static int line_termination = '\n';
  13static int inter_name_termination = '\t';
  14
  15static int parse_diff_raw(char *buf1, char *buf2, char *buf3)
  16{
  17        char old_path[PATH_MAX];
  18        unsigned char old_sha1[20], new_sha1[20];
  19        char *ep;
  20        char *cp = buf1;
  21        int ch, old_mode, new_mode;
  22
  23        old_mode = new_mode = 0;
  24        while ((ch = *cp) && ('0' <= ch && ch <= '7')) {
  25                old_mode = (old_mode << 3) | (ch - '0');
  26                cp++;
  27        }
  28        if (*cp++ != ' ')
  29                return -1;
  30        while ((ch = *cp) && ('0' <= ch && ch <= '7')) {
  31                new_mode = (new_mode << 3) | (ch - '0');
  32                cp++;
  33        }
  34        if (*cp++ != ' ')
  35                return -1;
  36        if (get_sha1_hex(cp, old_sha1))
  37                return -1;
  38        cp += 40;
  39        if (*cp++ != ' ')
  40                return -1;
  41        if (get_sha1_hex(cp, new_sha1))
  42                return -1;
  43        cp += 40;
  44        if (*cp++ != inter_name_termination)
  45                return -1;
  46        if (buf2)
  47                cp = buf2;
  48        ep = strchr(cp, inter_name_termination);
  49        if (!ep)
  50                return -1;
  51        *ep++ = 0;
  52        strcpy(old_path, cp);
  53        diff_guif(old_mode, new_mode, old_sha1, new_sha1,
  54                  old_path, buf3 ? buf3 : ep);
  55        return 0;
  56}
  57
  58static const char *diff_helper_usage =
  59        "git-diff-helper [-z] [-R] [-M] [-C] [-S<string>] paths...";
  60
  61int main(int ac, const char **av) {
  62        struct strbuf sb1, sb2, sb3;
  63        int reverse_diff = 0;
  64
  65        strbuf_init(&sb1);
  66        strbuf_init(&sb2);
  67        strbuf_init(&sb3);
  68
  69        while (1 < ac && av[1][0] == '-') {
  70                if (av[1][1] == 'R')
  71                        reverse_diff = 1;
  72                else if (av[1][1] == 'z')
  73                        line_termination = inter_name_termination = 0;
  74                else if (av[1][1] == 'p') /* hidden from the help */
  75                        diff_output_style = DIFF_FORMAT_HUMAN;
  76                else if (av[1][1] == 'P') /* hidden from the help */
  77                        diff_output_style = DIFF_FORMAT_MACHINE;
  78                else if (av[1][1] == 'M') {
  79                        detect_rename = DIFF_DETECT_RENAME;
  80                        diff_score_opt = diff_scoreopt_parse(av[1]);
  81                }
  82                else if (av[1][1] == 'C') {
  83                        detect_rename = DIFF_DETECT_COPY;
  84                        diff_score_opt = diff_scoreopt_parse(av[1]);
  85                }
  86                else if (av[1][1] == 'S') {
  87                        pickaxe = av[1] + 2;
  88                }
  89                else
  90                        usage(diff_helper_usage);
  91                ac--; av++;
  92        }
  93        /* the remaining parameters are paths patterns */
  94
  95        diff_setup(reverse_diff);
  96        while (1) {
  97                int status;
  98                read_line(&sb1, stdin, line_termination);
  99                if (sb1.eof)
 100                        break;
 101                switch (sb1.buf[0]) {
 102                case 'U':
 103                        diff_unmerge(sb1.buf + 2);
 104                        continue;
 105                case ':':
 106                        break;
 107                default:
 108                        goto unrecognized;
 109                }
 110                if (!line_termination) {
 111                        read_line(&sb2, stdin, line_termination);
 112                        if (sb2.eof)
 113                                break;
 114                        read_line(&sb3, stdin, line_termination);
 115                        if (sb3.eof)
 116                                break;
 117                        status = parse_diff_raw(sb1.buf+1, sb2.buf, sb3.buf);
 118                }
 119                else
 120                        status = parse_diff_raw(sb1.buf+1, NULL, NULL);
 121                if (status) {
 122                unrecognized:
 123                        diff_flush(diff_output_style);
 124                        printf("%s%c", sb1.buf, line_termination);
 125                }
 126        }
 127        if (detect_rename)
 128                diffcore_rename(detect_rename, diff_score_opt);
 129        diffcore_prune();
 130        if (pickaxe)
 131                diffcore_pickaxe(pickaxe);
 132        if (ac)
 133                diffcore_pathspec(av + 1);
 134        diff_flush(diff_output_style);
 135        return 0;
 136}