]> rtime.felk.cvut.cz Git - git.git/commitdiff
Merge branch 'bc/maint-keep-pack' into maint
authorJunio C Hamano <gitster@pobox.com>
Wed, 3 Dec 2008 07:00:04 +0000 (23:00 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 3 Dec 2008 07:00:04 +0000 (23:00 -0800)
* 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

1  2 
builtin-pack-objects.c
cache.h
sha1_file.c

diff --combined builtin-pack-objects.c
index 8fe51244e069da96b669c260a37f4b7cf831026f,85bd795d3b811aaba42aa1165c30137b8a6105e8..4411a480c1067f6841181e838ffba54edbec823f
@@@ -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) {
                                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 3960931a9559e9f292f4ea4f01488f7294057148,7595c149ea10aa847f01235a2c1ca17129d43fe4..d1cd6aaf738f94930b94ebbee303fc267064e2ac
+++ 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 4e05429aba880a5d6672cf3fc2033e872798e970,0203de5855cde2de6268ffb0ec90985490080ece..c35469d488596bd1279c06bc391d744565f35e59
@@@ -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));