diff-helper.con commit [PATCH] Fix rename/copy when dealing with temporarily broken pairs. (2210100)
   1/*
   2 * Copyright (C) 2005 Junio C Hamano
   3 */
   4#include "cache.h"
   5#include "strbuf.h"
   6#include "diff.h"
   7
   8static const char *pickaxe = NULL;
   9static int pickaxe_opts = 0;
  10static const char *orderfile = NULL;
  11static int line_termination = '\n';
  12static int inter_name_termination = '\t';
  13
  14static void flush_them(int ac, const char **av)
  15{
  16        diffcore_std(av + 1,
  17                     0, 0, /* no renames */
  18                     pickaxe, pickaxe_opts,
  19                     -1, /* no breaks */
  20                     orderfile);
  21        diff_flush(DIFF_FORMAT_PATCH, 0);
  22}
  23
  24static const char *diff_helper_usage =
  25        "git-diff-helper [-z] [-S<string>] [-O<orderfile>] paths...";
  26
  27int main(int ac, const char **av) {
  28        struct strbuf sb;
  29        const char *garbage_flush_format;
  30
  31        strbuf_init(&sb);
  32
  33        while (1 < ac && av[1][0] == '-') {
  34                if (av[1][1] == 'z')
  35                        line_termination = inter_name_termination = 0;
  36                else if (av[1][1] == 'S') {
  37                        pickaxe = av[1] + 2;
  38                }
  39                else if (!strcmp(av[1], "--pickaxe-all"))
  40                        pickaxe_opts = DIFF_PICKAXE_ALL;
  41                else
  42                        usage(diff_helper_usage);
  43                ac--; av++;
  44        }
  45        garbage_flush_format = (line_termination == 0) ? "%s" : "%s\n";
  46
  47        /* the remaining parameters are paths patterns */
  48
  49        diff_setup(0);
  50        while (1) {
  51                unsigned old_mode, new_mode;
  52                unsigned char old_sha1[20], new_sha1[20];
  53                char old_path[PATH_MAX];
  54                int status, score, two_paths;
  55                char new_path[PATH_MAX];
  56
  57                int ch;
  58                char *cp, *ep;
  59
  60                read_line(&sb, stdin, line_termination);
  61                if (sb.eof)
  62                        break;
  63                switch (sb.buf[0]) {
  64                case ':':
  65                        /* parse the first part up to the status */
  66                        cp = sb.buf + 1;
  67                        old_mode = new_mode = 0;
  68                        while ((ch = *cp) && ('0' <= ch && ch <= '7')) {
  69                                old_mode = (old_mode << 3) | (ch - '0');
  70                                cp++;
  71                        }
  72                        if (*cp++ != ' ')
  73                                break;
  74                        while ((ch = *cp) && ('0' <= ch && ch <= '7')) {
  75                                new_mode = (new_mode << 3) | (ch - '0');
  76                                cp++;
  77                        }
  78                        if (*cp++ != ' ')
  79                                break;
  80                        if (get_sha1_hex(cp, old_sha1))
  81                                break;
  82                        cp += 40;
  83                        if (*cp++ != ' ')
  84                                break;
  85                        if (get_sha1_hex(cp, new_sha1))
  86                                break;
  87                        cp += 40;
  88                        if (*cp++ != ' ')
  89                                break;
  90                        status = *cp++;
  91                        if (!strchr("MCRNDU", status))
  92                                break;
  93                        two_paths = score = 0;
  94                        if (status == 'R' || status == 'C')
  95                                two_paths = 1;
  96
  97                        /* pick up score if exists */
  98                        if (sscanf(cp, "%d", &score) != 1)
  99                                score = 0;
 100                        cp = strchr(cp,
 101                                    inter_name_termination);
 102                        if (!cp)
 103                                break;
 104                        if (*cp++ != inter_name_termination)
 105                                break;
 106
 107                        /* first pathname */
 108                        if (!line_termination) {
 109                                read_line(&sb, stdin, line_termination);
 110                                if (sb.eof)
 111                                        break;
 112                                strcpy(old_path, sb.buf);
 113                        }
 114                        else if (!two_paths)
 115                                strcpy(old_path, cp);
 116                        else {
 117                                ep = strchr(cp, inter_name_termination);
 118                                if (!ep)
 119                                        break;
 120                                strncpy(old_path, cp, ep-cp);
 121                                old_path[ep-cp] = 0;
 122                                cp = ep + 1;
 123                        }
 124
 125                        /* second pathname */
 126                        if (!two_paths)
 127                                strcpy(new_path, old_path);
 128                        else {
 129                                if (!line_termination) {
 130                                        read_line(&sb, stdin,
 131                                                  line_termination);
 132                                        if (sb.eof)
 133                                                break;
 134                                        strcpy(new_path, sb.buf);
 135                                }
 136                                else
 137                                        strcpy(new_path, cp);
 138                        }
 139                        diff_helper_input(old_mode, new_mode,
 140                                          old_sha1, new_sha1,
 141                                          old_path, status, score,
 142                                          new_path);
 143                        continue;
 144                }
 145                flush_them(ac, av);
 146                printf(garbage_flush_format, sb.buf);
 147        }
 148        flush_them(ac, av);
 149        return 0;
 150}