* Copyright (C) Linus Torvalds, 2005
*/
#include "cache.h"
+#include "tree.h"
+#include "cache-tree.h"
-static int check_valid_sha1(unsigned char *sha1)
-{
- char *filename = sha1_file_name(sha1);
- int ret;
-
- /* If we were anal, we'd check that the sha1 of the contents actually matches */
- ret = access(filename, R_OK);
- if (ret)
- perror(filename);
- return ret;
-}
+static int missing_ok = 0;
+static char *prefix = NULL;
-static int prepend_integer(char *buffer, unsigned val, int i)
-{
- buffer[--i] = '\0';
- do {
- buffer[--i] = '0' + (val % 10);
- val /= 10;
- } while (val);
- return i;
-}
+static const char write_tree_usage[] =
+"git-write-tree [--missing-ok] [--prefix=<prefix>/]";
-#define ORIG_OFFSET (40) /* Enough space to add the header of "tree <size>\0" */
+static struct cache_file cache_file;
int main(int argc, char **argv)
{
- unsigned long size, offset;
- int i, entries = read_cache();
- char *buffer;
+ int entries, was_valid, newfd;
- if (entries <= 0) {
- fprintf(stderr, "No file-cache to create a tree of\n");
- exit(1);
- }
+ setup_git_directory();
- /* Guess at an initial size */
- size = entries * 40 + 400;
- buffer = malloc(size);
- offset = ORIG_OFFSET;
+ newfd = hold_index_file_for_update(&cache_file, get_index_file());
+ entries = read_cache();
- for (i = 0; i < entries; i++) {
- struct cache_entry *ce = active_cache[i];
- if (check_valid_sha1(ce->sha1) < 0)
- exit(1);
- if (offset + ce->namelen + 60 > size) {
- size = alloc_nr(offset + ce->namelen + 60);
- buffer = realloc(buffer, size);
- }
- offset += sprintf(buffer + offset, "%o %s", ce->st_mode, ce->name);
- buffer[offset++] = 0;
- memcpy(buffer + offset, ce->sha1, 20);
- offset += 20;
+ while (1 < argc) {
+ char *arg = argv[1];
+ if (!strcmp(arg, "--missing-ok"))
+ missing_ok = 1;
+ else if (!strncmp(arg, "--prefix=", 9))
+ prefix = arg + 9;
+ else
+ die(write_tree_usage);
+ argc--; argv++;
}
- i = prepend_integer(buffer, offset - ORIG_OFFSET, ORIG_OFFSET);
- i -= 5;
- memcpy(buffer+i, "tree ", 5);
+ if (argc > 2)
+ die("too many options");
+
+ if (entries < 0)
+ die("git-write-tree: error reading cache");
- buffer += i;
- offset -= i;
+ if (!active_cache_tree)
+ active_cache_tree = cache_tree();
- write_sha1_file(buffer, offset);
+ was_valid = cache_tree_fully_valid(active_cache_tree);
+ if (!was_valid) {
+ if (cache_tree_update(active_cache_tree,
+ active_cache, active_nr,
+ missing_ok, 0) < 0)
+ die("git-write-tree: error building trees");
+ if (0 <= newfd) {
+ if (!write_cache(newfd, active_cache, active_nr))
+ commit_index_file(&cache_file);
+ }
+ /* Not being able to write is fine -- we are only interested
+ * in updating the cache-tree part, and if the next caller
+ * ends up using the old index with unupdated cache-tree part
+ * it misses the work we did here, but that is just a
+ * performance penalty and not a big deal.
+ */
+ }
+ if (prefix) {
+ struct cache_tree *subtree =
+ cache_tree_find(active_cache_tree, prefix);
+ printf("%s\n", sha1_to_hex(subtree->sha1));
+ }
+ else
+ printf("%s\n", sha1_to_hex(active_cache_tree->sha1));
return 0;
}