]>
Commit | Line | Data |
---|---|---|
178cb243 LT |
1 | /* |
2 | * rev-parse.c | |
3 | * | |
4 | * Copyright (C) Linus Torvalds, 2005 | |
5 | */ | |
6 | #include "cache.h" | |
a8be83fe | 7 | #include "commit.h" |
960bba0d | 8 | #include "refs.h" |
a8be83fe | 9 | |
4866ccf0 JH |
10 | #define DO_REVS 1 |
11 | #define DO_NOREV 2 | |
12 | #define DO_FLAGS 4 | |
13 | #define DO_NONFLAGS 8 | |
14 | static int filter = ~0; | |
15 | ||
023d66ed | 16 | static char *def = NULL; |
023d66ed | 17 | |
042a4ed7 LT |
18 | #define NORMAL 0 |
19 | #define REVERSED 1 | |
20 | static int show_type = NORMAL; | |
4866ccf0 JH |
21 | static int symbolic = 0; |
22 | static int output_sq = 0; | |
23 | ||
24 | static int revs_count = 0; | |
042a4ed7 | 25 | |
921d865e LT |
26 | /* |
27 | * Some arguments are relevant "revision" arguments, | |
28 | * others are about output format or other details. | |
29 | * This sorts it all out. | |
30 | */ | |
31 | static int is_rev_argument(const char *arg) | |
32 | { | |
33 | static const char *rev_args[] = { | |
4866ccf0 JH |
34 | "--bisect", |
35 | "--header", | |
921d865e | 36 | "--max-age=", |
4866ccf0 | 37 | "--max-count=", |
921d865e | 38 | "--merge-order", |
4866ccf0 | 39 | "--min-age=", |
5ccfb758 | 40 | "--no-merges", |
4866ccf0 JH |
41 | "--objects", |
42 | "--parents", | |
43 | "--pretty", | |
44 | "--show-breaks", | |
45 | "--topo-order", | |
46 | "--unpacked", | |
921d865e LT |
47 | NULL |
48 | }; | |
49 | const char **p = rev_args; | |
50 | ||
51 | for (;;) { | |
52 | const char *str = *p++; | |
53 | int len; | |
54 | if (!str) | |
55 | return 0; | |
56 | len = strlen(str); | |
4866ccf0 JH |
57 | if (!strcmp(arg, str) || |
58 | (str[len-1] == '=' && !strncmp(arg, str, len))) | |
921d865e LT |
59 | return 1; |
60 | } | |
61 | } | |
62 | ||
4866ccf0 | 63 | /* Output argument as a string, either SQ or normal */ |
5bb2c65a JH |
64 | static void show(const char *arg) |
65 | { | |
66 | if (output_sq) { | |
67 | int sq = '\'', ch; | |
68 | ||
69 | putchar(sq); | |
70 | while ((ch = *arg++)) { | |
71 | if (ch == sq) | |
72 | fputs("'\\'", stdout); | |
73 | putchar(ch); | |
74 | } | |
75 | putchar(sq); | |
76 | putchar(' '); | |
77 | } | |
78 | else | |
79 | puts(arg); | |
80 | } | |
81 | ||
4866ccf0 | 82 | /* Output a revision, only if filter allows it */ |
30b96fce | 83 | static void show_rev(int type, const unsigned char *sha1, const char *name) |
023d66ed | 84 | { |
4866ccf0 | 85 | if (!(filter & DO_REVS)) |
023d66ed | 86 | return; |
4866ccf0 JH |
87 | def = NULL; |
88 | revs_count++; | |
5bb2c65a | 89 | |
30b96fce JH |
90 | if (type != show_type) |
91 | putchar('^'); | |
92 | if (symbolic && name) | |
93 | show(name); | |
94 | else | |
95 | show(sha1_to_hex(sha1)); | |
023d66ed LT |
96 | } |
97 | ||
4866ccf0 JH |
98 | /* Output a flag, only if filter allows it. */ |
99 | static void show_flag(char *arg) | |
023d66ed | 100 | { |
4866ccf0 | 101 | if (!(filter & DO_FLAGS)) |
023d66ed | 102 | return; |
4866ccf0 | 103 | if (filter & (is_rev_argument(arg) ? DO_REVS : DO_NOREV)) |
0360e99d | 104 | show(arg); |
023d66ed LT |
105 | } |
106 | ||
023d66ed LT |
107 | static void show_default(void) |
108 | { | |
109 | char *s = def; | |
110 | ||
111 | if (s) { | |
112 | unsigned char sha1[20]; | |
113 | ||
114 | def = NULL; | |
9938af6a | 115 | if (!get_sha1(s, sha1)) { |
30b96fce | 116 | show_rev(NORMAL, sha1, s); |
023d66ed LT |
117 | return; |
118 | } | |
023d66ed LT |
119 | } |
120 | } | |
121 | ||
960bba0d LT |
122 | static int show_reference(const char *refname, const unsigned char *sha1) |
123 | { | |
30b96fce | 124 | show_rev(NORMAL, sha1, refname); |
960bba0d LT |
125 | return 0; |
126 | } | |
127 | ||
178cb243 LT |
128 | int main(int argc, char **argv) |
129 | { | |
4866ccf0 | 130 | int i, as_is = 0, verify = 0; |
178cb243 | 131 | unsigned char sha1[20]; |
d288a700 LT |
132 | const char *prefix = setup_git_directory(); |
133 | ||
178cb243 LT |
134 | for (i = 1; i < argc; i++) { |
135 | char *arg = argv[i]; | |
136 | char *dotdot; | |
137 | ||
138 | if (as_is) { | |
4866ccf0 | 139 | show(arg); |
178cb243 LT |
140 | continue; |
141 | } | |
142 | if (*arg == '-') { | |
143 | if (!strcmp(arg, "--")) { | |
178cb243 | 144 | as_is = 1; |
4866ccf0 | 145 | continue; |
178cb243 LT |
146 | } |
147 | if (!strcmp(arg, "--default")) { | |
178cb243 LT |
148 | def = argv[i+1]; |
149 | i++; | |
150 | continue; | |
151 | } | |
8ebb0184 | 152 | if (!strcmp(arg, "--revs-only")) { |
4866ccf0 | 153 | filter &= ~DO_NOREV; |
8ebb0184 LT |
154 | continue; |
155 | } | |
156 | if (!strcmp(arg, "--no-revs")) { | |
4866ccf0 | 157 | filter &= ~DO_REVS; |
8ebb0184 LT |
158 | continue; |
159 | } | |
f79b65aa | 160 | if (!strcmp(arg, "--flags")) { |
4866ccf0 | 161 | filter &= ~DO_NONFLAGS; |
f79b65aa LT |
162 | continue; |
163 | } | |
164 | if (!strcmp(arg, "--no-flags")) { | |
4866ccf0 | 165 | filter &= ~DO_FLAGS; |
f79b65aa LT |
166 | continue; |
167 | } | |
023d66ed | 168 | if (!strcmp(arg, "--verify")) { |
4866ccf0 JH |
169 | filter &= ~(DO_FLAGS|DO_NOREV); |
170 | verify = 1; | |
023d66ed | 171 | continue; |
921d865e | 172 | } |
5bb2c65a JH |
173 | if (!strcmp(arg, "--sq")) { |
174 | output_sq = 1; | |
175 | continue; | |
176 | } | |
042a4ed7 LT |
177 | if (!strcmp(arg, "--not")) { |
178 | show_type ^= REVERSED; | |
179 | continue; | |
180 | } | |
30b96fce JH |
181 | if (!strcmp(arg, "--symbolic")) { |
182 | symbolic = 1; | |
183 | continue; | |
184 | } | |
960bba0d LT |
185 | if (!strcmp(arg, "--all")) { |
186 | for_each_ref(show_reference); | |
187 | continue; | |
188 | } | |
d288a700 | 189 | if (!strcmp(arg, "--show-prefix")) { |
4866ccf0 JH |
190 | if (prefix) |
191 | puts(prefix); | |
d288a700 LT |
192 | continue; |
193 | } | |
a8783eeb LT |
194 | if (!strcmp(arg, "--git-dir")) { |
195 | const char *gitdir = getenv(GIT_DIR_ENVIRONMENT); | |
196 | static char cwd[PATH_MAX]; | |
197 | if (gitdir) { | |
198 | puts(gitdir); | |
199 | continue; | |
200 | } | |
201 | if (!prefix) { | |
202 | puts(".git"); | |
203 | continue; | |
204 | } | |
205 | if (!getcwd(cwd, PATH_MAX)) | |
206 | die("unable to get current working directory"); | |
207 | printf("%s/.git\n", cwd); | |
208 | continue; | |
209 | } | |
4866ccf0 JH |
210 | if (verify) |
211 | die("Needed a single revision"); | |
212 | show_flag(arg); | |
178cb243 LT |
213 | continue; |
214 | } | |
4866ccf0 JH |
215 | |
216 | /* Not a flag argument */ | |
178cb243 LT |
217 | dotdot = strstr(arg, ".."); |
218 | if (dotdot) { | |
219 | unsigned char end[20]; | |
220 | char *n = dotdot+2; | |
221 | *dotdot = 0; | |
9938af6a | 222 | if (!get_sha1(arg, sha1)) { |
178cb243 LT |
223 | if (!*n) |
224 | n = "HEAD"; | |
9938af6a | 225 | if (!get_sha1(n, end)) { |
30b96fce JH |
226 | show_rev(NORMAL, end, n); |
227 | show_rev(REVERSED, sha1, arg); | |
178cb243 LT |
228 | continue; |
229 | } | |
230 | } | |
231 | *dotdot = '.'; | |
232 | } | |
9938af6a | 233 | if (!get_sha1(arg, sha1)) { |
30b96fce | 234 | show_rev(NORMAL, sha1, arg); |
800644c5 LT |
235 | continue; |
236 | } | |
9938af6a | 237 | if (*arg == '^' && !get_sha1(arg+1, sha1)) { |
30b96fce | 238 | show_rev(REVERSED, sha1, arg+1); |
800644c5 LT |
239 | continue; |
240 | } | |
4866ccf0 JH |
241 | if (verify) |
242 | die("Needed a single revision"); | |
243 | if ((filter & (DO_NONFLAGS|DO_NOREV)) == | |
244 | (DO_NONFLAGS|DO_NOREV)) | |
245 | show(arg); | |
023d66ed LT |
246 | } |
247 | show_default(); | |
4866ccf0 JH |
248 | if (verify && revs_count != 1) |
249 | die("Needed a single revision"); | |
178cb243 LT |
250 | return 0; |
251 | } |