X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=write-tree.c;h=7a4f691d8ab8f6f560685ec6fe71cf2d82e8a018;hb=dd8239f997962d94162790039b008acb6068a242;hp=6e531b40a84914cf1b37e12f8629fecbec0ae041;hpb=19b2860cba5742ab31fd682b80fefefac19be141;p=git.git diff --git a/write-tree.c b/write-tree.c index 6e531b40..7a4f691d 100644 --- a/write-tree.c +++ b/write-tree.c @@ -4,68 +4,56 @@ * 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 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]"; -#define ORIG_OFFSET (40) /* Enough space to add the header of "tree \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; - - 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); + newfd = hold_index_file_for_update(&cache_file, get_index_file()); + entries = read_cache(); + if (argc == 2) { + if (!strcmp(argv[1], "--missing-ok")) + missing_ok = 1; + else + die(write_tree_usage); + } + + if (argc > 2) + die("too many options"); + + if (entries < 0) + die("git-write-tree: error reading cache"); + + if (!active_cache_tree) + active_cache_tree = cache_tree(); + + 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); } - offset += sprintf(buffer + offset, "%o %s", ce->st_mode, ce->name); - buffer[offset++] = 0; - memcpy(buffer + offset, ce->sha1, 20); - offset += 20; + /* 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. + */ } - - i = prepend_integer(buffer, offset - ORIG_OFFSET, ORIG_OFFSET); - i -= 5; - memcpy(buffer+i, "tree ", 5); - - buffer += i; - offset -= i; - - write_sha1_file(buffer, offset); + printf("%s\n", sha1_to_hex(active_cache_tree->sha1)); return 0; }