source src/describe.c
| Line | Flow | Count | Block(s) | Source |
|---|---|---|---|---|
| 1 | - | /* | ||
| 2 | - | * Copyright (C) the libgit2 contributors. All rights reserved. | ||
| 3 | - | * | ||
| 4 | - | * This file is part of libgit2, distributed under the GNU GPL v2 with | ||
| 5 | - | * a Linking Exception. For full terms see the included COPYING file. | ||
| 6 | - | */ | ||
| 7 | - | |||
| 8 | - | #include "common.h" | ||
| 9 | - | |||
| 10 | - | #include "git2/describe.h" | ||
| 11 | - | #include "git2/strarray.h" | ||
| 12 | - | #include "git2/diff.h" | ||
| 13 | - | #include "git2/status.h" | ||
| 14 | - | |||
| 15 | - | #include "commit.h" | ||
| 16 | - | #include "commit_list.h" | ||
| 17 | - | #include "oidmap.h" | ||
| 18 | - | #include "refs.h" | ||
| 19 | - | #include "repository.h" | ||
| 20 | - | #include "revwalk.h" | ||
| 21 | - | #include "tag.h" | ||
| 22 | - | #include "vector.h" | ||
| 23 | - | #include "wildmatch.h" | ||
| 24 | - | |||
| 25 | - | /* Ported from https://github.com/git/git/blob/89dde7882f71f846ccd0359756d27bebc31108de/builtin/describe.c */ | ||
| 26 | - | |||
| 27 | - | struct commit_name { | ||
| 28 | - | git_tag *tag; | ||
| 29 | - | unsigned prio:2; /* annotated tag = 2, tag = 1, head = 0 */ | ||
| 30 | - | unsigned name_checked:1; | ||
| 31 | - | git_oid sha1; | ||
| 32 | - | char *path; | ||
| 33 | - | |||
| 34 | - | /* Khash workaround. They original key has to still be reachable */ | ||
| 35 | - | git_oid peeled; | ||
| 36 | - | }; | ||
| 37 | - | |||
| 38 | 356 | 2 | static void *oidmap_value_bykey(git_oidmap *map, const git_oid *key) | |
| 39 | - | { | ||
| 40 | 356 | 2 | return git_oidmap_get(map, key); | |
| 41 | - | } | ||
| 42 | - | |||
| 43 | 356 | 2 | static struct commit_name *find_commit_name( | |
| 44 | - | git_oidmap *names, | ||
| 45 | - | const git_oid *peeled) | ||
| 46 | - | { | ||
| 47 | 356 | 2 | return (struct commit_name *)(oidmap_value_bykey(names, peeled)); | |
| 48 | - | } | ||
| 49 | - | |||
| 50 | ![]() |
153 | 2 | static int replace_name( |
| 51 | - | git_tag **tag, | ||
| 52 | - | git_repository *repo, | ||
| 53 | - | struct commit_name *e, | ||
| 54 | - | unsigned int prio, | ||
| 55 | - | const git_oid *sha1) | ||
| 56 | - | { | ||
| 57 | 153 | 2 | git_time_t e_time = 0, t_time = 0; | |
| 58 | - | |||
| 59 | 153 | 2,3 | if (!e || e->prio < prio) | |
| 60 | 123 | 4 | return 1; | |
| 61 | - | |||
| 62 | 30 | 5,6 | if (e->prio == 2 && prio == 2) { | |
| 63 | - | /* Multiple annotated tags point to the same commit. | ||
| 64 | - | * Select one to keep based upon their tagger date. | ||
| 65 | - | */ | ||
| 66 | 28 | 7 | git_tag *t = NULL; | |
| 67 | - | |||
| 68 | 28 | 7 | if (!e->tag) { | |
| 69 | 26 | 8,9 | if (git_tag_lookup(&t, repo, &e->sha1) < 0) | |
| 70 | 24 | 10,22 | return 1; | |
| 71 | 26 | 11 | e->tag = t; | |
| 72 | - | } | ||
| 73 | - | |||
| 74 | 28 | 12,13 | if (git_tag_lookup(&t, repo, sha1) < 0) | |
| 75 | ##### | 14 | return 0; | |
| 76 | - | |||
| 77 | 28 | 15 | *tag = t; | |
| 78 | - | |||
| 79 | 28 | 15 | if (e->tag->tagger) | |
| 80 | 28 | 16 | e_time = e->tag->tagger->when.time; | |
| 81 | - | |||
| 82 | 28 | 17 | if (t->tagger) | |
| 83 | 26 | 18 | t_time = t->tagger->when.time; | |
| 84 | - | |||
| 85 | 28 | 19 | if (e_time < t_time) | |
| 86 | 24 | 20,21 | return 1; | |
| 87 | - | } | ||
| 88 | - | |||
| 89 | 6 | 23 | return 0; | |
| 90 | - | } | ||
| 91 | - | |||
| 92 | ![]() |
153 | 2 | static int add_to_known_names( |
| 93 | - | git_repository *repo, | ||
| 94 | - | git_oidmap *names, | ||
| 95 | - | const char *path, | ||
| 96 | - | const git_oid *peeled, | ||
| 97 | - | unsigned int prio, | ||
| 98 | - | const git_oid *sha1) | ||
| 99 | - | { | ||
| 100 | 153 | 2 | struct commit_name *e = find_commit_name(names, peeled); | |
| 101 | 153 | 3 | bool found = (e != NULL); | |
| 102 | - | |||
| 103 | 153 | 3 | git_tag *tag = NULL; | |
| 104 | 153 | 3,4 | if (replace_name(&tag, repo, e, prio, sha1)) { | |
| 105 | 147 | 5 | if (!found) { | |
| 106 | 123 | 6 | e = git__malloc(sizeof(struct commit_name)); | |
| 107 | 123 | 7,8 | GIT_ERROR_CHECK_ALLOC(e); | |
| 108 | - | |||
| 109 | 123 | 9 | e->path = NULL; | |
| 110 | 123 | 9 | e->tag = NULL; | |
| 111 | - | } | ||
| 112 | - | |||
| 113 | 147 | 10 | if (e->tag) | |
| 114 | 24 | 11 | git_tag_free(e->tag); | |
| 115 | 147 | 12 | e->tag = tag; | |
| 116 | 147 | 12 | e->prio = prio; | |
| 117 | 147 | 12 | e->name_checked = 0; | |
| 118 | 147 | 12 | git_oid_cpy(&e->sha1, sha1); | |
| 119 | 147 | 13 | git__free(e->path); | |
| 120 | 147 | 14 | e->path = git__strdup(path); | |
| 121 | 147 | 15 | git_oid_cpy(&e->peeled, peeled); | |
| 122 | - | |||
| 123 | 147 | 16-18 | if (!found && git_oidmap_set(names, &e->peeled, e) < 0) | |
| 124 | ##### | 19 | return -1; | |
| 125 | - | } | ||
| 126 | - | else | ||
| 127 | 6 | 20 | git_tag_free(tag); | |
| 128 | - | |||
| 129 | 153 | 21 | return 0; | |
| 130 | - | } | ||
| 131 | - | |||
| 132 | 153 | 2 | static int retrieve_peeled_tag_or_object_oid( | |
| 133 | - | git_oid *peeled_out, | ||
| 134 | - | git_oid *ref_target_out, | ||
| 135 | - | git_repository *repo, | ||
| 136 | - | const char *refname) | ||
| 137 | - | { | ||
| 138 | - | git_reference *ref; | ||
| 139 | 153 | 2 | git_object *peeled = NULL; | |
| 140 | - | int error; | ||
| 141 | - | |||
| 142 | 153 | 2,3 | if ((error = git_reference_lookup_resolved(&ref, repo, refname, -1)) < 0) | |
| 143 | ##### | 4 | return error; | |
| 144 | - | |||
| 145 | 153 | 5,6 | if ((error = git_reference_peel(&peeled, ref, GIT_OBJECT_ANY)) < 0) | |
| 146 | ##### | 7 | goto cleanup; | |
| 147 | - | |||
| 148 | 153 | 8,9 | git_oid_cpy(ref_target_out, git_reference_target(ref)); | |
| 149 | 153 | 10,11 | git_oid_cpy(peeled_out, git_object_id(peeled)); | |
| 150 | - | |||
| 151 | 153 | 12,13 | if (git_oid_cmp(ref_target_out, peeled_out) != 0) | |
| 152 | 101 | 14 | error = 1; /* The reference was pointing to a annotated tag */ | |
| 153 | - | else | ||
| 154 | 52 | 15 | error = 0; /* Any other object */ | |
| 155 | - | |||
| 156 | - | cleanup: | ||
| 157 | 153 | 16 | git_reference_free(ref); | |
| 158 | 153 | 17 | git_object_free(peeled); | |
| 159 | 153 | 18 | return error; | |
| 160 | - | } | ||
| 161 | - | |||
| 162 | - | struct git_describe_result { | ||
| 163 | - | int dirty; | ||
| 164 | - | int exact_match; | ||
| 165 | - | int fallback_to_id; | ||
| 166 | - | git_oid commit_id; | ||
| 167 | - | git_repository *repo; | ||
| 168 | - | struct commit_name *name; | ||
| 169 | - | struct possible_tag *tag; | ||
| 170 | - | }; | ||
| 171 | - | |||
| 172 | - | struct get_name_data | ||
| 173 | - | { | ||
| 174 | - | git_describe_options *opts; | ||
| 175 | - | git_repository *repo; | ||
| 176 | - | git_oidmap *names; | ||
| 177 | - | git_describe_result *result; | ||
| 178 | - | }; | ||
| 179 | - | |||
| 180 | ![]() |
27 | 2 | static int commit_name_dup(struct commit_name **out, struct commit_name *in) |
| 181 | - | { | ||
| 182 | - | struct commit_name *name; | ||
| 183 | - | |||
| 184 | 27 | 2 | name = git__malloc(sizeof(struct commit_name)); | |
| 185 | 27 | 3,4 | GIT_ERROR_CHECK_ALLOC(name); | |
| 186 | - | |||
| 187 | 27 | 5 | memcpy(name, in, sizeof(struct commit_name)); | |
| 188 | 27 | 5 | name->tag = NULL; | |
| 189 | 27 | 5 | name->path = NULL; | |
| 190 | - | |||
| 191 | 27 | 5-7 | if (in->tag && git_tag_dup(&name->tag, in->tag) < 0) | |
| 192 | ##### | 8 | return -1; | |
| 193 | - | |||
| 194 | 27 | 9 | name->path = git__strdup(in->path); | |
| 195 | 27 | 10,11 | GIT_ERROR_CHECK_ALLOC(name->path); | |
| 196 | - | |||
| 197 | 27 | 12 | *out = name; | |
| 198 | 27 | 12 | return 0; | |
| 199 | - | } | ||
| 200 | - | |||
| 201 | ![]() |
238 | 2 | static int get_name(const char *refname, void *payload) |
| 202 | - | { | ||
| 203 | - | struct get_name_data *data; | ||
| 204 | - | bool is_tag, is_annotated, all; | ||
| 205 | - | git_oid peeled, sha1; | ||
| 206 | - | unsigned int prio; | ||
| 207 | 238 | 2 | int error = 0; | |
| 208 | - | |||
| 209 | 238 | 2 | data = (struct get_name_data *)payload; | |
| 210 | 238 | 2 | is_tag = !git__prefixcmp(refname, GIT_REFS_TAGS_DIR); | |
| 211 | 238 | 3 | all = data->opts->describe_strategy == GIT_DESCRIBE_ALL; | |
| 212 | - | |||
| 213 | - | /* Reject anything outside refs/tags/ unless --all */ | ||
| 214 | 238 | 3,4 | if (!all && !is_tag) | |
| 215 | 53 | 5 | return 0; | |
| 216 | - | |||
| 217 | - | /* Accept only tags that match the pattern, if given */ | ||
| 218 | 185 | 6-9 | if (data->opts->pattern && (!is_tag || wildmatch(data->opts->pattern, | |
| 219 | - | refname + strlen(GIT_REFS_TAGS_DIR), 0))) | ||
| 220 | 32 | 10 | return 0; | |
| 221 | - | |||
| 222 | - | /* Is it annotated? */ | ||
| 223 | 153 | 11,12 | if ((error = retrieve_peeled_tag_or_object_oid( | |
| 224 | - | &peeled, &sha1, data->repo, refname)) < 0) | ||
| 225 | ##### | 13 | return error; | |
| 226 | - | |||
| 227 | 153 | 14 | is_annotated = error; | |
| 228 | - | |||
| 229 | - | /* | ||
| 230 | - | * By default, we only use annotated tags, but with --tags | ||
| 231 | - | * we fall back to lightweight ones (even without --tags, | ||
| 232 | - | * we still remember lightweight ones, only to give hints | ||
| 233 | - | * in an error message). --all allows any refs to be used. | ||
| 234 | - | */ | ||
| 235 | 153 | 14 | if (is_annotated) | |
| 236 | 101 | 15 | prio = 2; | |
| 237 | 52 | 16 | else if (is_tag) | |
| 238 | 49 | 17 | prio = 1; | |
| 239 | - | else | ||
| 240 | 3 | 18 | prio = 0; | |
| 241 | - | |||
| 242 | 153 | 19-22 | add_to_known_names(data->repo, data->names, | |
| 243 | - | all ? refname + strlen(GIT_REFS_DIR) : refname + strlen(GIT_REFS_TAGS_DIR), | ||
| 244 | - | &peeled, prio, &sha1); | ||
| 245 | 153 | 23 | return 0; | |
| 246 | - | } | ||
| 247 | - | |||
| 248 | - | struct possible_tag { | ||
| 249 | - | struct commit_name *name; | ||
| 250 | - | int depth; | ||
| 251 | - | int found_order; | ||
| 252 | - | unsigned flag_within; | ||
| 253 | - | }; | ||
| 254 | - | |||
| 255 | 19 | 2 | static int possible_tag_dup(struct possible_tag **out, struct possible_tag *in) | |
| 256 | - | { | ||
| 257 | - | struct possible_tag *tag; | ||
| 258 | - | int error; | ||
| 259 | - | |||
| 260 | 19 | 2 | tag = git__malloc(sizeof(struct possible_tag)); | |
| 261 | 19 | 3,4 | GIT_ERROR_CHECK_ALLOC(tag); | |
| 262 | - | |||
| 263 | 19 | 5 | memcpy(tag, in, sizeof(struct possible_tag)); | |
| 264 | 19 | 5 | tag->name = NULL; | |
| 265 | - | |||
| 266 | 19 | 5,6 | if ((error = commit_name_dup(&tag->name, in->name)) < 0) { | |
| 267 | ##### | 7 | git__free(tag); | |
| 268 | ##### | 8 | *out = NULL; | |
| 269 | ##### | 8 | return error; | |
| 270 | - | } | ||
| 271 | - | |||
| 272 | 19 | 9 | *out = tag; | |
| 273 | 19 | 9 | return 0; | |
| 274 | - | } | ||
| 275 | - | |||
| 276 | 43 | 2 | static int compare_pt(const void *a_, const void *b_) | |
| 277 | - | { | ||
| 278 | 43 | 2 | struct possible_tag *a = (struct possible_tag *)a_; | |
| 279 | 43 | 2 | struct possible_tag *b = (struct possible_tag *)b_; | |
| 280 | 43 | 2 | if (a->depth != b->depth) | |
| 281 | 30 | 3 | return a->depth - b->depth; | |
| 282 | 13 | 4 | if (a->found_order != b->found_order) | |
| 283 | 13 | 5 | return a->found_order - b->found_order; | |
| 284 | ##### | 6 | return 0; | |
| 285 | - | } | ||
| 286 | - | |||
| 287 | - | #define SEEN (1u << 0) | ||
| 288 | - | |||
| 289 | ![]() |
19 | 2 | static unsigned long finish_depth_computation( |
| 290 | - | git_pqueue *list, | ||
| 291 | - | git_revwalk *walk, | ||
| 292 | - | struct possible_tag *best) | ||
| 293 | - | { | ||
| 294 | 19 | 2 | unsigned long seen_commits = 0; | |
| 295 | - | int error, i; | ||
| 296 | - | |||
| 297 | 19 | 2,27,28 | while (git_pqueue_size(list) > 0) { | |
| 298 | ##### | 3 | git_commit_list_node *c = git_pqueue_pop(list); | |
| 299 | ##### | 4 | seen_commits++; | |
| 300 | ##### | 4 | if (c->flags & best->flag_within) { | |
| 301 | ##### | 5 | size_t index = 0; | |
| 302 | ##### | 5,10,11 | while (git_pqueue_size(list) > index) { | |
| 303 | ##### | 6 | git_commit_list_node *i = git_pqueue_get(list, index); | |
| 304 | ##### | 7 | if (!(i->flags & best->flag_within)) | |
| 305 | ##### | 8 | break; | |
| 306 | ##### | 9 | index++; | |
| 307 | - | } | ||
| 308 | ##### | 12,13 | if (index > git_pqueue_size(list)) | |
| 309 | ##### | 14,15 | break; | |
| 310 | - | } else | ||
| 311 | ##### | 16 | best->depth++; | |
| 312 | ##### | 17,25,26 | for (i = 0; i < c->out_degree; i++) { | |
| 313 | ##### | 18 | git_commit_list_node *p = c->parents[i]; | |
| 314 | ##### | 18,19 | if ((error = git_commit_list_parse(walk, p)) < 0) | |
| 315 | ##### | 20 | return error; | |
| 316 | ##### | 21 | if (!(p->flags & SEEN)) | |
| 317 | ##### | 22,23 | if ((error = git_pqueue_insert(list, p)) < 0) | |
| 318 | ##### | 24 | return error; | |
| 319 | ##### | 25 | p->flags |= c->flags; | |
| 320 | - | } | ||
| 321 | - | } | ||
| 322 | 19 | 29 | return seen_commits; | |
| 323 | - | } | ||
| 324 | - | |||
| 325 | ![]() |
27 | 2 | static int display_name(git_buf *buf, git_repository *repo, struct commit_name *n) |
| 326 | - | { | ||
| 327 | 27 | 2,3 | if (n->prio == 2 && !n->tag) { | |
| 328 | 11 | 4,5 | if (git_tag_lookup(&n->tag, repo, &n->sha1) < 0) { | |
| 329 | ##### | 6 | git_error_set(GIT_ERROR_TAG, "annotated tag '%s' not available", n->path); | |
| 330 | ##### | 7 | return -1; | |
| 331 | - | } | ||
| 332 | - | } | ||
| 333 | - | |||
| 334 | 27 | 8,9 | if (n->tag && !n->name_checked) { | |
| 335 | 14 | 10,11 | if (!git_tag_name(n->tag)) { | |
| 336 | ##### | 12 | git_error_set(GIT_ERROR_TAG, "annotated tag '%s' has no embedded name", n->path); | |
| 337 | ##### | 13 | return -1; | |
| 338 | - | } | ||
| 339 | - | |||
| 340 | - | /* TODO: Cope with warnings | ||
| 341 | - | if (strcmp(n->tag->tag, all ? n->path + 5 : n->path)) | ||
| 342 | - | warning(_("tag '%s' is really '%s' here"), n->tag->tag, n->path); | ||
| 343 | - | */ | ||
| 344 | - | |||
| 345 | 14 | 14 | n->name_checked = 1; | |
| 346 | - | } | ||
| 347 | - | |||
| 348 | 27 | 15 | if (n->tag) | |
| 349 | 14 | 16,17 | git_buf_printf(buf, "%s", git_tag_name(n->tag)); | |
| 350 | - | else | ||
| 351 | 13 | 18 | git_buf_printf(buf, "%s", n->path); | |
| 352 | - | |||
| 353 | 27 | 19 | return 0; | |
| 354 | - | } | ||
| 355 | - | |||
| 356 | ![]() |
22 | 2 | static int find_unique_abbrev_size( |
| 357 | - | int *out, | ||
| 358 | - | git_repository *repo, | ||
| 359 | - | const git_oid *oid_in, | ||
| 360 | - | unsigned int abbreviated_size) | ||
| 361 | - | { | ||
| 362 | 22 | 2 | size_t size = abbreviated_size; | |
| 363 | - | git_odb *odb; | ||
| 364 | - | git_oid dummy; | ||
| 365 | - | int error; | ||
| 366 | - | |||
| 367 | 22 | 2,3 | if ((error = git_repository_odb__weakptr(&odb, repo)) < 0) | |
| 368 | ##### | 4 | return error; | |
| 369 | - | |||
| 370 | 22 | 5,12 | while (size < GIT_OID_HEXSZ) { | |
| 371 | 22 | 6,7 | if ((error = git_odb_exists_prefix(&dummy, odb, oid_in, size)) == 0) { | |
| 372 | 22 | 8 | *out = (int) size; | |
| 373 | 22 | 8 | return 0; | |
| 374 | - | } | ||
| 375 | - | |||
| 376 | - | /* If the error wasn't that it's not unique, then it's a proper error */ | ||
| 377 | ##### | 9 | if (error != GIT_EAMBIGUOUS) | |
| 378 | ##### | 10 | return error; | |
| 379 | - | |||
| 380 | - | /* Try again with a larger size */ | ||
| 381 | ##### | 11 | size++; | |
| 382 | - | } | ||
| 383 | - | |||
| 384 | - | /* If we didn't find any shorter prefix, we have to do the whole thing */ | ||
| 385 | ##### | 13 | *out = GIT_OID_HEXSZ; | |
| 386 | - | |||
| 387 | ##### | 13 | return 0; | |
| 388 | - | } | ||
| 389 | - | |||
| 390 | 21 | 2 | static int show_suffix( | |
| 391 | - | git_buf *buf, | ||
| 392 | - | int depth, | ||
| 393 | - | git_repository *repo, | ||
| 394 | - | const git_oid* id, | ||
| 395 | - | unsigned int abbrev_size) | ||
| 396 | - | { | ||
| 397 | 21 | 2 | int error, size = 0; | |
| 398 | - | |||
| 399 | - | char hex_oid[GIT_OID_HEXSZ]; | ||
| 400 | - | |||
| 401 | 21 | 2,3 | if ((error = find_unique_abbrev_size(&size, repo, id, abbrev_size)) < 0) | |
| 402 | ##### | 4 | return error; | |
| 403 | - | |||
| 404 | 21 | 5 | git_oid_fmt(hex_oid, id); | |
| 405 | - | |||
| 406 | 21 | 6 | git_buf_printf(buf, "-%d-g", depth); | |
| 407 | - | |||
| 408 | 21 | 7 | git_buf_put(buf, hex_oid, size); | |
| 409 | - | |||
| 410 | 21 | 8 | return git_buf_oom(buf) ? -1 : 0; | |
| 411 | - | } | ||
| 412 | - | |||
| 413 | - | #define MAX_CANDIDATES_TAGS FLAG_BITS - 1 | ||
| 414 | - | |||
| 415 | ##### | 2 | static int describe_not_found(const git_oid *oid, const char *message_format) { | |
| 416 | - | char oid_str[GIT_OID_HEXSZ + 1]; | ||
| 417 | ##### | 2 | git_oid_tostr(oid_str, sizeof(oid_str), oid); | |
| 418 | - | |||
| 419 | ##### | 3 | git_error_set(GIT_ERROR_DESCRIBE, message_format, oid_str); | |
| 420 | ##### | 4 | return GIT_ENOTFOUND; | |
| 421 | - | } | ||
| 422 | - | |||
| 423 | ![]() |
29 | 2 | static int describe( |
| 424 | - | struct get_name_data *data, | ||
| 425 | - | git_commit *commit) | ||
| 426 | - | { | ||
| 427 | - | struct commit_name *n; | ||
| 428 | - | struct possible_tag *best; | ||
| 429 | - | bool all, tags; | ||
| 430 | 29 | 2 | git_revwalk *walk = NULL; | |
| 431 | - | git_pqueue list; | ||
| 432 | 29 | 2 | git_commit_list_node *cmit, *gave_up_on = NULL; | |
| 433 | 29 | 2 | git_vector all_matches = GIT_VECTOR_INIT; | |
| 434 | 29 | 2 | unsigned int match_cnt = 0, annotated_cnt = 0, cur_match; | |
| 435 | 29 | 2 | unsigned long seen_commits = 0; /* TODO: Check long */ | |
| 436 | 29 | 2 | unsigned int unannotated_cnt = 0; | |
| 437 | - | int error; | ||
| 438 | - | |||
| 439 | 29 | 2,3 | if (git_vector_init(&all_matches, MAX_CANDIDATES_TAGS, compare_pt) < 0) | |
| 440 | ##### | 4 | return -1; | |
| 441 | - | |||
| 442 | 29 | 5,6 | if ((error = git_pqueue_init(&list, 0, 2, git_commit_list_time_cmp)) < 0) | |
| 443 | ##### | 7 | goto cleanup; | |
| 444 | - | |||
| 445 | 29 | 8 | all = data->opts->describe_strategy == GIT_DESCRIBE_ALL; | |
| 446 | 29 | 8 | tags = data->opts->describe_strategy == GIT_DESCRIBE_TAGS; | |
| 447 | - | |||
| 448 | 29 | 8,9 | git_oid_cpy(&data->result->commit_id, git_commit_id(commit)); | |
| 449 | - | |||
| 450 | 29 | 10,11 | n = find_commit_name(data->names, git_commit_id(commit)); | |
| 451 | 29 | 12-15 | if (n && (tags || all || n->prio == 2)) { | |
| 452 | - | /* | ||
| 453 | - | * Exact match to an existing ref. | ||
| 454 | - | */ | ||
| 455 | 8 | 16 | data->result->exact_match = 1; | |
| 456 | 8 | 16,17 | if ((error = commit_name_dup(&data->result->name, n)) < 0) | |
| 457 | ##### | 18 | goto cleanup; | |
| 458 | - | |||
| 459 | 8 | 19 | goto cleanup; | |
| 460 | - | } | ||
| 461 | - | |||
| 462 | 21 | 20 | if (!data->opts->max_candidates_tags) { | |
| 463 | ##### | 21,22 | error = describe_not_found( | |
| 464 | - | git_commit_id(commit), | ||
| 465 | - | "cannot describe - no tag exactly matches '%s'"); | ||
| 466 | - | |||
| 467 | ##### | 23 | goto cleanup; | |
| 468 | - | } | ||
| 469 | - | |||
| 470 | 21 | 24-26 | if ((error = git_revwalk_new(&walk, git_commit_owner(commit))) < 0) | |
| 471 | ##### | 27 | goto cleanup; | |
| 472 | - | |||
| 473 | 21 | 28-30 | if ((cmit = git_revwalk__commit_lookup(walk, git_commit_id(commit))) == NULL) | |
| 474 | ##### | 31 | goto cleanup; | |
| 475 | - | |||
| 476 | 21 | 32,33 | if ((error = git_commit_list_parse(walk, cmit)) < 0) | |
| 477 | ##### | 34 | goto cleanup; | |
| 478 | - | |||
| 479 | 21 | 35 | cmit->flags = SEEN; | |
| 480 | - | |||
| 481 | 21 | 35,36 | if ((error = git_pqueue_insert(&list, cmit)) < 0) | |
| 482 | ##### | 37 | goto cleanup; | |
| 483 | - | |||
| 484 | 178 | 38,79,80 | while (git_pqueue_size(&list) > 0) | |
| 485 | - | { | ||
| 486 | - | int i; | ||
| 487 | - | |||
| 488 | 174 | 39 | git_commit_list_node *c = (git_commit_list_node *)git_pqueue_pop(&list); | |
| 489 | 174 | 40 | seen_commits++; | |
| 490 | - | |||
| 491 | 174 | 40 | n = find_commit_name(data->names, &c->oid); | |
| 492 | - | |||
| 493 | 174 | 41 | if (n) { | |
| 494 | 65 | 42-44 | if (!tags && !all && n->prio < 2) { | |
| 495 | 14 | 45 | unannotated_cnt++; | |
| 496 | 51 | 46 | } else if (match_cnt < data->opts->max_candidates_tags) { | |
| 497 | 51 | 47 | struct possible_tag *t = git__malloc(sizeof(struct commit_name)); | |
| 498 | 51 | 48,49 | GIT_ERROR_CHECK_ALLOC(t); | |
| 499 | 51 | 50,51 | if ((error = git_vector_insert(&all_matches, t)) < 0) | |
| 500 | ##### | 52 | goto cleanup; | |
| 501 | - | |||
| 502 | 51 | 53 | match_cnt++; | |
| 503 | - | |||
| 504 | 51 | 53 | t->name = n; | |
| 505 | 51 | 53 | t->depth = seen_commits - 1; | |
| 506 | 51 | 53 | t->flag_within = 1u << match_cnt; | |
| 507 | 51 | 53 | t->found_order = match_cnt; | |
| 508 | 51 | 53 | c->flags |= t->flag_within; | |
| 509 | 51 | 53 | if (n->prio == 2) | |
| 510 | 51 | 54,55 | annotated_cnt++; | |
| 511 | - | } | ||
| 512 | - | else { | ||
| 513 | ##### | 56 | gave_up_on = c; | |
| 514 | ##### | 56 | break; | |
| 515 | - | } | ||
| 516 | - | } | ||
| 517 | - | |||
| 518 | 421 | 57,61,62 | for (cur_match = 0; cur_match < match_cnt; cur_match++) { | |
| 519 | 247 | 58 | struct possible_tag *t = git_vector_get(&all_matches, cur_match); | |
| 520 | 247 | 59 | if (!(c->flags & t->flag_within)) | |
| 521 | 129 | 60 | t->depth++; | |
| 522 | - | } | ||
| 523 | - | |||
| 524 | 174 | 63-65 | if (annotated_cnt && (git_pqueue_size(&list) == 0)) { | |
| 525 | - | /* | ||
| 526 | - | if (debug) { | ||
| 527 | - | char oid_str[GIT_OID_HEXSZ + 1]; | ||
| 528 | - | git_oid_tostr(oid_str, sizeof(oid_str), &c->oid); | ||
| 529 | - | |||
| 530 | - | fprintf(stderr, "finished search at %s\n", oid_str); | ||
| 531 | - | } | ||
| 532 | - | */ | ||
| 533 | 17 | 66 | break; | |
| 534 | - | } | ||
| 535 | 333 | 67,77,78 | for (i = 0; i < c->out_degree; i++) { | |
| 536 | 180 | 68 | git_commit_list_node *p = c->parents[i]; | |
| 537 | 180 | 68,69 | if ((error = git_commit_list_parse(walk, p)) < 0) | |
| 538 | ##### | 70 | goto cleanup; | |
| 539 | 180 | 71 | if (!(p->flags & SEEN)) | |
| 540 | 153 | 72,73 | if ((error = git_pqueue_insert(&list, p)) < 0) | |
| 541 | ##### | 74 | goto cleanup; | |
| 542 | 180 | 75 | p->flags |= c->flags; | |
| 543 | - | |||
| 544 | 180 | 75 | if (data->opts->only_follow_first_parent) | |
| 545 | 4 | 76 | break; | |
| 546 | - | } | ||
| 547 | - | } | ||
| 548 | - | |||
| 549 | 21 | 81 | if (!match_cnt) { | |
| 550 | 2 | 82 | if (data->opts->show_commit_oid_as_fallback) { | |
| 551 | 2 | 83 | data->result->fallback_to_id = 1; | |
| 552 | 2 | 83 | git_oid_cpy(&data->result->commit_id, &cmit->oid); | |
| 553 | - | |||
| 554 | 2 | 84 | goto cleanup; | |
| 555 | - | } | ||
| 556 | ##### | 85 | if (unannotated_cnt) { | |
| 557 | ##### | 86,87 | error = describe_not_found(git_commit_id(commit), | |
| 558 | - | "cannot describe - " | ||
| 559 | - | "no annotated tags can describe '%s'; " | ||
| 560 | - | "however, there were unannotated tags."); | ||
| 561 | ##### | 88 | goto cleanup; | |
| 562 | - | } | ||
| 563 | - | else { | ||
| 564 | ##### | 89,90 | error = describe_not_found(git_commit_id(commit), | |
| 565 | - | "cannot describe - " | ||
| 566 | - | "no tags can describe '%s'."); | ||
| 567 | ##### | 91 | goto cleanup; | |
| 568 | - | } | ||
| 569 | - | } | ||
| 570 | - | |||
| 571 | 19 | 92 | git_vector_sort(&all_matches); | |
| 572 | - | |||
| 573 | 19 | 93 | best = (struct possible_tag *)git_vector_get(&all_matches, 0); | |
| 574 | - | |||
| 575 | 19 | 94 | if (gave_up_on) { | |
| 576 | ##### | 95,96 | if ((error = git_pqueue_insert(&list, gave_up_on)) < 0) | |
| 577 | ##### | 97 | goto cleanup; | |
| 578 | ##### | 98 | seen_commits--; | |
| 579 | - | } | ||
| 580 | 19 | 99,100 | if ((error = finish_depth_computation( | |
| 581 | - | &list, walk, best)) < 0) | ||
| 582 | ##### | 101 | goto cleanup; | |
| 583 | - | |||
| 584 | 19 | 102 | seen_commits += error; | |
| 585 | 19 | 102,103 | if ((error = possible_tag_dup(&data->result->tag, best)) < 0) | |
| 586 | ##### | 104 | goto cleanup; | |
| 587 | - | |||
| 588 | - | /* | ||
| 589 | - | { | ||
| 590 | - | static const char *prio_names[] = { | ||
| 591 | - | "head", "lightweight", "annotated", | ||
| 592 | - | }; | ||
| 593 | - | |||
| 594 | - | char oid_str[GIT_OID_HEXSZ + 1]; | ||
| 595 | - | |||
| 596 | - | if (debug) { | ||
| 597 | - | for (cur_match = 0; cur_match < match_cnt; cur_match++) { | ||
| 598 | - | struct possible_tag *t = (struct possible_tag *)git_vector_get(&all_matches, cur_match); | ||
| 599 | - | fprintf(stderr, " %-11s %8d %s\n", | ||
| 600 | - | prio_names[t->name->prio], | ||
| 601 | - | t->depth, t->name->path); | ||
| 602 | - | } | ||
| 603 | - | fprintf(stderr, "traversed %lu commits\n", seen_commits); | ||
| 604 | - | if (gave_up_on) { | ||
| 605 | - | git_oid_tostr(oid_str, sizeof(oid_str), &gave_up_on->oid); | ||
| 606 | - | fprintf(stderr, | ||
| 607 | - | "more than %i tags found; listed %i most recent\n" | ||
| 608 | - | "gave up search at %s\n", | ||
| 609 | - | data->opts->max_candidates_tags, data->opts->max_candidates_tags, | ||
| 610 | - | oid_str); | ||
| 611 | - | } | ||
| 612 | - | } | ||
| 613 | - | } | ||
| 614 | - | */ | ||
| 615 | - | |||
| 616 | 19 | 105 | git_oid_cpy(&data->result->commit_id, &cmit->oid); | |
| 617 | - | |||
| 618 | - | cleanup: | ||
| 619 | - | { | ||
| 620 | - | size_t i; | ||
| 621 | - | struct possible_tag *match; | ||
| 622 | 80 | 106,108-110 | git_vector_foreach(&all_matches, i, match) { | |
| 623 | 51 | 107 | git__free(match); | |
| 624 | - | } | ||
| 625 | - | } | ||
| 626 | 29 | 111 | git_vector_free(&all_matches); | |
| 627 | 29 | 112 | git_pqueue_free(&list); | |
| 628 | 29 | 113 | git_revwalk_free(walk); | |
| 629 | 29 | 114 | return error; | |
| 630 | - | } | ||
| 631 | - | |||
| 632 | 30 | 2 | static int normalize_options( | |
| 633 | - | git_describe_options *dst, | ||
| 634 | - | const git_describe_options *src) | ||
| 635 | - | { | ||
| 636 | 30 | 2 | git_describe_options default_options = GIT_DESCRIBE_OPTIONS_INIT; | |
| 637 | 30 | 2,3 | if (!src) src = &default_options; | |
| 638 | - | |||
| 639 | 30 | 4 | *dst = *src; | |
| 640 | - | |||
| 641 | 30 | 4 | if (dst->max_candidates_tags > GIT_DESCRIBE_DEFAULT_MAX_CANDIDATES_TAGS) | |
| 642 | ##### | 5 | dst->max_candidates_tags = GIT_DESCRIBE_DEFAULT_MAX_CANDIDATES_TAGS; | |
| 643 | - | |||
| 644 | 30 | 6 | return 0; | |
| 645 | - | } | ||
| 646 | - | |||
| 647 | ![]() |
30 | 2 | int git_describe_commit( |
| 648 | - | git_describe_result **result, | ||
| 649 | - | git_object *committish, | ||
| 650 | - | git_describe_options *opts) | ||
| 651 | - | { | ||
| 652 | - | struct get_name_data data; | ||
| 653 | - | struct commit_name *name; | ||
| 654 | - | git_commit *commit; | ||
| 655 | 30 | 2 | int error = -1; | |
| 656 | - | git_describe_options normalized; | ||
| 657 | - | |||
| 658 | 30 | 2,3 | assert(committish); | |
| 659 | - | |||
| 660 | 30 | 4 | data.result = git__calloc(1, sizeof(git_describe_result)); | |
| 661 | 30 | 5,6 | GIT_ERROR_CHECK_ALLOC(data.result); | |
| 662 | 30 | 7 | data.result->repo = git_object_owner(committish); | |
| 663 | - | |||
| 664 | 30 | 8 | data.repo = git_object_owner(committish); | |
| 665 | - | |||
| 666 | 30 | 9,10 | if ((error = normalize_options(&normalized, opts)) < 0) | |
| 667 | ##### | 11 | return error; | |
| 668 | - | |||
| 669 | 30 | 12-14 | GIT_ERROR_CHECK_VERSION( | |
| 670 | - | &normalized, | ||
| 671 | - | GIT_DESCRIBE_OPTIONS_VERSION, | ||
| 672 | - | "git_describe_options"); | ||
| 673 | 30 | 15 | data.opts = &normalized; | |
| 674 | - | |||
| 675 | 30 | 15,16 | if ((error = git_oidmap_new(&data.names)) < 0) | |
| 676 | ##### | 17 | return error; | |
| 677 | - | |||
| 678 | - | /** TODO: contains to be implemented */ | ||
| 679 | - | |||
| 680 | 30 | 18,19 | if ((error = git_object_peel((git_object **)(&commit), committish, GIT_OBJECT_COMMIT)) < 0) | |
| 681 | ##### | 20 | goto cleanup; | |
| 682 | - | |||
| 683 | 30 | 21-23 | if ((error = git_reference_foreach_name( | |
| 684 | - | git_object_owner(committish), | ||
| 685 | - | get_name, &data)) < 0) | ||
| 686 | ##### | 24 | goto cleanup; | |
| 687 | - | |||
| 688 | 30 | 25-27 | if (git_oidmap_size(data.names) == 0 && !opts->show_commit_oid_as_fallback) { | |
| 689 | 1 | 28 | git_error_set(GIT_ERROR_DESCRIBE, "cannot describe - " | |
| 690 | - | "no reference found, cannot describe anything."); | ||
| 691 | 1 | 29 | error = -1; | |
| 692 | 1 | 29 | goto cleanup; | |
| 693 | - | } | ||
| 694 | - | |||
| 695 | 29 | 30,31 | if ((error = describe(&data, commit)) < 0) | |
| 696 | ##### | 32 | goto cleanup; | |
| 697 | - | |||
| 698 | - | cleanup: | ||
| 699 | 30 | 33 | git_commit_free(commit); | |
| 700 | - | |||
| 701 | 153 | 34-39 | git_oidmap_foreach_value(data.names, name, { | |
| 702 | - | git_tag_free(name->tag); | ||
| 703 | - | git__free(name->path); | ||
| 704 | - | git__free(name); | ||
| 705 | - | }); | ||
| 706 | - | |||
| 707 | 30 | 40 | git_oidmap_free(data.names); | |
| 708 | - | |||
| 709 | 30 | 41 | if (error < 0) | |
| 710 | 1 | 42 | git_describe_result_free(data.result); | |
| 711 | - | else | ||
| 712 | 29 | 43 | *result = data.result; | |
| 713 | - | |||
| 714 | 30 | 44 | return error; | |
| 715 | - | } | ||
| 716 | - | |||
| 717 | ![]() |
3 | 2 | int git_describe_workdir( |
| 718 | - | git_describe_result **out, | ||
| 719 | - | git_repository *repo, | ||
| 720 | - | git_describe_options *opts) | ||
| 721 | - | { | ||
| 722 | - | int error; | ||
| 723 | - | git_oid current_id; | ||
| 724 | 3 | 2 | git_status_list *status = NULL; | |
| 725 | 3 | 2 | git_status_options status_opts = GIT_STATUS_OPTIONS_INIT; | |
| 726 | 3 | 2 | git_describe_result *result = NULL; | |
| 727 | - | git_object *commit; | ||
| 728 | - | |||
| 729 | 3 | 2,3 | if ((error = git_reference_name_to_id(¤t_id, repo, GIT_HEAD_FILE)) < 0) | |
| 730 | ##### | 4 | return error; | |
| 731 | - | |||
| 732 | 3 | 5,6 | if ((error = git_object_lookup(&commit, repo, ¤t_id, GIT_OBJECT_COMMIT)) < 0) | |
| 733 | ##### | 7 | return error; | |
| 734 | - | |||
| 735 | - | /* The first step is to perform a describe of HEAD, so we can leverage this */ | ||
| 736 | 3 | 8,9 | if ((error = git_describe_commit(&result, commit, opts)) < 0) | |
| 737 | ##### | 10 | goto out; | |
| 738 | - | |||
| 739 | 3 | 11,12 | if ((error = git_status_list_new(&status, repo, &status_opts)) < 0) | |
| 740 | ##### | 13 | goto out; | |
| 741 | - | |||
| 742 | - | |||
| 743 | 3 | 14,15 | if (git_status_list_entrycount(status) > 0) | |
| 744 | 3 | 16 | result->dirty = 1; | |
| 745 | - | |||
| 746 | - | out: | ||
| 747 | 3 | 17 | git_object_free(commit); | |
| 748 | 3 | 18 | git_status_list_free(status); | |
| 749 | - | |||
| 750 | 3 | 19 | if (error < 0) | |
| 751 | ##### | 20 | git_describe_result_free(result); | |
| 752 | - | else | ||
| 753 | 3 | 21 | *out = result; | |
| 754 | - | |||
| 755 | 3 | 22 | return error; | |
| 756 | - | } | ||
| 757 | - | |||
| 758 | 28 | 2 | static int normalize_format_options( | |
| 759 | - | git_describe_format_options *dst, | ||
| 760 | - | const git_describe_format_options *src) | ||
| 761 | - | { | ||
| 762 | 28 | 2 | if (!src) { | |
| 763 | ##### | 3 | git_describe_format_options_init(dst, GIT_DESCRIBE_FORMAT_OPTIONS_VERSION); | |
| 764 | ##### | 4 | return 0; | |
| 765 | - | } | ||
| 766 | - | |||
| 767 | 28 | 5 | memcpy(dst, src, sizeof(git_describe_format_options)); | |
| 768 | 28 | 5 | return 0; | |
| 769 | - | } | ||
| 770 | - | |||
| 771 | ![]() |
28 | 2 | int git_describe_format(git_buf *out, const git_describe_result *result, const git_describe_format_options *given) |
| 772 | - | { | ||
| 773 | - | int error; | ||
| 774 | - | git_repository *repo; | ||
| 775 | - | struct commit_name *name; | ||
| 776 | - | git_describe_format_options opts; | ||
| 777 | - | |||
| 778 | 28 | 2-4 | assert(out && result); | |
| 779 | - | |||
| 780 | 28 | 5-7 | GIT_ERROR_CHECK_VERSION(given, GIT_DESCRIBE_FORMAT_OPTIONS_VERSION, "git_describe_format_options"); | |
| 781 | 28 | 8 | normalize_format_options(&opts, given); | |
| 782 | - | |||
| 783 | 28 | 9 | git_buf_sanitize(out); | |
| 784 | - | |||
| 785 | - | |||
| 786 | 28 | 10,11 | if (opts.always_use_long_format && opts.abbreviated_size == 0) { | |
| 787 | ##### | 12 | git_error_set(GIT_ERROR_DESCRIBE, "cannot describe - " | |
| 788 | - | "'always_use_long_format' is incompatible with a zero" | ||
| 789 | - | "'abbreviated_size'"); | ||
| 790 | ##### | 13 | return -1; | |
| 791 | - | } | ||
| 792 | - | |||
| 793 | - | |||
| 794 | 28 | 14 | repo = result->repo; | |
| 795 | - | |||
| 796 | - | /* If we did find an exact match, then it's the easier method */ | ||
| 797 | 28 | 14 | if (result->exact_match) { | |
| 798 | 8 | 15 | name = result->name; | |
| 799 | 8 | 15,16 | if ((error = display_name(out, repo, name)) < 0) | |
| 800 | ##### | 17 | return error; | |
| 801 | - | |||
| 802 | 8 | 18 | if (opts.always_use_long_format) { | |
| 803 | 2 | 19-21 | const git_oid *id = name->tag ? git_tag_target_id(name->tag) : &result->commit_id; | |
| 804 | 2 | 22,23 | if ((error = show_suffix(out, 0, repo, id, opts.abbreviated_size)) < 0) | |
| 805 | ##### | 24 | return error; | |
| 806 | - | } | ||
| 807 | - | |||
| 808 | 8 | 25,26 | if (result->dirty && opts.dirty_suffix) | |
| 809 | ##### | 27 | git_buf_puts(out, opts.dirty_suffix); | |
| 810 | - | |||
| 811 | 8 | 28-32 | return git_buf_oom(out) ? -1 : 0; | |
| 812 | - | } | ||
| 813 | - | |||
| 814 | - | /* If we didn't find *any* tags, we fall back to the commit's id */ | ||
| 815 | 20 | 33 | if (result->fallback_to_id) { | |
| 816 | 1 | 34 | char hex_oid[GIT_OID_HEXSZ + 1] = {0}; | |
| 817 | 1 | 34 | int size = 0; | |
| 818 | - | |||
| 819 | 1 | 34,35 | if ((error = find_unique_abbrev_size( | |
| 820 | - | &size, repo, &result->commit_id, opts.abbreviated_size)) < 0) | ||
| 821 | ##### | 36 | return -1; | |
| 822 | - | |||
| 823 | 1 | 37 | git_oid_fmt(hex_oid, &result->commit_id); | |
| 824 | 1 | 38 | git_buf_put(out, hex_oid, size); | |
| 825 | - | |||
| 826 | 1 | 39,40 | if (result->dirty && opts.dirty_suffix) | |
| 827 | ##### | 41 | git_buf_puts(out, opts.dirty_suffix); | |
| 828 | - | |||
| 829 | 1 | 42-47 | return git_buf_oom(out) ? -1 : 0; | |
| 830 | - | } | ||
| 831 | - | |||
| 832 | - | /* Lastly, if we found a matching tag, we show that */ | ||
| 833 | 19 | 48 | name = result->tag->name; | |
| 834 | - | |||
| 835 | 19 | 48,49 | if ((error = display_name(out, repo, name)) < 0) | |
| 836 | ##### | 50 | return error; | |
| 837 | - | |||
| 838 | 19 | 51 | if (opts.abbreviated_size) { | |
| 839 | 19 | 52,53 | if ((error = show_suffix(out, result->tag->depth, repo, | |
| 840 | - | &result->commit_id, opts.abbreviated_size)) < 0) | ||
| 841 | ##### | 54 | return error; | |
| 842 | - | } | ||
| 843 | - | |||
| 844 | 19 | 55,56 | if (result->dirty && opts.dirty_suffix) { | |
| 845 | 2 | 57 | git_buf_puts(out, opts.dirty_suffix); | |
| 846 | - | } | ||
| 847 | - | |||
| 848 | 19 | 58 | return git_buf_oom(out) ? -1 : 0; | |
| 849 | - | } | ||
| 850 | - | |||
| 851 | 30 | 2 | void git_describe_result_free(git_describe_result *result) | |
| 852 | - | { | ||
| 853 | 30 | 2 | if (result == NULL) | |
| 854 | 30 | 3,14 | return; | |
| 855 | - | |||
| 856 | 30 | 4 | if (result->name) { | |
| 857 | 8 | 5 | git_tag_free(result->name->tag); | |
| 858 | 8 | 6 | git__free(result->name->path); | |
| 859 | 8 | 7 | git__free(result->name); | |
| 860 | - | } | ||
| 861 | - | |||
| 862 | 30 | 8 | if (result->tag) { | |
| 863 | 19 | 9 | git_tag_free(result->tag->name->tag); | |
| 864 | 19 | 10 | git__free(result->tag->name->path); | |
| 865 | 19 | 11 | git__free(result->tag->name); | |
| 866 | 19 | 12 | git__free(result->tag); | |
| 867 | - | } | ||
| 868 | - | |||
| 869 | 30 | 13 | git__free(result); | |
| 870 | - | } | ||
| 871 | - | |||
| 872 | ![]() |
##### | 2 | int git_describe_options_init(git_describe_options *opts, unsigned int version) |
| 873 | - | { | ||
| 874 | ##### | 2-4 | GIT_INIT_STRUCTURE_FROM_TEMPLATE( | |
| 875 | - | opts, version, git_describe_options, GIT_DESCRIBE_OPTIONS_INIT); | ||
| 876 | ##### | 5 | return 0; | |
| 877 | - | } | ||
| 878 | - | |||
| 879 | - | #ifndef GIT_DEPRECATE_HARD | ||
| 880 | ##### | 2 | int git_describe_init_options(git_describe_options *opts, unsigned int version) | |
| 881 | - | { | ||
| 882 | ##### | 2 | return git_describe_options_init(opts, version); | |
| 883 | - | } | ||
| 884 | - | #endif | ||
| 885 | - | |||
| 886 | ![]() |
##### | 2 | int git_describe_format_options_init(git_describe_format_options *opts, unsigned int version) |
| 887 | - | { | ||
| 888 | ##### | 2-4 | GIT_INIT_STRUCTURE_FROM_TEMPLATE( | |
| 889 | - | opts, version, git_describe_format_options, GIT_DESCRIBE_FORMAT_OPTIONS_INIT); | ||
| 890 | ##### | 5 | return 0; | |
| 891 | - | } | ||
| 892 | - | |||
| 893 | - | #ifndef GIT_DEPRECATE_HARD | ||
| 894 | ##### | 2 | int git_describe_init_format_options(git_describe_format_options *opts, unsigned int version) | |
| 895 | - | { | ||
| 896 | ##### | 2 | return git_describe_format_options_init(opts, version); | |
| 897 | - | } | ||
| 898 | - | #endif |