2 * GIT - The information manager from hell
4 * Copyright (C) Linus Torvalds, 2005
8 static int check_valid_sha1(unsigned char *sha1
)
10 char *filename
= sha1_file_name(sha1
);
13 /* If we were anal, we'd check that the sha1 of the contents actually matches */
14 ret
= access(filename
, R_OK
);
20 static int prepend_integer(char *buffer
, unsigned val
, int i
)
24 buffer
[--i
] = '0' + (val
% 10);
30 #define ORIG_OFFSET (40) /* Enough space to add the header of "tree <size>\0" */
32 static int write_tree(struct cache_entry
**cachep
, int maxentries
, const char *base
, int baselen
, unsigned char *returnsha1
)
34 unsigned char subdir_sha1
[20];
35 unsigned long size
, offset
;
39 /* Guess at some random initial size */
41 buffer
= malloc(size
);
46 struct cache_entry
*ce
= cachep
[nr
];
47 const char *pathname
= ce
->name
, *filename
, *dirname
;
48 int pathlen
= ce
->namelen
, entrylen
;
52 /* Did we hit the end of the directory? Return how many we wrote */
53 if (baselen
>= pathlen
|| memcmp(base
, pathname
, baselen
))
59 /* Do we have _further_ subdirectories? */
60 filename
= pathname
+ baselen
;
61 dirname
= strchr(filename
, '/');
65 subdir_written
= write_tree(cachep
+ nr
, maxentries
- nr
, pathname
, dirname
-pathname
+1, subdir_sha1
);
66 fprintf(stderr
, "Wrote %d entries from subdirectory '%.*s'\n",
67 subdir_written
, dirname
-pathname
, pathname
);
70 /* Now we need to write out the directory entry into this tree.. */
72 pathlen
= dirname
- pathname
;
74 /* ..but the directory entry doesn't count towards the total count */
79 if (check_valid_sha1(sha1
) < 0)
82 entrylen
= pathlen
- baselen
;
83 if (offset
+ entrylen
+ 100 > size
) {
84 size
= alloc_nr(offset
+ entrylen
+ 100);
85 buffer
= realloc(buffer
, size
);
87 offset
+= sprintf(buffer
+ offset
, "%o %.*s", mode
, entrylen
, filename
);
89 memcpy(buffer
+ offset
, sha1
, 20);
92 } while (nr
< maxentries
);
94 i
= prepend_integer(buffer
, offset
- ORIG_OFFSET
, ORIG_OFFSET
);
96 memcpy(buffer
+i
, "tree ", 5);
101 write_sha1_file(buffer
, offset
, returnsha1
);
105 int main(int argc
, char **argv
)
107 int entries
= read_cache();
108 unsigned char sha1
[20];
111 usage("no cache contents to write");
112 if (write_tree(active_cache
, entries
, "", 0, sha1
) != entries
)
113 usage("write-tree: internal error");
114 printf("%s\n", sha1_to_hex(sha1
));