X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=write-tree.c;h=bd07da6183b25470b00b9a2eedef29b7275760ec;hb=HEAD;hp=6e531b40a84914cf1b37e12f8629fecbec0ae041;hpb=19b2860cba5742ab31fd682b80fefefac19be141;p=git.git diff --git a/write-tree.c b/write-tree.c index 6e531b40..bd07da61 100644 --- a/write-tree.c +++ b/write-tree.c @@ -4,68 +4,69 @@ * 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=/]"; -#define ORIG_OFFSET (40) /* Enough space to add the header of "tree \0" */ +static struct lock_file lock_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_lock_file_for_update(&lock_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_lock_file(&lock_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; }