static int maybe_describe(git_object**out, git_repository *repo, const char *spec) { const char *substr; int error; regex_t regex; substr = strstr(spec, "-g"); if (substr == NULL) return GIT_ENOTFOUND; if (build_regex(®ex, ".+-[0-9]+-g[0-9a-fA-F]+") < 0) return -1; error = regexec(®ex, spec, 0, NULL, 0); regfree(®ex); if (error) return GIT_ENOTFOUND; return maybe_abbrev(out, repo, substr+2); }
static int revparse_lookup_object(git_object **out, git_repository *repo, const char *spec) { int error; git_reference *ref; error = maybe_sha(out, repo, spec); if (!error) return 0; if (error < 0 && error != GIT_ENOTFOUND) return error; error = disambiguate_refname(&ref, repo, spec); if (!error) { error = git_object_lookup(out, repo, git_reference_target(ref), GIT_OBJ_ANY); git_reference_free(ref); return error; } if (error < 0 && error != GIT_ENOTFOUND) return error; error = maybe_abbrev(out, repo, spec); if (!error) return 0; if (error < 0 && error != GIT_ENOTFOUND) return error; error = maybe_describe(out, repo, spec); if (!error) return 0; if (error < 0 && error != GIT_ENOTFOUND) return error; giterr_set(GITERR_REFERENCE, "Refspec '%s' not found.", spec); return GIT_ENOTFOUND; }
static int revparse_lookup_object( git_object **object_out, git_reference **reference_out, git_repository *repo, const char *spec) { int error; git_reference *ref; if ((error = maybe_sha(object_out, repo, spec)) != GIT_ENOTFOUND) return error; error = git_reference_dwim(&ref, repo, spec); if (!error) { error = git_object_lookup( object_out, repo, git_reference_target(ref), GIT_OBJ_ANY); if (!error) *reference_out = ref; return error; } if (error != GIT_ENOTFOUND) return error; if ((strlen(spec) < GIT_OID_HEXSZ) && ((error = maybe_abbrev(object_out, repo, spec)) != GIT_ENOTFOUND)) return error; if ((error = maybe_describe(object_out, repo, spec)) != GIT_ENOTFOUND) return error; giterr_set(GITERR_REFERENCE, "revspec '%s' not found", spec); return GIT_ENOTFOUND; }
static int retrieve_previously_checked_out_branch_or_revision(git_object **out, git_reference **base_ref, git_repository *repo, const char *identifier, size_t position) { git_reference *ref = NULL; git_reflog *reflog = NULL; regex_t preg; int error = -1; size_t i, numentries, cur; const git_reflog_entry *entry; const char *msg; regmatch_t regexmatches[2]; git_buf buf = GIT_BUF_INIT; cur = position; if (*identifier != '\0' || *base_ref != NULL) return GIT_EINVALIDSPEC; if (build_regex(&preg, "checkout: moving from (.*) to .*") < 0) return -1; if (git_reference_lookup(&ref, repo, GIT_HEAD_FILE) < 0) goto cleanup; if (git_reflog_read(&reflog, repo, GIT_HEAD_FILE) < 0) goto cleanup; numentries = git_reflog_entrycount(reflog); for (i = 0; i < numentries; i++) { entry = git_reflog_entry_byindex(reflog, i); msg = git_reflog_entry_message(entry); if (!msg) continue; if (regexec(&preg, msg, 2, regexmatches, 0)) continue; cur--; if (cur > 0) continue; git_buf_put(&buf, msg+regexmatches[1].rm_so, regexmatches[1].rm_eo - regexmatches[1].rm_so); if ((error = git_reference_dwim(base_ref, repo, git_buf_cstr(&buf))) == 0) goto cleanup; if (error < 0 && error != GIT_ENOTFOUND) goto cleanup; error = maybe_abbrev(out, repo, git_buf_cstr(&buf)); goto cleanup; } error = GIT_ENOTFOUND; cleanup: git_reference_free(ref); git_buf_free(&buf); regfree(&preg); git_reflog_free(reflog); return error; }