Skip to content

Commit a4d0cce

Browse files
author
Junio C Hamano
committed
Merge branch 'lt/xsha1'
* lt/xsha1: get_tree_entry(): make it available from tree-walk sha1_name.c: no need to include diff.h; tree-walk.h will do. sha1_name.c: prepare to make get_tree_entry() reusable from others. get_sha1() shorthands for blob/tree objects
2 parents b895076 + 4dcff63 commit a4d0cce

File tree

3 files changed

+67
-1
lines changed

3 files changed

+67
-1
lines changed

sha1_name.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "commit.h"
44
#include "tree.h"
55
#include "blob.h"
6+
#include "tree-walk.h"
67

78
static int find_short_object_filename(int len, const char *name, unsigned char *sha1)
89
{
@@ -455,6 +456,19 @@ static int get_sha1_1(const char *name, int len, unsigned char *sha1)
455456
*/
456457
int get_sha1(const char *name, unsigned char *sha1)
457458
{
459+
int ret;
460+
unsigned unused;
461+
458462
prepare_alt_odb();
459-
return get_sha1_1(name, strlen(name), sha1);
463+
ret = get_sha1_1(name, strlen(name), sha1);
464+
if (ret < 0) {
465+
const char *cp = strchr(name, ':');
466+
if (cp) {
467+
unsigned char tree_sha1[20];
468+
if (!get_sha1_1(name, cp-name, tree_sha1))
469+
return get_tree_entry(tree_sha1, cp+1, sha1,
470+
&unused);
471+
}
472+
}
473+
return ret;
460474
}

tree-walk.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,53 @@ void traverse_trees(int n, struct tree_desc *t, const char *base, traverse_callb
115115
free(entry);
116116
}
117117

118+
static int find_tree_entry(struct tree_desc *t, const char *name, unsigned char *result, unsigned *mode)
119+
{
120+
int namelen = strlen(name);
121+
while (t->size) {
122+
const char *entry;
123+
const unsigned char *sha1;
124+
int entrylen, cmp;
125+
126+
sha1 = tree_entry_extract(t, &entry, mode);
127+
update_tree_entry(t);
128+
entrylen = strlen(entry);
129+
if (entrylen > namelen)
130+
continue;
131+
cmp = memcmp(name, entry, entrylen);
132+
if (cmp > 0)
133+
continue;
134+
if (cmp < 0)
135+
break;
136+
if (entrylen == namelen) {
137+
memcpy(result, sha1, 20);
138+
return 0;
139+
}
140+
if (name[entrylen] != '/')
141+
continue;
142+
if (!S_ISDIR(*mode))
143+
break;
144+
if (++entrylen == namelen) {
145+
memcpy(result, sha1, 20);
146+
return 0;
147+
}
148+
return get_tree_entry(sha1, name + entrylen, result, mode);
149+
}
150+
return -1;
151+
}
152+
153+
int get_tree_entry(const unsigned char *tree_sha1, const char *name, unsigned char *sha1, unsigned *mode)
154+
{
155+
int retval;
156+
void *tree;
157+
struct tree_desc t;
158+
159+
tree = read_object_with_reference(tree_sha1, tree_type, &t.size, NULL);
160+
if (!tree)
161+
return -1;
162+
t.buf = tree;
163+
retval = find_tree_entry(&t, name, sha1, mode);
164+
free(tree);
165+
return retval;
166+
}
167+

tree-walk.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,6 @@ typedef void (*traverse_callback_t)(int n, unsigned long mask, struct name_entry
2222

2323
void traverse_trees(int n, struct tree_desc *t, const char *base, traverse_callback_t callback);
2424

25+
int get_tree_entry(const unsigned char *, const char *, unsigned char *, unsigned *);
26+
2527
#endif

0 commit comments

Comments
 (0)