Skip to content

Commit 94537c7

Browse files
author
Linus Torvalds
committed
Move "read_tree()" to "tree.c" to be used as a generic helper function.
Next step: make "diff-cache" use it.
1 parent aba0668 commit 94537c7

File tree

3 files changed

+71
-63
lines changed

3 files changed

+71
-63
lines changed

cache.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ extern void * read_sha1_file(const unsigned char *sha1, char *type, unsigned lon
122122
extern int write_sha1_file(char *buf, unsigned len, unsigned char *return_sha1);
123123
extern int check_sha1_signature(unsigned char *sha1, void *buf, unsigned long size, const char *type);
124124

125+
/* Read a tree into the cache */
126+
extern int read_tree(void *buffer, unsigned long size, int stage);
127+
125128
/* Convert to/from hex/sha1 representation */
126129
extern int get_sha1_hex(const char *hex, unsigned char *sha1);
127130
extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */

read-tree.c

Lines changed: 3 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -7,75 +7,15 @@
77

88
static int stage = 0;
99

10-
static int read_one_entry(unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode)
11-
{
12-
int len = strlen(pathname);
13-
unsigned int size = cache_entry_size(baselen + len);
14-
struct cache_entry *ce = malloc(size);
15-
16-
memset(ce, 0, size);
17-
18-
ce->ce_mode = create_ce_mode(mode);
19-
ce->ce_flags = create_ce_flags(baselen + len, stage);
20-
memcpy(ce->name, base, baselen);
21-
memcpy(ce->name + baselen, pathname, len+1);
22-
memcpy(ce->sha1, sha1, 20);
23-
return add_cache_entry(ce, 1);
24-
}
25-
26-
static int read_tree_recursive(void *buffer, unsigned long size,
27-
const char *base, int baselen)
28-
{
29-
while (size) {
30-
int len = strlen(buffer)+1;
31-
unsigned char *sha1 = buffer + len;
32-
char *path = strchr(buffer, ' ')+1;
33-
unsigned int mode;
34-
35-
if (size < len + 20 || sscanf(buffer, "%o", &mode) != 1)
36-
return -1;
37-
38-
buffer = sha1 + 20;
39-
size -= len + 20;
40-
41-
if (S_ISDIR(mode)) {
42-
int retval;
43-
int pathlen = strlen(path);
44-
char *newbase = malloc(baselen + 1 + pathlen);
45-
void *eltbuf;
46-
char elttype[20];
47-
unsigned long eltsize;
48-
49-
eltbuf = read_sha1_file(sha1, elttype, &eltsize);
50-
if (!eltbuf || strcmp(elttype, "tree"))
51-
return -1;
52-
memcpy(newbase, base, baselen);
53-
memcpy(newbase + baselen, path, pathlen);
54-
newbase[baselen + pathlen] = '/';
55-
retval = read_tree_recursive(eltbuf, eltsize,
56-
newbase,
57-
baselen + pathlen + 1);
58-
free(eltbuf);
59-
free(newbase);
60-
if (retval)
61-
return -1;
62-
continue;
63-
}
64-
if (read_one_entry(sha1, base, baselen, path, mode) < 0)
65-
return -1;
66-
}
67-
return 0;
68-
}
69-
70-
static int read_tree(unsigned char *sha1, const char *base, int baselen)
10+
static int unpack_tree(unsigned char *sha1)
7111
{
7212
void *buffer;
7313
unsigned long size;
7414

7515
buffer = read_tree_with_tree_or_commit_sha1(sha1, &size, 0);
7616
if (!buffer)
7717
return -1;
78-
return read_tree_recursive(buffer, size, base, baselen);
18+
return read_tree(buffer, size, stage);
7919
}
8020

8121
static char *lockfile_name;
@@ -255,7 +195,7 @@ int main(int argc, char **argv)
255195
usage(read_tree_usage);
256196
if (stage > 3)
257197
usage(read_tree_usage);
258-
if (read_tree(sha1, "", 0) < 0)
198+
if (unpack_tree(sha1) < 0)
259199
die("failed to unpack tree object %s", arg);
260200
stage++;
261201
}

tree.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,71 @@
55

66
const char *tree_type = "tree";
77

8+
static int read_one_entry(unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage)
9+
{
10+
int len = strlen(pathname);
11+
unsigned int size = cache_entry_size(baselen + len);
12+
struct cache_entry *ce = malloc(size);
13+
14+
memset(ce, 0, size);
15+
16+
ce->ce_mode = create_ce_mode(mode);
17+
ce->ce_flags = create_ce_flags(baselen + len, stage);
18+
memcpy(ce->name, base, baselen);
19+
memcpy(ce->name + baselen, pathname, len+1);
20+
memcpy(ce->sha1, sha1, 20);
21+
return add_cache_entry(ce, 1);
22+
}
23+
24+
static int read_tree_recursive(void *buffer, unsigned long size,
25+
const char *base, int baselen, int stage)
26+
{
27+
while (size) {
28+
int len = strlen(buffer)+1;
29+
unsigned char *sha1 = buffer + len;
30+
char *path = strchr(buffer, ' ')+1;
31+
unsigned int mode;
32+
33+
if (size < len + 20 || sscanf(buffer, "%o", &mode) != 1)
34+
return -1;
35+
36+
buffer = sha1 + 20;
37+
size -= len + 20;
38+
39+
if (S_ISDIR(mode)) {
40+
int retval;
41+
int pathlen = strlen(path);
42+
char *newbase = malloc(baselen + 1 + pathlen);
43+
void *eltbuf;
44+
char elttype[20];
45+
unsigned long eltsize;
46+
47+
eltbuf = read_sha1_file(sha1, elttype, &eltsize);
48+
if (!eltbuf || strcmp(elttype, "tree"))
49+
return -1;
50+
memcpy(newbase, base, baselen);
51+
memcpy(newbase + baselen, path, pathlen);
52+
newbase[baselen + pathlen] = '/';
53+
retval = read_tree_recursive(eltbuf, eltsize,
54+
newbase,
55+
baselen + pathlen + 1, stage);
56+
free(eltbuf);
57+
free(newbase);
58+
if (retval)
59+
return -1;
60+
continue;
61+
}
62+
if (read_one_entry(sha1, base, baselen, path, mode, stage) < 0)
63+
return -1;
64+
}
65+
return 0;
66+
}
67+
68+
int read_tree(void *buffer, unsigned long size, int stage)
69+
{
70+
return read_tree_recursive(buffer, size, "", 0, stage);
71+
}
72+
873
struct tree *lookup_tree(unsigned char *sha1)
974
{
1075
struct object *obj = lookup_object(sha1);

0 commit comments

Comments
 (0)