4 static int find_short_object_filename(int len
, const char *name
, unsigned char *sha1
)
6 static char dirname
[PATH_MAX
];
11 snprintf(dirname
, sizeof(dirname
), "%s/%.2s", get_object_directory(), name
);
12 dir
= opendir(dirname
);
13 sprintf(hex
, "%.2s", name
);
17 while ((de
= readdir(dir
)) != NULL
) {
18 if (strlen(de
->d_name
) != 38)
20 if (memcmp(de
->d_name
, name
+ 2, len
-2))
22 memcpy(hex
+ 2, de
->d_name
, 38);
29 return get_sha1_hex(hex
, sha1
) == 0;
33 static int match_sha(unsigned len
, const unsigned char *a
, const unsigned char *b
)
48 static int find_short_packed_object(int len
, const unsigned char *match
, unsigned char *sha1
)
53 for (p
= packed_git
; p
; p
= p
->next
) {
54 unsigned num
= num_packed_objects(p
);
55 unsigned first
= 0, last
= num
;
56 while (first
< last
) {
57 unsigned mid
= (first
+ last
) / 2;
58 unsigned char now
[20];
61 nth_packed_object_sha1(p
, mid
, now
);
62 cmp
= memcmp(match
, now
, 20);
74 unsigned char now
[20], next
[20];
75 nth_packed_object_sha1(p
, first
, now
);
76 if (match_sha(len
, match
, now
)) {
77 if (nth_packed_object_sha1(p
, first
+1, next
) || !match_sha(len
, match
, next
)) {
78 memcpy(sha1
, now
, 20);
87 static int get_short_sha1(const char *name
, unsigned char *sha1
)
91 unsigned char res
[20];
94 memset(canonical
, 'x', 40);
96 unsigned char c
= name
[i
];
100 if (c
>= '0' && c
<= '9')
102 else if (c
>= 'a' && c
<= 'f')
104 else if (c
>= 'A' && c
<='F') {
117 if (find_short_object_filename(i
, canonical
, sha1
))
119 if (find_short_packed_object(i
, res
, sha1
))
124 static int get_sha1_file(const char *path
, unsigned char *result
)
127 int fd
= open(path
, O_RDONLY
);
132 len
= read(fd
, buffer
, sizeof(buffer
));
136 return get_sha1_hex(buffer
, result
);
139 static int get_sha1_basic(const char *str
, int len
, unsigned char *sha1
)
141 static const char *prefix
[] = {
151 if (!get_sha1_hex(str
, sha1
))
154 for (p
= prefix
; *p
; p
++) {
155 char *pathname
= git_path("%s/%.*s", *p
, len
, str
);
156 if (!get_sha1_file(pathname
, sha1
))
163 static int get_sha1_1(const char *name
, int len
, unsigned char *sha1
);
165 static int get_parent(const char *name
, int len
,
166 unsigned char *result
, int idx
)
168 unsigned char sha1
[20];
169 int ret
= get_sha1_1(name
, len
, sha1
);
170 struct commit
*commit
;
171 struct commit_list
*p
;
175 commit
= lookup_commit_reference(sha1
);
178 if (parse_commit(commit
))
181 memcpy(result
, commit
->object
.sha1
, 20);
187 memcpy(result
, p
->item
->object
.sha1
, 20);
195 static int get_sha1_1(const char *name
, int len
, unsigned char *sha1
)
199 /* foo^[0-9] or foo^ (== foo^1); we do not do more than 9 parents. */
200 if (len
> 2 && name
[len
-2] == '^' &&
201 name
[len
-1] >= '0' && name
[len
-1] <= '9') {
202 parent
= name
[len
-1] - '0';
205 else if (len
> 1 && name
[len
-1] == '^')
211 ret
= get_parent(name
, len
-1, sha1
, parent
);
215 ret
= get_sha1_basic(name
, len
, sha1
);
218 return get_short_sha1(name
, sha1
);
222 * This is like "get_sha1_basic()", except it allows "sha1 expressions",
223 * notably "xyz^" for "parent of xyz"
225 int get_sha1(const char *name
, unsigned char *sha1
)
227 return get_sha1_1(name
, strlen(name
), sha1
);