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
, int len
, unsigned char *sha1
)
91 unsigned char res
[20];
96 memset(canonical
, 'x', 40);
97 for (i
= 0; i
< len
;i
++) {
98 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') {
115 if (find_short_object_filename(i
, canonical
, sha1
))
117 if (find_short_packed_object(i
, res
, sha1
))
122 static int get_sha1_basic(const char *str
, int len
, unsigned char *sha1
)
124 static const char *prefix
[] = {
133 if (len
== 40 && !get_sha1_hex(str
, sha1
))
136 for (p
= prefix
; *p
; p
++) {
137 char *pathname
= git_path("%s/%.*s", *p
, len
, str
);
138 if (!read_ref(pathname
, sha1
))
145 static int get_sha1_1(const char *name
, int len
, unsigned char *sha1
);
147 static int get_parent(const char *name
, int len
,
148 unsigned char *result
, int idx
)
150 unsigned char sha1
[20];
151 int ret
= get_sha1_1(name
, len
, sha1
);
152 struct commit
*commit
;
153 struct commit_list
*p
;
157 commit
= lookup_commit_reference(sha1
);
160 if (parse_commit(commit
))
163 memcpy(result
, commit
->object
.sha1
, 20);
169 memcpy(result
, p
->item
->object
.sha1
, 20);
177 static int get_nth_ancestor(const char *name
, int len
,
178 unsigned char *result
, int generation
)
180 unsigned char sha1
[20];
181 int ret
= get_sha1_1(name
, len
, sha1
);
185 while (generation
--) {
186 struct commit
*commit
= lookup_commit_reference(sha1
);
188 if (!commit
|| parse_commit(commit
) || !commit
->parents
)
190 memcpy(sha1
, commit
->parents
->item
->object
.sha1
, 20);
192 memcpy(result
, sha1
, 20);
196 static int get_sha1_1(const char *name
, int len
, unsigned char *sha1
)
201 /* foo^[0-9] or foo^ (== foo^1); we do not do more than 9 parents. */
202 if (len
> 2 && name
[len
-2] == '^' &&
203 name
[len
-1] >= '0' && name
[len
-1] <= '9') {
204 parent
= name
[len
-1] - '0';
207 else if (len
> 1 && name
[len
-1] == '^') {
214 return get_parent(name
, len
, sha1
, parent
);
216 /* "name~3" is "name^^^",
217 * "name~12" is "name^^^^^^^^^^^^", and
218 * "name~" and "name~0" are name -- not "name^0"!
221 for (cp
= name
+ len
- 1; name
<= cp
; cp
--) {
223 if ('0' <= ch
&& ch
<= '9')
229 if (!parent
&& *cp
== '~') {
230 int len1
= cp
- name
;
232 while (cp
< name
+ len
)
233 parent
= parent
* 10 + *cp
++ - '0';
234 return get_nth_ancestor(name
, len1
, sha1
, parent
);
237 ret
= get_sha1_basic(name
, len
, sha1
);
240 return get_short_sha1(name
, len
, sha1
);
244 * This is like "get_sha1_basic()", except it allows "sha1 expressions",
245 * notably "xyz^" for "parent of xyz"
247 int get_sha1(const char *name
, unsigned char *sha1
)
249 return get_sha1_1(name
, strlen(name
), sha1
);