rev-parse.con commit [PATCH] Make "git diff" work inside relative subdirectories (d288a70)
   1/*
   2 * rev-parse.c
   3 *
   4 * Copyright (C) Linus Torvalds, 2005
   5 */
   6#include "cache.h"
   7#include "commit.h"
   8#include "refs.h"
   9
  10static char *def = NULL;
  11static int no_revs = 0;
  12static int single_rev = 0;
  13static int revs_only = 0;
  14static int do_rev_argument = 1;
  15static int output_revs = 0;
  16static int flags_only = 0;
  17static int no_flags = 0;
  18static int output_sq = 0;
  19
  20#define NORMAL 0
  21#define REVERSED 1
  22static int show_type = NORMAL;
  23
  24/*
  25 * Some arguments are relevant "revision" arguments,
  26 * others are about output format or other details.
  27 * This sorts it all out.
  28 */
  29static int is_rev_argument(const char *arg)
  30{
  31        static const char *rev_args[] = {
  32                "--max-count=",
  33                "--max-age=",
  34                "--min-age=",
  35                "--merge-order",
  36                "--topo-order",
  37                "--bisect",
  38                "--no-merges",
  39                NULL
  40        };
  41        const char **p = rev_args;
  42
  43        for (;;) {
  44                const char *str = *p++;
  45                int len;
  46                if (!str)
  47                        return 0;
  48                len = strlen(str);
  49                if (!strncmp(arg, str, len))
  50                        return 1;
  51        }
  52}
  53
  54static void show(const char *arg)
  55{
  56        if (output_sq) {
  57                int sq = '\'', ch;
  58
  59                putchar(sq);
  60                while ((ch = *arg++)) {
  61                        if (ch == sq)
  62                                fputs("'\\'", stdout);
  63                        putchar(ch);
  64                }
  65                putchar(sq);
  66                putchar(' ');
  67        }
  68        else
  69                puts(arg);
  70}
  71
  72static void show_rev(int type, const unsigned char *sha1)
  73{
  74        if (no_revs)
  75                return;
  76        output_revs++;
  77
  78        /* Hexadecimal string plus possibly a carret;
  79         * this does not have to be quoted even under output_sq.
  80         */
  81        printf("%s%s%c", type == show_type ? "" : "^", sha1_to_hex(sha1),
  82               output_sq ? ' ' : '\n');
  83}
  84
  85static void show_rev_arg(char *rev)
  86{
  87        if (no_revs)
  88                return;
  89        show(rev);
  90}
  91
  92static void show_norev(char *norev)
  93{
  94        if (flags_only)
  95                return;
  96        if (revs_only)
  97                return;
  98        show(norev);
  99}
 100
 101static void show_arg(char *arg)
 102{
 103        if (no_flags)
 104                return;
 105        if (do_rev_argument && is_rev_argument(arg))
 106                show_rev_arg(arg);
 107        else
 108                show_norev(arg);
 109}
 110
 111static void show_default(void)
 112{
 113        char *s = def;
 114
 115        if (s) {
 116                unsigned char sha1[20];
 117
 118                def = NULL;
 119                if (!get_sha1(s, sha1)) {
 120                        show_rev(NORMAL, sha1);
 121                        return;
 122                }
 123                show_arg(s);
 124        }
 125}
 126
 127static int show_reference(const char *refname, const unsigned char *sha1)
 128{
 129        show_rev(NORMAL, sha1);
 130        return 0;
 131}
 132
 133int main(int argc, char **argv)
 134{
 135        int i, as_is = 0;
 136        unsigned char sha1[20];
 137        const char *prefix = setup_git_directory();
 138        
 139        for (i = 1; i < argc; i++) {
 140                char *arg = argv[i];
 141                char *dotdot;
 142        
 143                if (as_is) {
 144                        show_norev(arg);
 145                        continue;
 146                }
 147                if (*arg == '-') {
 148                        if (!strcmp(arg, "--")) {
 149                                show_default();
 150                                if (revs_only)
 151                                        break;
 152                                as_is = 1;
 153                        }
 154                        if (!strcmp(arg, "--default")) {
 155                                def = argv[i+1];
 156                                i++;
 157                                continue;
 158                        }
 159                        if (!strcmp(arg, "--revs-only")) {
 160                                revs_only = 1;
 161                                continue;
 162                        }
 163                        if (!strcmp(arg, "--no-revs")) {
 164                                no_revs = 1;
 165                                continue;
 166                        }
 167                        if (!strcmp(arg, "--flags")) {
 168                                flags_only = 1;
 169                                continue;
 170                        }
 171                        if (!strcmp(arg, "--no-flags")) {
 172                                no_flags = 1;
 173                                continue;
 174                        }
 175                        if (!strcmp(arg, "--verify")) {
 176                                revs_only = 1;
 177                                do_rev_argument = 0;
 178                                single_rev = 1;
 179                                continue;
 180                        }
 181                        if (!strcmp(arg, "--sq")) {
 182                                output_sq = 1;
 183                                continue;
 184                        }
 185                        if (!strcmp(arg, "--not")) {
 186                                show_type ^= REVERSED;
 187                                continue;
 188                        }
 189                        if (!strcmp(arg, "--all")) {
 190                                for_each_ref(show_reference);
 191                                continue;
 192                        }
 193                        if (!strcmp(arg, "--show-prefix")) {
 194                                puts(prefix);
 195                                continue;
 196                        }
 197                        show_arg(arg);
 198                        continue;
 199                }
 200                dotdot = strstr(arg, "..");
 201                if (dotdot) {
 202                        unsigned char end[20];
 203                        char *n = dotdot+2;
 204                        *dotdot = 0;
 205                        if (!get_sha1(arg, sha1)) {
 206                                if (!*n)
 207                                        n = "HEAD";
 208                                if (!get_sha1(n, end)) {
 209                                        if (no_revs)
 210                                                continue;
 211                                        def = NULL;
 212                                        show_rev(NORMAL, end);
 213                                        show_rev(REVERSED, sha1);
 214                                        continue;
 215                                }
 216                        }
 217                        *dotdot = '.';
 218                }
 219                if (!get_sha1(arg, sha1)) {
 220                        if (no_revs)
 221                                continue;
 222                        def = NULL;
 223                        show_rev(NORMAL, sha1);
 224                        continue;
 225                }
 226                if (*arg == '^' && !get_sha1(arg+1, sha1)) {
 227                        if (no_revs)
 228                                continue;
 229                        def = NULL;
 230                        show_rev(REVERSED, sha1);
 231                        continue;
 232                }
 233                show_default();
 234                show_norev(arg);
 235        }
 236        show_default();
 237        if (single_rev && output_revs != 1) {
 238                fprintf(stderr, "Needed a single revision\n");
 239                exit(1);
 240        }
 241        return 0;
 242}