static int fetch_pack(const unsigned char *sha1) { struct packed_git *target; char filename[PATH_MAX]; if (setup_indices()) return -1; target = find_sha1_pack(sha1, packs); if (!target) return error("Couldn't find %s: not separate or in any pack", sha1_to_hex(sha1)); if (get_verbosely) { fprintf(stderr, "Getting pack %s\n", sha1_to_hex(target->sha1)); fprintf(stderr, " which contains %s\n", sha1_to_hex(sha1)); } sprintf(filename, "%s/objects/pack/pack-%s.pack", path, sha1_to_hex(target->sha1)); copy_file(filename, sha1_pack_name(target->sha1), sha1_to_hex(target->sha1), 1); sprintf(filename, "%s/objects/pack/pack-%s.idx", path, sha1_to_hex(target->sha1)); copy_file(filename, sha1_pack_index_name(target->sha1), sha1_to_hex(target->sha1), 1); install_packed_git(target); return 0; }
int cmd_pack_redundant(int argc, const char **argv, const char *prefix) { int i; struct pack_list *min, *red, *pl; struct llist *ignore; struct object_id *oid; char buf[GIT_MAX_HEXSZ + 2]; /* hex hash + \n + \0 */ if (argc == 2 && !strcmp(argv[1], "-h")) usage(pack_redundant_usage); for (i = 1; i < argc; i++) { const char *arg = argv[i]; if (!strcmp(arg, "--")) { i++; break; } if (!strcmp(arg, "--all")) { load_all_packs = 1; continue; } if (!strcmp(arg, "--verbose")) { verbose = 1; continue; } if (!strcmp(arg, "--alt-odb")) { alt_odb = 1; continue; } if (*arg == '-') usage(pack_redundant_usage); else break; } if (load_all_packs) load_all(); else while (*(argv + i) != NULL) add_pack_file(*(argv + i++)); if (local_packs == NULL) die("Zero packs found!"); load_all_objects(); cmp_local_packs(); if (alt_odb) scan_alt_odb_packs(); /* ignore objects given on stdin */ llist_init(&ignore); if (!isatty(0)) { while (fgets(buf, sizeof(buf), stdin)) { oid = xmalloc(sizeof(*oid)); if (get_oid_hex(buf, oid)) die("Bad object ID on stdin: %s", buf); llist_insert_sorted_unique(ignore, oid, NULL); } } llist_sorted_difference_inplace(all_objects, ignore); pl = local_packs; while (pl) { llist_sorted_difference_inplace(pl->unique_objects, ignore); pl = pl->next; } minimize(&min); if (verbose) { fprintf(stderr, "There are %lu packs available in alt-odbs.\n", (unsigned long)pack_list_size(altodb_packs)); fprintf(stderr, "The smallest (bytewise) set of packs is:\n"); pl = min; while (pl) { fprintf(stderr, "\t%s\n", pl->pack->pack_name); pl = pl->next; } fprintf(stderr, "containing %lu duplicate objects " "with a total size of %lukb.\n", (unsigned long)get_pack_redundancy(min), (unsigned long)pack_set_bytecount(min)/1024); fprintf(stderr, "A total of %lu unique objects were considered.\n", (unsigned long)all_objects->size); fprintf(stderr, "Redundant packs (with indexes):\n"); } pl = red = pack_list_difference(local_packs, min); while (pl) { printf("%s\n%s\n", sha1_pack_index_name(pl->pack->sha1), pl->pack->pack_name); pl = pl->next; } if (verbose) fprintf(stderr, "%luMB of redundant packs in total.\n", (unsigned long)pack_set_bytecount(red)/(1024*1024)); return 0; }
static int fetch_index(struct walker *walker, struct alt_base *repo, unsigned char *sha1) { char *hex = sha1_to_hex(sha1); char *filename; char *url; char tmpfile[PATH_MAX]; long prev_posn = 0; char range[RANGE_HEADER_SIZE]; struct curl_slist *range_header = NULL; struct walker_data *data = walker->data; FILE *indexfile; struct active_request_slot *slot; struct slot_results results; if (has_pack_index(sha1)) return 0; if (walker->get_verbosely) fprintf(stderr, "Getting index for pack %s\n", hex); url = xmalloc(strlen(repo->base) + 64); sprintf(url, "%s/objects/pack/pack-%s.idx", repo->base, hex); filename = sha1_pack_index_name(sha1); snprintf(tmpfile, sizeof(tmpfile), "%s.temp", filename); indexfile = fopen(tmpfile, "a"); if (!indexfile) return error("Unable to open local file %s for pack index", tmpfile); slot = get_active_slot(); slot->results = &results; curl_easy_setopt(slot->curl, CURLOPT_FILE, indexfile); curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite); curl_easy_setopt(slot->curl, CURLOPT_URL, url); curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, data->no_pragma_header); slot->local = indexfile; /* If there is data present from a previous transfer attempt, resume where it left off */ prev_posn = ftell(indexfile); if (prev_posn>0) { if (walker->get_verbosely) fprintf(stderr, "Resuming fetch of index for pack %s at byte %ld\n", hex, prev_posn); sprintf(range, "Range: bytes=%ld-", prev_posn); range_header = curl_slist_append(range_header, range); curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, range_header); } if (start_active_slot(slot)) { run_active_slot(slot); if (results.curl_result != CURLE_OK) { fclose(indexfile); return error("Unable to get pack index %s\n%s", url, curl_errorstr); } } else { fclose(indexfile); return error("Unable to start request"); } fclose(indexfile); return move_temp_to_file(tmpfile, filename); }