Code

Merge branch 'jk/maint-pack-objects-compete-with-delete'
authorJunio C Hamano <gitster@pobox.com>
Fri, 21 Oct 2011 23:04:33 +0000 (16:04 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 21 Oct 2011 23:04:33 +0000 (16:04 -0700)
* jk/maint-pack-objects-compete-with-delete:
  downgrade "packfile cannot be accessed" errors to warnings
  pack-objects: protect against disappearing packs

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

diff --combined builtin/pack-objects.c
index 2b18de5dc37bf849dbdbc892e4e9f3a34893dd9d,c31bcd01e8e220e3c60dac7f3d756395ff7823a6..ba3705d1de0d91714be4c967a26ffd263e09878c
@@@ -804,6 -804,10 +804,10 @@@ static int add_object_entry(const unsig
                off_t offset = find_pack_entry_one(sha1, p);
                if (offset) {
                        if (!found_pack) {
+                               if (!is_pack_valid(p)) {
+                                       warning("packfile %s cannot be accessed", p->pack_name);
+                                       continue;
+                               }
                                found_offset = offset;
                                found_pack = p;
                        }
@@@ -2073,9 -2077,7 +2077,9 @@@ static void show_commit(struct commit *
        commit->object.flags |= OBJECT_ADDED;
  }
  
 -static void show_object(struct object *obj, const struct name_path *path, const char *last)
 +static void show_object(struct object *obj,
 +                      const struct name_path *path, const char *last,
 +                      void *data)
  {
        char *name = path_name(path, last);
  
diff --combined cache.h
index 42884ec62c1e920f4aa65693c0efd773c1bc94cf,a723670c870346db19a636612cc460f323234eae..2e6ad3604e4cc6efd60a69407159967a1940e680
+++ b/cache.h
@@@ -168,7 -168,6 +168,7 @@@ struct cache_entry 
        unsigned int ce_flags;
        unsigned char sha1[20];
        struct cache_entry *next;
 +      struct cache_entry *dir_next;
        char name[FLEX_ARRAY]; /* more */
  };
  
@@@ -440,12 -439,12 +440,12 @@@ extern const char *get_git_namespace(vo
  extern const char *strip_namespace(const char *namespaced_ref);
  extern const char *get_git_work_tree(void);
  extern const char *read_gitfile(const char *path);
 +extern const char *resolve_gitdir(const char *suspect);
  extern void set_git_work_tree(const char *tree);
  
  #define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
  
  extern const char **get_pathspec(const char *prefix, const char **pathspec);
 -extern const char *pathspec_prefix(const char *prefix, const char **pathspec);
  extern void setup_work_tree(void);
  extern const char *setup_git_directory_gently(int *);
  extern const char *setup_git_directory(void);
@@@ -590,7 -589,6 +590,7 @@@ extern int warn_ambiguous_refs
  extern int shared_repository;
  extern const char *apply_default_whitespace;
  extern const char *apply_default_ignorewhitespace;
 +extern const char *git_attributes_file;
  extern int zlib_compression_level;
  extern int core_compression_level;
  extern int core_compression_seen;
@@@ -736,7 -734,7 +736,7 @@@ int safe_create_leading_directories(cha
  int safe_create_leading_directories_const(const char *path);
  int mkdir_in_gitdir(const char *path);
  extern char *expand_user_path(const char *path);
 -char *enter_repo(char *path, int strict);
 +const char *enter_repo(const char *path, int strict);
  static inline int is_absolute_path(const char *path)
  {
        return is_dir_sep(path[0]) || has_dos_drive_prefix(path);
@@@ -821,51 -819,10 +821,51 @@@ static inline int get_sha1_with_context
  {
        return get_sha1_with_context_1(str, sha1, orc, 0, NULL);
  }
 +
 +/*
 + * Try to read a SHA1 in hexadecimal format from the 40 characters
 + * starting at hex.  Write the 20-byte result to sha1 in binary form.
 + * Return 0 on success.  Reading stops if a NUL is encountered in the
 + * input, so it is safe to pass this function an arbitrary
 + * null-terminated string.
 + */
  extern int get_sha1_hex(const char *hex, unsigned char *sha1);
 +
  extern char *sha1_to_hex(const unsigned char *sha1);  /* static buffer result! */
  extern int read_ref(const char *filename, unsigned char *sha1);
 -extern const char *resolve_ref(const char *path, unsigned char *sha1, int, int *);
 +
 +/*
 + * Resolve a reference, recursively following symbolic refererences.
 + *
 + * Store the referred-to object's name in sha1 and return the name of
 + * the non-symbolic reference that ultimately pointed at it.  The
 + * return value, if not NULL, is a pointer into either a static buffer
 + * or the input ref.
 + *
 + * If the reference cannot be resolved to an object, the behavior
 + * depends on the "reading" argument:
 + *
 + * - If reading is set, return NULL.
 + *
 + * - If reading is not set, clear sha1 and return the name of the last
 + *   reference name in the chain, which will either be a non-symbolic
 + *   reference or an undefined reference.  If this is a prelude to
 + *   "writing" to the ref, the return value is the name of the ref
 + *   that will actually be created or changed.
 + *
 + * If flag is non-NULL, set the value that it points to the
 + * combination of REF_ISPACKED (if the reference was found among the
 + * packed references) and REF_ISSYMREF (if the initial reference was a
 + * symbolic reference).
 + *
 + * If ref is not a properly-formatted, normalized reference, return
 + * NULL.  If more than MAXDEPTH recursive symbolic lookups are needed,
 + * give up and return NULL.
 + *
 + * errno is sometimes set on errors, but not always.
 + */
 +extern const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *flag);
 +
  extern int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref);
  extern int dwim_log(const char *str, int len, unsigned char *sha1, char **ref);
  extern int interpret_branch_name(const char *str, struct strbuf *);
@@@ -1057,6 -1014,7 +1057,7 @@@ extern struct packed_git *add_packed_gi
  extern const unsigned char *nth_packed_object_sha1(struct packed_git *, uint32_t);
  extern off_t nth_packed_object_offset(const struct packed_git *, uint32_t);
  extern off_t find_pack_entry_one(const unsigned char *, struct packed_git *);
+ extern int is_pack_valid(struct packed_git *);
  extern void *unpack_entry(struct packed_git *, off_t, enum object_type *, unsigned long *);
  extern unsigned long unpack_object_header_buffer(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep);
  extern unsigned long get_size_from_delta(struct packed_git *, struct pack_window **, off_t);
@@@ -1119,11 -1077,9 +1120,11 @@@ extern int git_config_bool(const char *
  extern int git_config_maybe_bool(const char *, const char *);
  extern int git_config_string(const char **, const char *, const char *);
  extern int git_config_pathname(const char **, const char *, const char *);
 +extern int git_config_set_in_file(const char *, const char *, const char *);
  extern int git_config_set(const char *, const char *);
  extern int git_config_parse_key(const char *, char **, int *);
  extern int git_config_set_multivar(const char *, const char *, const char *, int);
 +extern int git_config_set_multivar_in_file(const char *, const char *, const char *, const char *, int);
  extern int git_config_rename_section(const char *, const char *);
  extern const char *git_etc_gitconfig(void);
  extern int check_repository_format_version(const char *var, const char *value, void *cb);
diff --combined sha1_file.c
index 34013014442e18bd02ae0ce33df34a89ec8d6171,cad1f22002d87c3bb015917c3f8d3292c1451639..27f3b9b278a97f66f92ca61a2bc39e30f0a70317
@@@ -248,30 -248,27 +248,30 @@@ static int link_alt_odb_entry(const cha
        const char *objdir = get_object_directory();
        struct alternate_object_database *ent;
        struct alternate_object_database *alt;
 -      /* 43 = 40-byte + 2 '/' + terminating NUL */
 -      int pfxlen = len;
 -      int entlen = pfxlen + 43;
 -      int base_len = -1;
 +      int pfxlen, entlen;
 +      struct strbuf pathbuf = STRBUF_INIT;
  
        if (!is_absolute_path(entry) && relative_base) {
 -              /* Relative alt-odb */
 -              if (base_len < 0)
 -                      base_len = strlen(relative_base) + 1;
 -              entlen += base_len;
 -              pfxlen += base_len;
 +              strbuf_addstr(&pathbuf, real_path(relative_base));
 +              strbuf_addch(&pathbuf, '/');
        }
 -      ent = xmalloc(sizeof(*ent) + entlen);
 +      strbuf_add(&pathbuf, entry, len);
  
 -      if (!is_absolute_path(entry) && relative_base) {
 -              memcpy(ent->base, relative_base, base_len - 1);
 -              ent->base[base_len - 1] = '/';
 -              memcpy(ent->base + base_len, entry, len);
 -      }
 -      else
 -              memcpy(ent->base, entry, pfxlen);
 +      normalize_path_copy(pathbuf.buf, pathbuf.buf);
 +
 +      pfxlen = strlen(pathbuf.buf);
 +
 +      /*
 +       * The trailing slash after the directory name is given by
 +       * this function at the end. Remove duplicates.
 +       */
 +      while (pfxlen && pathbuf.buf[pfxlen-1] == '/')
 +              pfxlen -= 1;
 +
 +      entlen = pfxlen + 43; /* '/' + 2 hex + '/' + 38 hex + NUL */
 +      ent = xmalloc(sizeof(*ent) + entlen);
 +      memcpy(ent->base, pathbuf.buf, pfxlen);
 +      strbuf_release(&pathbuf);
  
        ent->name = ent->base + pfxlen + 1;
        ent->base[pfxlen + 3] = '/';
@@@ -1987,7 -1984,7 +1987,7 @@@ off_t find_pack_entry_one(const unsigne
        return 0;
  }
  
static int is_pack_valid(struct packed_git *p)
+ int is_pack_valid(struct packed_git *p)
  {
        /* An already open pack is known to be valid. */
        if (p->pack_fd != -1)
@@@ -2038,7 -2035,7 +2038,7 @@@ static int find_pack_entry(const unsign
                         * was loaded!
                         */
                        if (!is_pack_valid(p)) {
-                               error("packfile %s cannot be accessed", p->pack_name);
+                               warning("packfile %s cannot be accessed", p->pack_name);
                                goto next;
                        }
                        e->offset = offset;