int status, exists;
static char hex[41];
- exists = has_sha1_file(sha1);
memcpy(hex, sha1_to_hex(sha1), 40);
if (len == 40 || !len)
return hex;
+ exists = has_sha1_file(sha1);
while (len < 40) {
unsigned char sha1_ret[20];
status = get_short_sha1(hex, len, sha1_ret, GET_SHA1_QUIETLY);
static int get_sha1_1(const char *name, int len, unsigned char *sha1, unsigned lookup_flags);
static int interpret_nth_prior_checkout(const char *name, int namelen, struct strbuf *buf);
-static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
+static int get_sha1_basic(const char *str, int len, unsigned char *sha1,
+ unsigned int flags)
{
static const char *warn_msg = "refname '%.*s' is ambiguous.";
static const char *object_name_msg = N_(
int at, reflog_len, nth_prior = 0;
if (len == 40 && !get_sha1_hex(str, sha1)) {
- if (warn_on_object_refname_ambiguity) {
+ if (warn_ambiguous_refs && warn_on_object_refname_ambiguity) {
refs_found = dwim_ref(str, len, tmp_sha1, &real_ref);
- if (refs_found > 0 && warn_ambiguous_refs) {
+ if (refs_found > 0) {
warning(warn_msg, len, str);
if (advice_object_name_warning)
fprintf(stderr, "%s\n", _(object_name_msg));
if (!refs_found)
return -1;
- if (warn_ambiguous_refs &&
+ if (warn_ambiguous_refs && !(flags & GET_SHA1_QUIETLY) &&
(refs_found > 1 ||
!get_short_sha1(str, len, tmp_sha1, GET_SHA1_QUIETLY)))
warning(warn_msg, len, str);
char *tmp = xstrndup(str + at + 2, reflog_len);
at_time = approxidate_careful(tmp, &errors);
free(tmp);
- if (errors)
+ if (errors) {
+ free(real_ref);
return -1;
+ }
}
- if (read_ref_at(real_ref, at_time, nth, sha1, NULL,
+ if (read_ref_at(real_ref, flags, at_time, nth, sha1, NULL,
&co_time, &co_tz, &co_cnt)) {
if (!len) {
- if (!prefixcmp(real_ref, "refs/heads/")) {
+ if (starts_with(real_ref, "refs/heads/")) {
str = real_ref + 11;
len = strlen(real_ref + 11);
} else {
len = 4;
}
}
- if (at_time)
- warning("Log for '%.*s' only goes "
- "back to %s.", len, str,
- show_date(co_time, co_tz, DATE_RFC2822));
- else {
+ if (at_time) {
+ if (!(flags & GET_SHA1_QUIETLY)) {
+ warning("Log for '%.*s' only goes "
+ "back to %s.", len, str,
+ show_date(co_time, co_tz, DATE_RFC2822));
+ }
+ } else {
+ if (flags & GET_SHA1_QUIETLY) {
+ exit(128);
+ }
die("Log for '%.*s' only has %d entries.",
len, str, co_cnt);
}
if (ret)
return ret;
commit = lookup_commit_reference(sha1);
- if (!commit)
- return -1;
if (parse_commit(commit))
return -1;
if (!idx) {
return -1;
sp++; /* beginning of type name, or closing brace for empty */
- if (!prefixcmp(sp, "commit}"))
+ if (starts_with(sp, "commit}"))
expected_type = OBJ_COMMIT;
- else if (!prefixcmp(sp, "tag}"))
+ else if (starts_with(sp, "tag}"))
expected_type = OBJ_TAG;
- else if (!prefixcmp(sp, "tree}"))
+ else if (starts_with(sp, "tree}"))
expected_type = OBJ_TREE;
- else if (!prefixcmp(sp, "blob}"))
+ else if (starts_with(sp, "blob}"))
expected_type = OBJ_BLOB;
- else if (!prefixcmp(sp, "object}"))
+ else if (starts_with(sp, "object}"))
expected_type = OBJ_ANY;
else if (sp[0] == '}')
expected_type = OBJ_NONE;
if (!ret)
return 0;
- ret = get_sha1_basic(name, len, sha1);
+ ret = get_sha1_basic(name, len, sha1, lookup_flags);
if (!ret)
return 0;
* For future extension, ':/!' is reserved. If you want to match a message
* beginning with a '!', you have to repeat the exclamation mark.
*/
+
+/* Remember to update object flag allocation in object.h */
#define ONELINE_SEEN (1u<<20)
static int handle_one_ref(const char *path,
}
if (object->type != OBJ_COMMIT)
return 0;
- commit_list_insert_by_date((struct commit *)object, list);
+ commit_list_insert((struct commit *)object, list);
return 0;
}
commit_list_insert(l->item, &backup);
}
while (list) {
- char *p, *to_free = NULL;
+ const char *p, *buf;
struct commit *commit;
- enum object_type type;
- unsigned long size;
int matches;
commit = pop_most_recent_commit(&list, ONELINE_SEEN);
if (!parse_object(commit->object.sha1))
continue;
- if (commit->buffer)
- p = commit->buffer;
- else {
- p = read_sha1_file(commit->object.sha1, &type, &size);
- if (!p)
- continue;
- to_free = p;
- }
-
- p = strstr(p, "\n\n");
+ buf = get_commit_buffer(commit, NULL);
+ p = strstr(buf, "\n\n");
matches = p && !regexec(®ex, p + 2, 0, NULL, 0);
- free(to_free);
+ unuse_commit_buffer(commit, buf);
if (matches) {
hashcpy(sha1, commit->object.sha1);
const char *match = NULL, *target = NULL;
size_t len;
- if (!prefixcmp(message, "checkout: moving from ")) {
- match = message + strlen("checkout: moving from ");
+ if (skip_prefix(message, "checkout: moving from ", &match))
target = strstr(match, " to ");
- }
if (!match || !target)
return 0;
retval = 0;
if (0 < for_each_reflog_ent_reverse("HEAD", grab_nth_branch_switch, &cb)) {
strbuf_reset(buf);
- strbuf_add(buf, cb.buf.buf, cb.buf.len);
+ strbuf_addbuf(buf, &cb.buf);
retval = brace - name + 1;
}
two = lookup_commit_reference_gently(sha1_tmp, 0);
if (!two)
return -1;
- mbs = get_merge_bases(one, two, 1);
+ mbs = get_merge_bases(one, two);
if (!mbs || mbs->next)
st = -1;
else {
die("Path '%s' exists on disk, but not in '%.*s'.",
filename, object_name_len, object_name);
if (errno == ENOENT || errno == ENOTDIR) {
- char *fullname = xmalloc(strlen(filename)
- + strlen(prefix) + 1);
- strcpy(fullname, prefix);
- strcat(fullname, filename);
+ char *fullname = xstrfmt("%s%s", prefix, filename);
if (!get_tree_entry(tree_sha1, fullname,
sha1, &mode)) {
static char *resolve_relative_path(const char *rel)
{
- if (prefixcmp(rel, "./") && prefixcmp(rel, "../"))
+ if (!starts_with(rel, "./") && !starts_with(rel, "../"))
return NULL;
if (!startup_info)
if (!only_to_die && namelen > 2 && name[1] == '/') {
struct commit_list *list = NULL;
for_each_ref(handle_one_ref, &list);
+ commit_list_sort_by_date(&list);
return get_sha1_oneline(name + 2, sha1, list);
}
if (namelen < 3 ||