Skip to content

Commit 83adac3

Browse files
author
Linus Torvalds
committed
Make "read-tree" read the tree into the current directory cache.
It will no longer update the actual working directory, just the cache. To update the working directory, you need to use "checkout-cache".
1 parent 197ee8c commit 83adac3

File tree

2 files changed

+82
-50
lines changed

2 files changed

+82
-50
lines changed

checkout-cache.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,34 @@
3636

3737
static int force = 0, quiet = 0;
3838

39+
static void create_directories(const char *path)
40+
{
41+
int len = strlen(path);
42+
char *buf = malloc(len + 1);
43+
const char *slash = path;
44+
45+
while ((slash = strchr(slash+1, '/')) != NULL) {
46+
len = slash - path;
47+
memcpy(buf, path, len);
48+
buf[len] = 0;
49+
mkdir(buf, 0700);
50+
}
51+
}
52+
53+
static int create_file(const char *path, unsigned int mode)
54+
{
55+
int fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0600);
56+
if (fd < 0) {
57+
if (errno == ENOENT) {
58+
create_directories(path);
59+
fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0600);
60+
}
61+
}
62+
if (fd >= 0)
63+
fchmod(fd, mode);
64+
return fd;
65+
}
66+
3967
static int write_entry(struct cache_entry *ce)
4068
{
4169
int fd;
@@ -50,7 +78,7 @@ static int write_entry(struct cache_entry *ce)
5078
ce->name, sha1_to_hex(ce->sha1));
5179
return -1;
5280
}
53-
fd = open(ce->name, O_WRONLY | O_CREAT | O_TRUNC, 0600);
81+
fd = create_file(ce->name, ce->st_mode);
5482
if (fd < 0) {
5583
fprintf(stderr, "checkout-cache: unable to create %s (%s)\n",
5684
ce->name, strerror(errno));

read-tree.c

Lines changed: 53 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,83 +5,87 @@
55
*/
66
#include "cache.h"
77

8-
static void create_directories(const char *path)
8+
static int read_one_entry(unsigned char *sha1, const char *pathname, unsigned mode)
99
{
10-
int len = strlen(path);
11-
char *buf = malloc(len + 1);
12-
const char *slash = path;
10+
int len = strlen(pathname);
11+
unsigned int size = cache_entry_size(len);
12+
struct cache_entry *ce = malloc(size);
1313

14-
while ((slash = strchr(slash+1, '/')) != NULL) {
15-
len = slash - path;
16-
memcpy(buf, path, len);
17-
buf[len] = 0;
18-
mkdir(buf, 0700);
19-
}
20-
}
14+
memset(ce, 0, size);
2115

22-
static int create_file(const char *path)
23-
{
24-
int fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0600);
25-
if (fd < 0) {
26-
if (errno == ENOENT) {
27-
create_directories(path);
28-
fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0600);
29-
}
30-
}
31-
return fd;
16+
ce->st_mode = mode;
17+
ce->namelen = len;
18+
memcpy(ce->name, pathname, len+1);
19+
memcpy(ce->sha1, sha1, 20);
20+
return add_cache_entry(ce);
3221
}
3322

34-
static int unpack(unsigned char *sha1)
23+
static int read_tree(unsigned char *sha1)
3524
{
3625
void *buffer;
3726
unsigned long size;
3827
char type[20];
3928

4029
buffer = read_sha1_file(sha1, type, &size);
4130
if (!buffer)
42-
usage("unable to read sha1 file");
31+
return -1;
4332
if (strcmp(type, "tree"))
44-
usage("expected a 'tree' node");
33+
return -1;
4534
while (size) {
4635
int len = strlen(buffer)+1;
4736
unsigned char *sha1 = buffer + len;
4837
char *path = strchr(buffer, ' ')+1;
49-
char *data;
50-
unsigned long filesize;
5138
unsigned int mode;
52-
int fd;
5339

5440
if (size < len + 20 || sscanf(buffer, "%o", &mode) != 1)
55-
usage("corrupt 'tree' file");
41+
return -1;
42+
5643
buffer = sha1 + 20;
5744
size -= len + 20;
58-
data = read_sha1_file(sha1, type, &filesize);
59-
if (!data || strcmp(type, "blob"))
60-
usage("tree file refers to bad file data");
61-
fd = create_file(path);
62-
if (fd < 0)
63-
usage("unable to create file");
64-
if (write(fd, data, filesize) != filesize)
65-
usage("unable to write file");
66-
fchmod(fd, mode);
67-
close(fd);
68-
free(data);
45+
46+
if (read_one_entry(sha1, path, mode) < 0)
47+
return -1;
6948
}
7049
return 0;
7150
}
7251

7352
int main(int argc, char **argv)
7453
{
54+
int i, newfd;
7555
unsigned char sha1[20];
7656

77-
if (argc != 2)
78-
usage("read-tree <key>");
79-
if (get_sha1_hex(argv[1], sha1) < 0)
80-
usage("read-tree <key>");
81-
sha1_file_directory = getenv(DB_ENVIRONMENT);
82-
if (!sha1_file_directory)
83-
sha1_file_directory = DEFAULT_DB_ENVIRONMENT;
84-
if (unpack(sha1) < 0)
85-
usage("unpack failed");
86-
return 0;
57+
newfd = open(".dircache/index.lock", O_RDWR | O_CREAT | O_EXCL, 0600);
58+
if (newfd < 0)
59+
usage("unable to create new cachefile");
60+
61+
for (i = 1; i < argc; i++) {
62+
const char *arg = argv[i];
63+
64+
/* "-m" stands for "merge" current directory cache */
65+
if (!strcmp(arg, "-m")) {
66+
if (active_cache) {
67+
fprintf(stderr, "read-tree: cannot merge old cache on top of new\n");
68+
goto out;
69+
}
70+
if (read_cache() < 0) {
71+
fprintf(stderr, "read-tree: corrupt directory cache\n");
72+
goto out;
73+
}
74+
continue;
75+
}
76+
if (get_sha1_hex(arg, sha1) < 0) {
77+
fprintf(stderr, "read-tree [-m] <sha1>\n");
78+
goto out;
79+
}
80+
if (read_tree(sha1) < 0) {
81+
fprintf(stderr, "failed to unpack tree object %s\n", arg);
82+
goto out;
83+
}
84+
}
85+
if (!write_cache(newfd, active_cache, active_nr) && !rename(".dircache/index.lock", ".dircache/index"))
86+
return 0;
87+
88+
out:
89+
unlink(".dircache/index.lock");
90+
exit(1);
8791
}

0 commit comments

Comments
 (0)