rev-parse.con commit Merge with master. (e764a10)
   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                NULL
  37        };
  38        const char **p = rev_args;
  39
  40        for (;;) {
  41                const char *str = *p++;
  42                int len;
  43                if (!str)
  44                        return 0;
  45                len = strlen(str);
  46                if (!strncmp(arg, str, len))
  47                        return 1;
  48        }
  49}
  50
  51static void show(const char *arg)
  52{
  53        if (output_sq) {
  54                int sq = '\'', ch;
  55
  56                putchar(sq);
  57                while ((ch = *arg++)) {
  58                        if (ch == sq)
  59                                fputs("'\\'", stdout);
  60                        putchar(ch);
  61                }
  62                putchar(sq);
  63                putchar(' ');
  64        }
  65        else
  66                puts(arg);
  67}
  68
  69static void show_rev(int type, const unsigned char *sha1)
  70{
  71        if (no_revs)
  72                return;
  73        output_revs++;
  74
  75        /* Hexadecimal string plus possibly a carret;
  76         * this does not have to be quoted even under output_sq.
  77         */
  78        printf("%s%s%c", type == show_type ? "" : "^", sha1_to_hex(sha1),
  79               output_sq ? ' ' : '\n');
  80}
  81
  82static void show_rev_arg(char *rev)
  83{
  84        if (no_revs)
  85                return;
  86        show(rev);
  87}
  88
  89static void show_norev(char *norev)
  90{
  91        if (flags_only)
  92                return;
  93        if (revs_only)
  94                return;
  95        show(norev);
  96}
  97
  98static void show_arg(char *arg)
  99{
 100        if (no_flags)
 101                return;
 102        if (do_rev_argument && is_rev_argument(arg))
 103                show_rev_arg(arg);
 104        else
 105                show_norev(arg);
 106}
 107
 108static void show_default(void)
 109{
 110        char *s = def;
 111
 112        if (s) {
 113                unsigned char sha1[20];
 114
 115                def = NULL;
 116                if (!get_sha1(s, sha1)) {
 117                        show_rev(NORMAL, sha1);
 118                        return;
 119                }
 120                show_arg(s);
 121        }
 122}
 123
 124static int show_reference(const char *refname, const unsigned char *sha1)
 125{
 126        show_rev(NORMAL, sha1);
 127        return 0;
 128}
 129
 130int main(int argc, char **argv)
 131{
 132        int i, as_is = 0;
 133        unsigned char sha1[20];
 134
 135        for (i = 1; i < argc; i++) {
 136                char *arg = argv[i];
 137                char *dotdot;
 138        
 139                if (as_is) {
 140                        show_norev(arg);
 141                        continue;
 142                }
 143                if (*arg == '-') {
 144                        if (!strcmp(arg, "--")) {
 145                                show_default();
 146                                if (revs_only)
 147                                        break;
 148                                as_is = 1;
 149                        }
 150                        if (!strcmp(arg, "--default")) {
 151                                def = argv[i+1];
 152                                i++;
 153                                continue;
 154                        }
 155                        if (!strcmp(arg, "--revs-only")) {
 156                                revs_only = 1;
 157                                continue;
 158                        }
 159                        if (!strcmp(arg, "--no-revs")) {
 160                                no_revs = 1;
 161                                continue;
 162                        }
 163                        if (!strcmp(arg, "--flags")) {
 164                                flags_only = 1;
 165                                continue;
 166                        }
 167                        if (!strcmp(arg, "--no-flags")) {
 168                                no_flags = 1;
 169                                continue;
 170                        }
 171                        if (!strcmp(arg, "--verify")) {
 172                                revs_only = 1;
 173                                do_rev_argument = 0;
 174                                single_rev = 1;
 175                                continue;
 176                        }
 177                        if (!strcmp(arg, "--sq")) {
 178                                output_sq = 1;
 179                                continue;
 180                        }
 181                        if (!strcmp(arg, "--not")) {
 182                                show_type ^= REVERSED;
 183                                continue;
 184                        }
 185                        if (!strcmp(arg, "--all")) {
 186                                for_each_ref(show_reference);
 187                                continue;
 188                        }
 189                        show_arg(arg);
 190                        continue;
 191                }
 192                dotdot = strstr(arg, "..");
 193                if (dotdot) {
 194                        unsigned char end[20];
 195                        char *n = dotdot+2;
 196                        *dotdot = 0;
 197                        if (!get_sha1(arg, sha1)) {
 198                                if (!*n)
 199                                        n = "HEAD";
 200                                if (!get_sha1(n, end)) {
 201                                        if (no_revs)
 202                                                continue;
 203                                        def = NULL;
 204                                        show_rev(NORMAL, end);
 205                                        show_rev(REVERSED, sha1);
 206                                        continue;
 207                                }
 208                        }
 209                        *dotdot = '.';
 210                }
 211                if (!get_sha1(arg, sha1)) {
 212                        if (no_revs)
 213                                continue;
 214                        def = NULL;
 215                        show_rev(NORMAL, sha1);
 216                        continue;
 217                }
 218                if (*arg == '^' && !get_sha1(arg+1, sha1)) {
 219                        if (no_revs)
 220                                continue;
 221                        def = NULL;
 222                        show_rev(REVERSED, sha1);
 223                        continue;
 224                }
 225                show_default();
 226                show_norev(arg);
 227        }
 228        show_default();
 229        if (single_rev && output_revs != 1) {
 230                fprintf(stderr, "Needed a single revision\n");
 231                exit(1);
 232        }
 233        return 0;
 234}