blob: 71be2a9364748668996696f6c74057dba43315b5 [file] [log] [blame]
Linus Torvalds908e5312005-12-24 13:50:45 -08001#include "cache.h"
2#include "commit.h"
Junio C Hamano635d4132005-12-27 14:36:49 -08003#include "tag.h"
Linus Torvalds908e5312005-12-24 13:50:45 -08004#include "refs.h"
Shawn O. Pearce9a0eaf82007-01-10 06:36:36 -05005#include "builtin.h"
Shawn O. Pearce23615702007-05-21 03:20:25 -04006#include "exec_cmd.h"
Pierre Habouzit166185b2007-10-07 20:54:08 +02007#include "parse-options.h"
Jean Privat9f67d2e2009-10-21 09:35:22 -04008#include "diff.h"
Linus Torvalds908e5312005-12-24 13:50:45 -08009
Shawn O. Pearce8713ab32007-01-13 17:30:53 -050010#define SEEN (1u<<0)
11#define MAX_TAGS (FLAG_BITS - 1)
12
Pierre Habouzit166185b2007-10-07 20:54:08 +020013static const char * const describe_usage[] = {
Stephan Beyer1b1dd232008-07-13 15:36:15 +020014 "git describe [options] <committish>*",
Jean Privat9f67d2e2009-10-21 09:35:22 -040015 "git describe [options] --dirty",
Pierre Habouzit166185b2007-10-07 20:54:08 +020016 NULL
17};
Linus Torvalds908e5312005-12-24 13:50:45 -080018
Shawn O. Pearce8713ab32007-01-13 17:30:53 -050019static int debug; /* Display lots of verbose info */
Shawn O. Pearce7e425c42008-10-13 07:39:46 -070020static int all; /* Any valid ref can be used */
21static int tags; /* Allow lightweight tags */
Santi Béjar518120e2008-02-25 10:43:33 +010022static int longformat;
Junio C Hamano2d9e7c92005-12-27 14:40:17 -080023static int abbrev = DEFAULT_ABBREV;
Shawn O. Pearce8713ab32007-01-13 17:30:53 -050024static int max_candidates = 10;
Björn Steinbrinkd68dc342009-08-06 14:15:14 +020025static int found_names;
Nanako Shiraishicb2a1cc2008-07-16 19:42:14 +090026static const char *pattern;
Junio C Hamanoda2478d2008-03-02 08:51:57 -080027static int always;
Jean Privat9f67d2e2009-10-21 09:35:22 -040028static const char *dirty;
29
30/* diff-index command arguments to check if working tree is dirty. */
31static const char *diff_index_args[] = {
32 "diff-index", "--quiet", "HEAD", "--", NULL
33};
34
Linus Torvalds908e5312005-12-24 13:50:45 -080035
Shawn O. Pearcee7eb5032007-01-14 22:16:55 -050036struct commit_name {
Shawn O. Pearce212945d2008-02-28 01:22:36 -050037 struct tag *tag;
Junio C Hamano64deb852005-12-27 16:09:37 -080038 int prio; /* annotated tag = 2, tag = 1, head = 0 */
Shawn O. Pearce212945d2008-02-28 01:22:36 -050039 unsigned char sha1[20];
Junio C Hamano5a2282d2006-01-08 14:22:19 -080040 char path[FLEX_ARRAY]; /* more */
Shawn O. Pearcee7eb5032007-01-14 22:16:55 -050041};
Shawn O. Pearcecf69fd42007-01-14 04:37:44 -050042static const char *prio_names[] = {
43 "head", "lightweight", "annotated",
44};
Linus Torvalds908e5312005-12-24 13:50:45 -080045
Junio C Hamano64deb852005-12-27 16:09:37 -080046static void add_to_known_names(const char *path,
Shawn O. Pearce80dbae02007-01-10 06:39:47 -050047 struct commit *commit,
Shawn O. Pearce212945d2008-02-28 01:22:36 -050048 int prio,
49 const unsigned char *sha1)
Linus Torvalds908e5312005-12-24 13:50:45 -080050{
Shawn O. Pearcee7eb5032007-01-14 22:16:55 -050051 struct commit_name *e = commit->util;
52 if (!e || e->prio < prio) {
53 size_t len = strlen(path)+1;
54 free(e);
55 e = xmalloc(sizeof(struct commit_name) + len);
Shawn O. Pearce212945d2008-02-28 01:22:36 -050056 e->tag = NULL;
Shawn O. Pearcee7eb5032007-01-14 22:16:55 -050057 e->prio = prio;
Shawn O. Pearce212945d2008-02-28 01:22:36 -050058 hashcpy(e->sha1, sha1);
Shawn O. Pearcee7eb5032007-01-14 22:16:55 -050059 memcpy(e->path, path, len);
60 commit->util = e;
Linus Torvalds908e5312005-12-24 13:50:45 -080061 }
Björn Steinbrinkd68dc342009-08-06 14:15:14 +020062 found_names = 1;
Linus Torvalds908e5312005-12-24 13:50:45 -080063}
64
Junio C Hamano8da19772006-09-20 22:02:01 -070065static int get_name(const char *path, const unsigned char *sha1, int flag, void *cb_data)
Linus Torvalds908e5312005-12-24 13:50:45 -080066{
Shawn O. Pearce8a5a1882008-02-24 03:07:28 -050067 int might_be_tag = !prefixcmp(path, "refs/tags/");
Shawn O. Pearcefeededd2008-02-24 03:07:25 -050068 struct commit *commit;
Junio C Hamano64deb852005-12-27 16:09:37 -080069 struct object *object;
Shawn O. Pearcefeededd2008-02-24 03:07:25 -050070 unsigned char peeled[20];
71 int is_tag, prio;
Junio C Hamano64deb852005-12-27 16:09:37 -080072
Shawn O. Pearce8a5a1882008-02-24 03:07:28 -050073 if (!all && !might_be_tag)
74 return 0;
75
Shawn O. Pearcefeededd2008-02-24 03:07:25 -050076 if (!peel_ref(path, peeled) && !is_null_sha1(peeled)) {
77 commit = lookup_commit_reference_gently(peeled, 1);
78 if (!commit)
79 return 0;
80 is_tag = !!hashcmp(sha1, commit->object.sha1);
81 } else {
82 commit = lookup_commit_reference_gently(sha1, 1);
83 object = parse_object(sha1);
84 if (!commit || !object)
85 return 0;
86 is_tag = object->type == OBJ_TAG;
87 }
88
Junio C Hamano2d9e7c92005-12-27 14:40:17 -080089 /* If --all, then any refs are used.
90 * If --tags, then any tags are used.
91 * Otherwise only annotated tags are used.
92 */
Shawn O. Pearce8a5a1882008-02-24 03:07:28 -050093 if (might_be_tag) {
Michael Dressel4ed19a32008-06-04 21:06:31 +020094 if (is_tag)
Junio C Hamano64deb852005-12-27 16:09:37 -080095 prio = 2;
Michael Dressel4ed19a32008-06-04 21:06:31 +020096 else
Junio C Hamano64deb852005-12-27 16:09:37 -080097 prio = 1;
Michael Dressel4ed19a32008-06-04 21:06:31 +020098
99 if (pattern && fnmatch(pattern, path + 10, 0))
100 prio = 0;
Junio C Hamano635d4132005-12-27 14:36:49 -0800101 }
Junio C Hamano64deb852005-12-27 16:09:37 -0800102 else
103 prio = 0;
104
105 if (!all) {
106 if (!prio)
107 return 0;
Junio C Hamano64deb852005-12-27 16:09:37 -0800108 }
Shawn O. Pearce212945d2008-02-28 01:22:36 -0500109 add_to_known_names(all ? path + 5 : path + 10, commit, prio, sha1);
Linus Torvalds908e5312005-12-24 13:50:45 -0800110 return 0;
111}
112
Shawn O. Pearce80dbae02007-01-10 06:39:47 -0500113struct possible_tag {
Shawn O. Pearce80dbae02007-01-10 06:39:47 -0500114 struct commit_name *name;
Shawn O. Pearcecf69fd42007-01-14 04:37:44 -0500115 int depth;
116 int found_order;
Shawn O. Pearce8713ab32007-01-13 17:30:53 -0500117 unsigned flag_within;
Shawn O. Pearce80dbae02007-01-10 06:39:47 -0500118};
119
Shawn O. Pearcecf69fd42007-01-14 04:37:44 -0500120static int compare_pt(const void *a_, const void *b_)
121{
122 struct possible_tag *a = (struct possible_tag *)a_;
123 struct possible_tag *b = (struct possible_tag *)b_;
Shawn O. Pearcecf69fd42007-01-14 04:37:44 -0500124 if (a->depth != b->depth)
125 return a->depth - b->depth;
126 if (a->found_order != b->found_order)
127 return a->found_order - b->found_order;
128 return 0;
129}
130
Shawn O. Pearce1b600e62007-01-27 01:54:21 -0500131static unsigned long finish_depth_computation(
132 struct commit_list **list,
133 struct possible_tag *best)
134{
135 unsigned long seen_commits = 0;
136 while (*list) {
137 struct commit *c = pop_commit(list);
138 struct commit_list *parents = c->parents;
139 seen_commits++;
140 if (c->object.flags & best->flag_within) {
141 struct commit_list *a = *list;
142 while (a) {
143 struct commit *i = a->item;
144 if (!(i->object.flags & best->flag_within))
145 break;
146 a = a->next;
147 }
148 if (!a)
149 break;
150 } else
151 best->depth++;
152 while (parents) {
153 struct commit *p = parents->item;
154 parse_commit(p);
155 if (!(p->object.flags & SEEN))
156 insert_by_date(p, list);
157 p->object.flags |= c->object.flags;
158 parents = parents->next;
159 }
160 }
161 return seen_commits;
162}
163
Shawn O. Pearce212945d2008-02-28 01:22:36 -0500164static void display_name(struct commit_name *n)
165{
166 if (n->prio == 2 && !n->tag) {
167 n->tag = lookup_tag(n->sha1);
Junio C Hamano3167d722008-03-03 15:54:23 -0800168 if (!n->tag || parse_tag(n->tag) || !n->tag->tag)
Shawn O. Pearce212945d2008-02-28 01:22:36 -0500169 die("annotated tag %s not available", n->path);
Shawn O. Pearce81dc2232008-12-26 14:02:01 -0800170 if (strcmp(n->tag->tag, all ? n->path + 5 : n->path))
Shawn O. Pearce212945d2008-02-28 01:22:36 -0500171 warning("tag '%s' is really '%s' here", n->tag->tag, n->path);
172 }
173
174 if (n->tag)
175 printf("%s", n->tag->tag);
176 else
177 printf("%s", n->path);
Junio C Hamano870cf7d2008-03-03 13:08:26 -0800178}
179
180static void show_suffix(int depth, const unsigned char *sha1)
181{
182 printf("-%d-g%s", depth, find_unique_abbrev(sha1, abbrev));
Shawn O. Pearce212945d2008-02-28 01:22:36 -0500183}
184
Timo Hirvonen554fe202006-06-28 12:04:39 +0300185static void describe(const char *arg, int last_one)
Linus Torvalds908e5312005-12-24 13:50:45 -0800186{
Junio C Hamano4c34a2c2006-01-11 13:57:42 -0800187 unsigned char sha1[20];
Shawn O. Pearce8713ab32007-01-13 17:30:53 -0500188 struct commit *cmit, *gave_up_on = NULL;
Linus Torvalds908e5312005-12-24 13:50:45 -0800189 struct commit_list *list;
Linus Torvalds908e5312005-12-24 13:50:45 -0800190 struct commit_name *n;
Shawn O. Pearcecf69fd42007-01-14 04:37:44 -0500191 struct possible_tag all_matches[MAX_TAGS];
Shawn O. Pearce8713ab32007-01-13 17:30:53 -0500192 unsigned int match_cnt = 0, annotated_cnt = 0, cur_match;
193 unsigned long seen_commits = 0;
Thomas Rast4d236602009-10-28 23:10:06 +0100194 unsigned int unannotated_cnt = 0;
Linus Torvalds908e5312005-12-24 13:50:45 -0800195
Dmitry V. Levin31fff302006-05-09 01:43:38 +0400196 if (get_sha1(arg, sha1))
197 die("Not a valid object name %s", arg);
Junio C Hamano4c34a2c2006-01-11 13:57:42 -0800198 cmit = lookup_commit_reference(sha1);
199 if (!cmit)
Dmitry V. Levin31fff302006-05-09 01:43:38 +0400200 die("%s is not a valid '%s' object", arg, commit_type);
Junio C Hamano4c34a2c2006-01-11 13:57:42 -0800201
Shawn O. Pearcee7eb5032007-01-14 22:16:55 -0500202 n = cmit->util;
Thomas Rast7a0d61b2009-11-18 14:32:26 +0100203 if (n && (tags || all || n->prio == 2)) {
Junio C Hamano870cf7d2008-03-03 13:08:26 -0800204 /*
205 * Exact match to an existing ref.
206 */
Shawn O. Pearce212945d2008-02-28 01:22:36 -0500207 display_name(n);
Junio C Hamano870cf7d2008-03-03 13:08:26 -0800208 if (longformat)
Shawn O. Pearce14d46422008-07-03 02:32:45 +0000209 show_suffix(0, n->tag ? n->tag->tagged->sha1 : sha1);
Jean Privat9f67d2e2009-10-21 09:35:22 -0400210 if (dirty)
211 printf("%s", dirty);
Shawn O. Pearce212945d2008-02-28 01:22:36 -0500212 printf("\n");
Linus Torvalds908e5312005-12-24 13:50:45 -0800213 return;
214 }
215
Shawn O. Pearce2c33f752008-02-24 03:07:31 -0500216 if (!max_candidates)
217 die("no tag exactly matches '%s'", sha1_to_hex(cmit->object.sha1));
Shawn O. Pearce8713ab32007-01-13 17:30:53 -0500218 if (debug)
219 fprintf(stderr, "searching to describe %s\n", arg);
220
Linus Torvalds908e5312005-12-24 13:50:45 -0800221 list = NULL;
Shawn O. Pearce8713ab32007-01-13 17:30:53 -0500222 cmit->object.flags = SEEN;
Linus Torvalds908e5312005-12-24 13:50:45 -0800223 commit_list_insert(cmit, &list);
224 while (list) {
Shawn O. Pearce80dbae02007-01-10 06:39:47 -0500225 struct commit *c = pop_commit(&list);
Shawn O. Pearcedccd0c22007-01-13 17:27:52 -0500226 struct commit_list *parents = c->parents;
Shawn O. Pearce8713ab32007-01-13 17:30:53 -0500227 seen_commits++;
Shawn O. Pearcee7eb5032007-01-14 22:16:55 -0500228 n = c->util;
Linus Torvalds908e5312005-12-24 13:50:45 -0800229 if (n) {
Thomas Rast4d236602009-10-28 23:10:06 +0100230 if (!tags && !all && n->prio < 2) {
231 unannotated_cnt++;
232 } else if (match_cnt < max_candidates) {
Shawn O. Pearce8713ab32007-01-13 17:30:53 -0500233 struct possible_tag *t = &all_matches[match_cnt++];
234 t->name = n;
235 t->depth = seen_commits - 1;
236 t->flag_within = 1u << match_cnt;
Shawn O. Pearce8a8169c2007-01-25 12:40:03 -0500237 t->found_order = match_cnt;
Shawn O. Pearce8713ab32007-01-13 17:30:53 -0500238 c->object.flags |= t->flag_within;
239 if (n->prio == 2)
240 annotated_cnt++;
241 }
242 else {
243 gave_up_on = c;
244 break;
245 }
246 }
247 for (cur_match = 0; cur_match < match_cnt; cur_match++) {
248 struct possible_tag *t = &all_matches[cur_match];
249 if (!(c->object.flags & t->flag_within))
250 t->depth++;
251 }
252 if (annotated_cnt && !list) {
253 if (debug)
254 fprintf(stderr, "finished search at %s\n",
255 sha1_to_hex(c->object.sha1));
256 break;
Shawn O. Pearcedccd0c22007-01-13 17:27:52 -0500257 }
258 while (parents) {
259 struct commit *p = parents->item;
260 parse_commit(p);
Shawn O. Pearce8713ab32007-01-13 17:30:53 -0500261 if (!(p->object.flags & SEEN))
Shawn O. Pearcedccd0c22007-01-13 17:27:52 -0500262 insert_by_date(p, &list);
Shawn O. Pearce8713ab32007-01-13 17:30:53 -0500263 p->object.flags |= c->object.flags;
Shawn O. Pearcedccd0c22007-01-13 17:27:52 -0500264 parents = parents->next;
Linus Torvalds908e5312005-12-24 13:50:45 -0800265 }
266 }
Shawn O. Pearce80dbae02007-01-10 06:39:47 -0500267
Junio C Hamanoda2478d2008-03-02 08:51:57 -0800268 if (!match_cnt) {
269 const unsigned char *sha1 = cmit->object.sha1;
270 if (always) {
Jean Privat9f67d2e2009-10-21 09:35:22 -0400271 printf("%s", find_unique_abbrev(sha1, abbrev));
272 if (dirty)
273 printf("%s", dirty);
274 printf("\n");
Junio C Hamanoda2478d2008-03-02 08:51:57 -0800275 return;
276 }
Thomas Rast4d236602009-10-28 23:10:06 +0100277 if (unannotated_cnt)
278 die("No annotated tags can describe '%s'.\n"
279 "However, there were unannotated tags: try --tags.",
280 sha1_to_hex(sha1));
281 else
282 die("No tags can describe '%s'.\n"
283 "Try --always, or create some tags.",
284 sha1_to_hex(sha1));
Junio C Hamanoda2478d2008-03-02 08:51:57 -0800285 }
Shawn O. Pearce80dbae02007-01-10 06:39:47 -0500286
Shawn O. Pearcecf69fd42007-01-14 04:37:44 -0500287 qsort(all_matches, match_cnt, sizeof(all_matches[0]), compare_pt);
Shawn O. Pearce1b600e62007-01-27 01:54:21 -0500288
289 if (gave_up_on) {
290 insert_by_date(gave_up_on, &list);
291 seen_commits--;
292 }
293 seen_commits += finish_depth_computation(&list, &all_matches[0]);
294 free_commit_list(list);
295
Shawn O. Pearce8713ab32007-01-13 17:30:53 -0500296 if (debug) {
297 for (cur_match = 0; cur_match < match_cnt; cur_match++) {
298 struct possible_tag *t = &all_matches[cur_match];
Shawn O. Pearcecf69fd42007-01-14 04:37:44 -0500299 fprintf(stderr, " %-11s %8d %s\n",
300 prio_names[t->name->prio],
Shawn O. Pearce8713ab32007-01-13 17:30:53 -0500301 t->depth, t->name->path);
302 }
303 fprintf(stderr, "traversed %lu commits\n", seen_commits);
304 if (gave_up_on) {
305 fprintf(stderr,
306 "more than %i tags found; listed %i most recent\n"
307 "gave up search at %s\n",
308 max_candidates, max_candidates,
309 sha1_to_hex(gave_up_on->object.sha1));
310 }
Shawn O. Pearce80dbae02007-01-10 06:39:47 -0500311 }
Shawn O. Pearce212945d2008-02-28 01:22:36 -0500312
313 display_name(all_matches[0].name);
314 if (abbrev)
Junio C Hamano870cf7d2008-03-03 13:08:26 -0800315 show_suffix(all_matches[0].depth, cmit->object.sha1);
Jean Privat9f67d2e2009-10-21 09:35:22 -0400316 if (dirty)
317 printf("%s", dirty);
Shawn O. Pearce212945d2008-02-28 01:22:36 -0500318 printf("\n");
Shawn O. Pearce80dbae02007-01-10 06:39:47 -0500319
Shawn O. Pearce8713ab32007-01-13 17:30:53 -0500320 if (!last_one)
321 clear_commit_marks(cmit, -1);
Linus Torvalds908e5312005-12-24 13:50:45 -0800322}
323
Shawn O. Pearce9a0eaf82007-01-10 06:36:36 -0500324int cmd_describe(int argc, const char **argv, const char *prefix)
Linus Torvalds908e5312005-12-24 13:50:45 -0800325{
Shawn O. Pearce23615702007-05-21 03:20:25 -0400326 int contains = 0;
Pierre Habouzit166185b2007-10-07 20:54:08 +0200327 struct option options[] = {
328 OPT_BOOLEAN(0, "contains", &contains, "find the tag that comes after the commit"),
329 OPT_BOOLEAN(0, "debug", &debug, "debug search strategy on stderr"),
330 OPT_BOOLEAN(0, "all", &all, "use any ref in .git/refs"),
331 OPT_BOOLEAN(0, "tags", &tags, "use any tag in .git/refs/tags"),
Santi Béjar518120e2008-02-25 10:43:33 +0100332 OPT_BOOLEAN(0, "long", &longformat, "always use long format"),
Pierre Habouzit166185b2007-10-07 20:54:08 +0200333 OPT__ABBREV(&abbrev),
Shawn O. Pearce2c33f752008-02-24 03:07:31 -0500334 OPT_SET_INT(0, "exact-match", &max_candidates,
335 "only output exact matches", 0),
Pierre Habouzit166185b2007-10-07 20:54:08 +0200336 OPT_INTEGER(0, "candidates", &max_candidates,
Pierre Habouzit30ffa602007-12-21 22:49:54 +0100337 "consider <n> most recent tags (default: 10)"),
338 OPT_STRING(0, "match", &pattern, "pattern",
339 "only consider tags matching <pattern>"),
Junio C Hamanoda2478d2008-03-02 08:51:57 -0800340 OPT_BOOLEAN(0, "always", &always,
341 "show abbreviated commit object as fallback"),
Jean Privat9f67d2e2009-10-21 09:35:22 -0400342 {OPTION_STRING, 0, "dirty", &dirty, "mark",
343 "append <mark> on dirty working tree (default: \"-dirty\")",
344 PARSE_OPT_OPTARG, NULL, (intptr_t) "-dirty"},
Pierre Habouzit166185b2007-10-07 20:54:08 +0200345 OPT_END(),
346 };
Linus Torvalds908e5312005-12-24 13:50:45 -0800347
Stephen Boyd37782922009-05-23 11:53:12 -0700348 argc = parse_options(argc, argv, prefix, options, describe_usage, 0);
Shawn O. Pearce2c33f752008-02-24 03:07:31 -0500349 if (max_candidates < 0)
350 max_candidates = 0;
Pierre Habouzit166185b2007-10-07 20:54:08 +0200351 else if (max_candidates > MAX_TAGS)
352 max_candidates = MAX_TAGS;
Junio C Hamano4c34a2c2006-01-11 13:57:42 -0800353
Shawn O. Pearce8c599c72007-01-10 06:36:29 -0500354 save_commit_buffer = 0;
Dmitry V. Levin81128942006-09-14 05:03:59 +0400355
Santi Béjar518120e2008-02-25 10:43:33 +0100356 if (longformat && abbrev == 0)
357 die("--long is incompatible with --abbrev=0");
358
Shawn O. Pearce23615702007-05-21 03:20:25 -0400359 if (contains) {
Felipe Contreras4b25d092009-05-01 12:06:36 +0300360 const char **args = xmalloc((7 + argc) * sizeof(char *));
Nicolas Pitre3f7701a2007-12-19 12:53:16 -0500361 int i = 0;
362 args[i++] = "name-rev";
363 args[i++] = "--name-only";
Pierre Habouzita2cf9f42007-12-24 12:18:22 +0100364 args[i++] = "--no-undefined";
Junio C Hamanoda2478d2008-03-02 08:51:57 -0800365 if (always)
366 args[i++] = "--always";
Pierre Habouzit30ffa602007-12-21 22:49:54 +0100367 if (!all) {
Nicolas Pitre3f7701a2007-12-19 12:53:16 -0500368 args[i++] = "--tags";
Pierre Habouzit30ffa602007-12-21 22:49:54 +0100369 if (pattern) {
370 char *s = xmalloc(strlen("--refs=refs/tags/") + strlen(pattern) + 1);
371 sprintf(s, "--refs=refs/tags/%s", pattern);
372 args[i++] = s;
373 }
374 }
Felipe Contreras4b25d092009-05-01 12:06:36 +0300375 memcpy(args + i, argv, argc * sizeof(char *));
Nicolas Pitre3f7701a2007-12-19 12:53:16 -0500376 args[i + argc] = NULL;
377 return cmd_name_rev(i + argc, args, prefix);
Shawn O. Pearce23615702007-05-21 03:20:25 -0400378 }
379
René Scharfefb423da2009-10-17 18:30:48 +0200380 for_each_ref(get_name, NULL);
Junio C Hamano02d56fa2009-10-23 22:40:18 -0700381 if (!found_names && !always)
René Scharfefb423da2009-10-17 18:30:48 +0200382 die("No names found, cannot describe anything.");
383
Pierre Habouzit166185b2007-10-07 20:54:08 +0200384 if (argc == 0) {
Jean Privat9f67d2e2009-10-21 09:35:22 -0400385 if (dirty && !cmd_diff_index(ARRAY_SIZE(diff_index_args) - 1, diff_index_args, prefix))
386 dirty = NULL;
Junio C Hamanofec9ebf2006-01-15 22:25:35 -0800387 describe("HEAD", 1);
Jean Privat9f67d2e2009-10-21 09:35:22 -0400388 } else if (dirty) {
389 die("--dirty is incompatible with committishes");
Pierre Habouzit166185b2007-10-07 20:54:08 +0200390 } else {
391 while (argc-- > 0) {
392 describe(*argv++, argc == 0);
Junio C Hamanofec9ebf2006-01-15 22:25:35 -0800393 }
Pierre Habouzit166185b2007-10-07 20:54:08 +0200394 }
Linus Torvalds908e5312005-12-24 13:50:45 -0800395 return 0;
396}