static int find_short_packed_object(int len, const unsigned char *match, unsigned char *sha1)
{
struct packed_git *p;
- unsigned char found_sha1[20];
+ const unsigned char *found_sha1 = NULL;
int found = 0;
prepare_packed_git();
for (p = packed_git; p && found < 2; p = p->next) {
- unsigned num = num_packed_objects(p);
- unsigned first = 0, last = num;
+ uint32_t num, last;
+ uint32_t first = 0;
+ open_pack_index(p);
+ num = p->num_objects;
+ last = num;
while (first < last) {
- unsigned mid = (first + last) / 2;
- unsigned char now[20];
+ uint32_t mid = (first + last) / 2;
+ const unsigned char *now;
int cmp;
- nth_packed_object_sha1(p, mid, now);
+ now = nth_packed_object_sha1(p, mid);
cmp = hashcmp(match, now);
if (!cmp) {
first = mid;
last = mid;
}
if (first < num) {
- unsigned char now[20], next[20];
- nth_packed_object_sha1(p, first, now);
+ const unsigned char *now, *next;
+ now = nth_packed_object_sha1(p, first);
if (match_sha(len, match, now)) {
- if (nth_packed_object_sha1(p, first+1, next) ||
- !match_sha(len, match, next)) {
+ next = nth_packed_object_sha1(p, first+1);
+ if (!next|| !match_sha(len, match, next)) {
/* unique within this pack */
if (!found) {
- hashcpy(found_sha1, now);
+ found_sha1 = now;
found++;
}
else if (hashcmp(found_sha1, now)) {
int has_unpacked, has_packed;
unsigned char unpacked_sha1[20], packed_sha1[20];
+ prepare_alt_odb();
has_unpacked = find_short_object_filename(len, canonical, unpacked_sha1);
has_packed = find_short_packed_object(len, res, packed_sha1);
if (!has_unpacked && !has_packed)
return slash;
}
-static const char *ref_fmt[] = {
- "%.*s",
- "refs/%.*s",
- "refs/tags/%.*s",
- "refs/heads/%.*s",
- "refs/remotes/%.*s",
- "refs/remotes/%.*s/HEAD",
- NULL
-};
-
int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref)
{
const char **p, *r;
int refs_found = 0;
*ref = NULL;
- for (p = ref_fmt; *p; p++) {
+ for (p = ref_rev_parse_rules; *p; p++) {
unsigned char sha1_from_ref[20];
unsigned char *this_result;
int logs_found = 0;
*log = NULL;
- for (p = ref_fmt; *p; p++) {
+ for (p = ref_rev_parse_rules; *p; p++) {
struct stat st;
unsigned char hash[20];
char path[PATH_MAX];
fprintf(stderr,
"warning: Log for '%.*s' only goes "
"back to %s.\n", len, str,
- show_rfc2822_date(co_time, co_tz));
+ show_date(co_time, co_tz, DATE_RFC2822));
else
fprintf(stderr,
"warning: Log for '%.*s' only has "
return 0;
}
+struct object *peel_to_type(const char *name, int namelen,
+ struct object *o, enum object_type expected_type)
+{
+ if (name && !namelen)
+ namelen = strlen(name);
+ if (!o) {
+ unsigned char sha1[20];
+ if (get_sha1_1(name, namelen, sha1))
+ return NULL;
+ o = parse_object(sha1);
+ }
+ while (1) {
+ if (!o || (!o->parsed && !parse_object(o->sha1)))
+ return NULL;
+ if (o->type == expected_type)
+ return o;
+ if (o->type == OBJ_TAG)
+ o = ((struct tag*) o)->tagged;
+ else if (o->type == OBJ_COMMIT)
+ o = &(((struct commit *) o)->tree->object);
+ else {
+ if (name)
+ error("%.*s: expected %s type, but the object "
+ "dereferences to %s type",
+ namelen, name, typename(expected_type),
+ typename(o->type));
+ return NULL;
+ }
+ }
+}
+
static int peel_onion(const char *name, int len, unsigned char *sha1)
{
unsigned char outer[20];
hashcpy(sha1, o->sha1);
}
else {
- /* At this point, the syntax look correct, so
+ /*
+ * At this point, the syntax look correct, so
* if we do not get the needed object, we should
* barf.
*/
-
- while (1) {
- if (!o || (!o->parsed && !parse_object(o->sha1)))
- return -1;
- if (o->type == expected_type) {
- hashcpy(sha1, o->sha1);
- return 0;
- }
- if (o->type == OBJ_TAG)
- o = ((struct tag*) o)->tagged;
- else if (o->type == OBJ_COMMIT)
- o = &(((struct commit *) o)->tree->object);
- else
- return error("%.*s: expected %s type, but the object dereferences to %s type",
- len, name, typename(expected_type),
- typename(o->type));
- if (!o->parsed)
- parse_object(o->sha1);
+ o = peel_to_type(name, len, o, expected_type);
+ if (o) {
+ hashcpy(sha1, o->sha1);
+ return 0;
}
+ return -1;
}
return 0;
}
struct object *object = parse_object(sha1);
if (!object)
return 0;
- if (object->type == OBJ_TAG)
+ if (object->type == OBJ_TAG) {
object = deref_tag(object, path, strlen(path));
+ if (!object)
+ return 0;
+ }
if (object->type != OBJ_COMMIT)
return 0;
insert_by_date((struct commit *)object, list);
*/
#define ONELINE_SEEN (1u<<20)
-int get_sha1_oneline(const char *prefix, unsigned char *sha1)
+static int get_sha1_oneline(const char *prefix, unsigned char *sha1)
{
struct commit_list *list = NULL, *backup = NULL, *l;
- struct commit *commit;
+ int retval = -1;
+ char *temp_commit_buffer = NULL;
if (prefix[0] == '!') {
if (prefix[1] != '!')
die ("Invalid search pattern: %s", prefix);
prefix++;
}
- if (!save_commit_buffer)
- return error("Could not expand oneline-name.");
for_each_ref(handle_one_ref, &list);
for (l = list; l; l = l->next)
commit_list_insert(l->item, &backup);
- while ((commit = pop_most_recent_commit(&list, ONELINE_SEEN))) {
+ while (list) {
char *p;
+ struct commit *commit;
+ enum object_type type;
+ unsigned long size;
+
+ commit = pop_most_recent_commit(&list, ONELINE_SEEN);
parse_object(commit->object.sha1);
- if (!commit->buffer || !(p = strstr(commit->buffer, "\n\n")))
+ if (temp_commit_buffer)
+ free(temp_commit_buffer);
+ if (commit->buffer)
+ p = commit->buffer;
+ else {
+ p = read_sha1_file(commit->object.sha1, &type, &size);
+ if (!p)
+ continue;
+ temp_commit_buffer = p;
+ }
+ if (!(p = strstr(p, "\n\n")))
continue;
if (!prefixcmp(p + 2, prefix)) {
hashcpy(sha1, commit->object.sha1);
+ retval = 0;
break;
}
}
+ if (temp_commit_buffer)
+ free(temp_commit_buffer);
free_commit_list(list);
for (l = backup; l; l = l->next)
clear_commit_marks(l->item, ONELINE_SEEN);
- return commit == NULL;
+ return retval;
}
/*
*/
int get_sha1(const char *name, unsigned char *sha1)
{
- int ret, bracket_depth;
unsigned unused;
+ return get_sha1_with_mode(name, sha1, &unused);
+}
+
+int get_sha1_with_mode(const char *name, unsigned char *sha1, unsigned *mode)
+{
+ int ret, bracket_depth;
int namelen = strlen(name);
const char *cp;
- prepare_alt_odb();
+ *mode = S_IFINVALID;
ret = get_sha1_1(name, namelen, sha1);
if (!ret)
return ret;
namelen = namelen - (cp - name);
if (!active_cache)
read_cache();
- if (active_nr < 0)
- return -1;
pos = cache_name_pos(cp, namelen);
if (pos < 0)
pos = -pos - 1;
break;
if (ce_stage(ce) == stage) {
hashcpy(sha1, ce->sha1);
+ *mode = ce->ce_mode;
return 0;
}
pos++;
unsigned char tree_sha1[20];
if (!get_sha1_1(name, cp-name, tree_sha1))
return get_tree_entry(tree_sha1, cp+1, sha1,
- &unused);
+ mode);
}
return ret;
}