From: Junio C Hamano Date: Wed, 3 Dec 2008 07:00:04 +0000 (-0800) Subject: Merge branch 'bc/maint-keep-pack' into maint X-Git-Tag: v1.6.0.5~8 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/0fd9d7e66deb7071da2a568b96c94f94ee890908?ds=inline;hp=-c Merge branch 'bc/maint-keep-pack' into maint * bc/maint-keep-pack: repack: only unpack-unreachable if we are deleting redundant packs t7700: test that 'repack -a' packs alternate packed objects pack-objects: extend --local to mean ignore non-local loose objects too sha1_file.c: split has_loose_object() into local and non-local counterparts t7700: demonstrate mishandling of loose objects in an alternate ODB builtin-gc.c: use new pack_keep bitfield to detect .keep file existence repack: do not fall back to incremental repacking with [-a|-A] repack: don't repack local objects in packs with .keep file pack-objects: new option --honor-pack-keep packed_git: convert pack_local flag into a bitfield and add pack_keep t7700: demonstrate mishandling of objects in packs with a .keep file --- 0fd9d7e66deb7071da2a568b96c94f94ee890908 diff --combined builtin-pack-objects.c index 8fe51244e0,85bd795d3b..4411a480c1 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@@ -71,6 -71,7 +71,7 @@@ static int reuse_delta = 1, reuse_objec static int keep_unreachable, unpack_unreachable, include_tag; static int local; static int incremental; + static int ignore_packed_keep; static int allow_ofs_delta; static const char *base_name; static int progress = 1; @@@ -245,16 -246,8 +246,16 @@@ static unsigned long write_object(struc type = entry->type; /* write limit if limited packsize and not first object */ - limit = pack_size_limit && nr_written ? - pack_size_limit - write_offset : 0; + if (!pack_size_limit || !nr_written) + limit = 0; + else if (pack_size_limit <= write_offset) + /* + * the earlier object did not fit the limit; avoid + * mistaking this with unlimited (i.e. limit = 0). + */ + limit = 1; + else + limit = pack_size_limit - write_offset; if (!entry->delta) usable_delta = 0; /* no delta */ @@@ -698,6 -691,9 +699,9 @@@ static int add_object_entry(const unsig return 0; } + if (!exclude && local && has_loose_object_nonlocal(sha1)) + return 0; + for (p = packed_git; p; p = p->next) { off_t offset = find_pack_entry_one(sha1, p); if (offset) { @@@ -711,6 -707,8 +715,8 @@@ return 0; if (local && !p->pack_local) return 0; + if (ignore_packed_keep && p->pack_local && p->pack_keep) + return 0; } } @@@ -2050,6 -2048,10 +2056,10 @@@ int cmd_pack_objects(int argc, const ch incremental = 1; continue; } + if (!strcmp("--honor-pack-keep", arg)) { + ignore_packed_keep = 1; + continue; + } if (!prefixcmp(arg, "--compression=")) { char *end; int level = strtoul(arg+14, &end, 0); diff --combined cache.h index 3960931a95,7595c149ea..d1cd6aaf73 --- a/cache.h +++ b/cache.h @@@ -255,7 -255,6 +255,7 @@@ static inline void remove_name_hash(str #define read_cache() read_index(&the_index) #define read_cache_from(path) read_index_from(&the_index, (path)) +#define is_cache_unborn() is_index_unborn(&the_index) #define read_cache_unmerged() read_index_unmerged(&the_index) #define write_cache(newfd, cache, entries) write_index(&the_index, (newfd)) #define discard_cache() discard_index(&the_index) @@@ -361,7 -360,6 +361,7 @@@ extern int init_db(const char *template /* Initialize and use the cache information */ extern int read_index(struct index_state *); extern int read_index_from(struct index_state *, const char *path); +extern int is_index_unborn(struct index_state *); extern int read_index_unmerged(struct index_state *); extern int write_index(const struct index_state *, int newfd); extern int discard_index(struct index_state *); @@@ -567,6 -565,7 +567,7 @@@ extern int move_temp_to_file(const cha extern int has_sha1_pack(const unsigned char *sha1, const char **ignore); extern int has_sha1_file(const unsigned char *sha1); + extern int has_loose_object_nonlocal(const unsigned char *sha1); extern int has_pack_file(const unsigned char *sha1); extern int has_pack_index(const unsigned char *sha1); @@@ -673,7 -672,8 +674,8 @@@ extern struct packed_git int index_version; time_t mtime; int pack_fd; - int pack_local; + unsigned pack_local:1, + pack_keep:1; unsigned char sha1[20]; /* something like ".git/objects/pack/xxxxx.pack" */ char pack_name[FLEX_ARRAY]; /* more */ diff --combined sha1_file.c index 4e05429aba,0203de5855..c35469d488 --- a/sha1_file.c +++ b/sha1_file.c @@@ -410,23 -410,30 +410,30 @@@ void prepare_alt_odb(void read_info_alternates(get_object_directory(), 0); } - static int has_loose_object(const unsigned char *sha1) + static int has_loose_object_local(const unsigned char *sha1) { char *name = sha1_file_name(sha1); - struct alternate_object_database *alt; + return !access(name, F_OK); + } - if (!access(name, F_OK)) - return 1; + int has_loose_object_nonlocal(const unsigned char *sha1) + { + struct alternate_object_database *alt; prepare_alt_odb(); for (alt = alt_odb_list; alt; alt = alt->next) { - name = alt->name; - fill_sha1_path(name, sha1); + fill_sha1_path(alt->name, sha1); if (!access(alt->base, F_OK)) return 1; } return 0; } + static int has_loose_object(const unsigned char *sha1) + { + return has_loose_object_local(sha1) || + has_loose_object_nonlocal(sha1); + } + static unsigned int pack_used_ctr; static unsigned int pack_mmap_calls; static unsigned int peak_pack_open_windows; @@@ -828,6 -835,11 +835,11 @@@ struct packed_git *add_packed_git(cons return NULL; } memcpy(p->pack_name, path, path_len); + + strcpy(p->pack_name + path_len, ".keep"); + if (!access(p->pack_name, F_OK)) + p->pack_keep = 1; + strcpy(p->pack_name + path_len, ".pack"); if (stat(p->pack_name, &st) || !S_ISREG(st.st_mode)) { free(p); @@@ -2220,7 -2232,7 +2232,7 @@@ static int create_tmpfile(char *buffer memcpy(buffer, filename, dirlen); strcpy(buffer + dirlen, "tmp_obj_XXXXXX"); fd = mkstemp(buffer); - if (fd < 0 && dirlen) { + if (fd < 0 && dirlen && errno == ENOENT) { /* Make sure the directory exists */ memcpy(buffer, filename, dirlen); buffer[dirlen-1] = 0; @@@ -2246,7 -2258,7 +2258,7 @@@ static int write_loose_object(const uns filename = sha1_file_name(sha1); fd = create_tmpfile(tmpfile, sizeof(tmpfile), filename); if (fd < 0) { - if (errno == EPERM) + if (errno == EACCES) return error("insufficient permission for adding an object to repository database %s\n", get_object_directory()); else return error("unable to create temporary sha1 filename %s: %s\n", tmpfile, strerror(errno));