X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=pack-objects.c;h=caf3b6be5a1cf85bafd034ed9e2cbe3cd596b26c;hb=1e80e0449248edb77b0fb9853f4a3404a599e207;hp=b3e61520339231f6d9a43c545100f4d5f87e0aac;hpb=4ae22d96fe9248dac4f26b1fc91154ba5e879799;p=git.git diff --git a/pack-objects.c b/pack-objects.c index b3e61520..caf3b6be 100644 --- a/pack-objects.c +++ b/pack-objects.c @@ -4,7 +4,7 @@ #include "pack.h" #include "csum-file.h" -static const char pack_usage[] = "git-pack-objects [--local] [--incremental] [--window=N] [--depth=N] {--stdout | base-name} < object-list"; +static const char pack_usage[] = "git-pack-objects [--non-empty] [--local] [--incremental] [--window=N] [--depth=N] {--stdout | base-name} < object-list"; struct object_entry { unsigned char sha1[20]; @@ -400,6 +400,71 @@ static void find_deltas(struct object_entry **list, int window, int depth) free(array); } +static void prepare_pack(int window, int depth) +{ + get_object_details(); + + fprintf(stderr, "Packing %d objects\n", nr_objects); + + sorted_by_type = create_sorted_list(type_size_sort); + if (window && depth) + find_deltas(sorted_by_type, window+1, depth); + write_pack_file(); +} + +static int reuse_cached_pack(unsigned char *sha1, int pack_to_stdout) +{ + static const char cache[] = "pack-cache/pack-%s.%s"; + char *cached_pack, *cached_idx; + int ifd, ofd, ifd_ix = -1; + + cached_pack = git_path(cache, sha1_to_hex(sha1), "pack"); + ifd = open(cached_pack, O_RDONLY); + if (ifd < 0) + return 0; + + if (!pack_to_stdout) { + cached_idx = git_path(cache, sha1_to_hex(sha1), "idx"); + ifd_ix = open(cached_idx, O_RDONLY); + if (ifd_ix < 0) { + close(ifd); + return 0; + } + } + + fprintf(stderr, "Reusing %d objects pack %s\n", nr_objects, + sha1_to_hex(sha1)); + + if (pack_to_stdout) { + if (copy_fd(ifd, 1)) + exit(1); + close(ifd); + } + else { + char name[PATH_MAX]; + snprintf(name, sizeof(name), + "%s-%s.%s", base_name, sha1_to_hex(sha1), "pack"); + ofd = open(name, O_CREAT | O_EXCL | O_WRONLY, 0666); + if (ofd < 0) + die("unable to open %s (%s)", name, strerror(errno)); + if (copy_fd(ifd, ofd)) + exit(1); + close(ifd); + + snprintf(name, sizeof(name), + "%s-%s.%s", base_name, sha1_to_hex(sha1), "idx"); + ofd = open(name, O_CREAT | O_EXCL | O_WRONLY, 0666); + if (ofd < 0) + die("unable to open %s (%s)", name, strerror(errno)); + if (copy_fd(ifd_ix, ofd)) + exit(1); + close(ifd_ix); + puts(sha1_to_hex(sha1)); + } + + return 1; +} + int main(int argc, char **argv) { SHA_CTX ctx; @@ -408,6 +473,8 @@ int main(int argc, char **argv) struct object_entry **list; int i; + setup_git_directory(); + for (i = 1; i < argc; i++) { const char *arg = argv[i]; @@ -459,7 +526,7 @@ int main(int argc, char **argv) unsigned char sha1[20]; if (get_sha1_hex(line, sha1)) - die("expected sha1, got garbage"); + die("expected sha1, got garbage:\n %s", line); hash = 0; p = line+40; while (*p) { @@ -472,9 +539,6 @@ int main(int argc, char **argv) } if (non_empty && !nr_objects) return 0; - get_object_details(); - - fprintf(stderr, "Packing %d objects\n", nr_objects); sorted_by_sha = create_sorted_list(sha1_sort); SHA1_Init(&ctx); @@ -485,14 +549,14 @@ int main(int argc, char **argv) } SHA1_Final(object_list_sha1, &ctx); - sorted_by_type = create_sorted_list(type_size_sort); - if (window && depth) - find_deltas(sorted_by_type, window+1, depth); - - write_pack_file(); - if (!pack_to_stdout) { - write_index_file(); - puts(sha1_to_hex(object_list_sha1)); + if (reuse_cached_pack(object_list_sha1, pack_to_stdout)) + ; + else { + prepare_pack(window, depth); + if (!pack_to_stdout) { + write_index_file(); + puts(sha1_to_hex(object_list_sha1)); + } } return 0; }