Initial revision of "git", the information manager from hell
[git/git.git] / write-tree.c
CommitLineData
e83c5163
LT
1#include "cache.h"
2
3static int check_valid_sha1(unsigned char *sha1)
4{
5 char *filename = sha1_file_name(sha1);
6 int ret;
7
8 /* If we were anal, we'd check that the sha1 of the contents actually matches */
9 ret = access(filename, R_OK);
10 if (ret)
11 perror(filename);
12 return ret;
13}
14
15static int prepend_integer(char *buffer, unsigned val, int i)
16{
17 buffer[--i] = '\0';
18 do {
19 buffer[--i] = '0' + (val % 10);
20 val /= 10;
21 } while (val);
22 return i;
23}
24
25#define ORIG_OFFSET (40) /* Enough space to add the header of "tree <size>\0" */
26
27int main(int argc, char **argv)
28{
29 unsigned long size, offset, val;
30 int i, entries = read_cache();
31 char *buffer;
32
33 if (entries <= 0) {
34 fprintf(stderr, "No file-cache to create a tree of\n");
35 exit(1);
36 }
37
38 /* Guess at an initial size */
39 size = entries * 40 + 400;
40 buffer = malloc(size);
41 offset = ORIG_OFFSET;
42
43 for (i = 0; i < entries; i++) {
44 struct cache_entry *ce = active_cache[i];
45 if (check_valid_sha1(ce->sha1) < 0)
46 exit(1);
47 if (offset + ce->namelen + 60 > size) {
48 size = alloc_nr(offset + ce->namelen + 60);
49 buffer = realloc(buffer, size);
50 }
51 offset += sprintf(buffer + offset, "%o %s", ce->st_mode, ce->name);
52 buffer[offset++] = 0;
53 memcpy(buffer + offset, ce->sha1, 20);
54 offset += 20;
55 }
56
57 i = prepend_integer(buffer, offset - ORIG_OFFSET, ORIG_OFFSET);
58 i -= 5;
59 memcpy(buffer+i, "tree ", 5);
60
61 buffer += i;
62 offset -= i;
63
64 write_sha1_file(buffer, offset);
65 return 0;
66}