]>
Commit | Line | Data |
---|---|---|
178cb243 LT |
1 | /* |
2 | * rev-parse.c | |
3 | * | |
4 | * Copyright (C) Linus Torvalds, 2005 | |
5 | */ | |
6 | #include "cache.h" | |
a8be83fe LT |
7 | #include "commit.h" |
8 | ||
9 | static int get_extended_sha1(char *name, unsigned char *sha1); | |
178cb243 | 10 | |
921d865e LT |
11 | /* |
12 | * Some arguments are relevant "revision" arguments, | |
13 | * others are about output format or other details. | |
14 | * This sorts it all out. | |
15 | */ | |
16 | static int is_rev_argument(const char *arg) | |
17 | { | |
18 | static const char *rev_args[] = { | |
19 | "--max-count=", | |
20 | "--max-age=", | |
21 | "--min-age=", | |
22 | "--merge-order", | |
23 | NULL | |
24 | }; | |
25 | const char **p = rev_args; | |
26 | ||
27 | for (;;) { | |
28 | const char *str = *p++; | |
29 | int len; | |
30 | if (!str) | |
31 | return 0; | |
32 | len = strlen(str); | |
33 | if (!strncmp(arg, str, len)) | |
34 | return 1; | |
35 | } | |
36 | } | |
37 | ||
a8be83fe LT |
38 | static int get_parent(char *name, unsigned char *result, int idx) |
39 | { | |
40 | unsigned char sha1[20]; | |
41 | int ret = get_extended_sha1(name, sha1); | |
42 | struct commit *commit; | |
43 | struct commit_list *p; | |
44 | ||
45 | if (ret) | |
46 | return ret; | |
47 | commit = lookup_commit_reference(sha1); | |
48 | if (!commit) | |
49 | return -1; | |
50 | if (parse_commit(commit)) | |
51 | return -1; | |
52 | p = commit->parents; | |
53 | while (p) { | |
54 | if (!--idx) { | |
55 | memcpy(result, p->item->object.sha1, 20); | |
56 | return 0; | |
57 | } | |
58 | p = p->next; | |
59 | } | |
60 | return -1; | |
61 | } | |
62 | ||
63 | /* | |
64 | * This is like "get_sha1()", except it allows "sha1 expressions", | |
65 | * notably "xyz.p" for "parent of xyz" | |
66 | */ | |
67 | static int get_extended_sha1(char *name, unsigned char *sha1) | |
68 | { | |
69 | int parent; | |
70 | int len = strlen(name); | |
71 | ||
72 | parent = 1; | |
73 | if (len > 3 && name[len-1] >= '1' && name[len-1] <= '9') { | |
74 | parent = name[len-1] - '0'; | |
75 | len--; | |
76 | } | |
77 | if (len > 2 && !memcmp(name + len - 2, ".p", 2)) { | |
78 | int ret; | |
79 | name[len-2] = 0; | |
80 | ret = get_parent(name, sha1, parent); | |
81 | name[len-2] = '.'; | |
82 | if (!ret) | |
83 | return 0; | |
84 | } | |
85 | return get_sha1(name, sha1); | |
86 | } | |
87 | ||
178cb243 LT |
88 | int main(int argc, char **argv) |
89 | { | |
8ebb0184 | 90 | int i, as_is = 0, revs_only = 0, no_revs = 0; |
178cb243 LT |
91 | char *def = NULL; |
92 | unsigned char sha1[20]; | |
93 | ||
94 | for (i = 1; i < argc; i++) { | |
95 | char *arg = argv[i]; | |
96 | char *dotdot; | |
97 | ||
98 | if (as_is) { | |
99 | printf("%s\n", arg); | |
100 | continue; | |
101 | } | |
102 | if (*arg == '-') { | |
103 | if (!strcmp(arg, "--")) { | |
104 | if (def) { | |
105 | printf("%s\n", def); | |
106 | def = NULL; | |
107 | } | |
8ebb0184 LT |
108 | if (revs_only) |
109 | break; | |
178cb243 LT |
110 | as_is = 1; |
111 | } | |
112 | if (!strcmp(arg, "--default")) { | |
113 | if (def) | |
114 | printf("%s\n", def); | |
115 | def = argv[i+1]; | |
116 | i++; | |
117 | continue; | |
118 | } | |
8ebb0184 LT |
119 | if (!strcmp(arg, "--revs-only")) { |
120 | revs_only = 1; | |
121 | continue; | |
122 | } | |
123 | if (!strcmp(arg, "--no-revs")) { | |
124 | no_revs = 1; | |
125 | continue; | |
126 | } | |
921d865e LT |
127 | if (revs_only | no_revs) { |
128 | if (is_rev_argument(arg) != revs_only) | |
129 | continue; | |
130 | } | |
178cb243 LT |
131 | printf("%s\n", arg); |
132 | continue; | |
133 | } | |
178cb243 LT |
134 | dotdot = strstr(arg, ".."); |
135 | if (dotdot) { | |
136 | unsigned char end[20]; | |
137 | char *n = dotdot+2; | |
138 | *dotdot = 0; | |
a8be83fe | 139 | if (!get_extended_sha1(arg, sha1)) { |
178cb243 LT |
140 | if (!*n) |
141 | n = "HEAD"; | |
a8be83fe | 142 | if (!get_extended_sha1(n, end)) { |
8ebb0184 LT |
143 | if (no_revs) |
144 | continue; | |
145 | def = NULL; | |
178cb243 LT |
146 | printf("%s\n", sha1_to_hex(end)); |
147 | printf("^%s\n", sha1_to_hex(sha1)); | |
148 | continue; | |
149 | } | |
150 | } | |
151 | *dotdot = '.'; | |
152 | } | |
a8be83fe | 153 | if (!get_extended_sha1(arg, sha1)) { |
800644c5 LT |
154 | if (no_revs) |
155 | continue; | |
156 | def = NULL; | |
157 | printf("%s\n", sha1_to_hex(sha1)); | |
158 | continue; | |
159 | } | |
a8be83fe | 160 | if (*arg == '^' && !get_extended_sha1(arg+1, sha1)) { |
800644c5 LT |
161 | if (no_revs) |
162 | continue; | |
163 | def = NULL; | |
164 | printf("^%s\n", sha1_to_hex(sha1)); | |
165 | continue; | |
166 | } | |
9d73fad4 LT |
167 | if (def) { |
168 | printf("%s\n", def); | |
169 | def = NULL; | |
170 | } | |
8ebb0184 LT |
171 | if (revs_only) |
172 | continue; | |
178cb243 LT |
173 | printf("%s\n", arg); |
174 | } | |
175 | if (def) | |
176 | printf("%s\n", def); | |
177 | return 0; | |
178 | } |