Merge branch 'jn/maint-fast-import-object-reuse' into maint
authorJunio C Hamano <gitster@pobox.com>
Wed, 19 Jan 2011 16:25:46 +0000 (08:25 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 19 Jan 2011 16:25:46 +0000 (08:25 -0800)
* jn/maint-fast-import-object-reuse:
fast-import: insert new object entries at start of hash bucket

1  2 
fast-import.c
diff --combined fast-import.c
index eab68d58c394a67f4805d77b0007b583e79e24b9,89d074bbe432440f84156a82164179ff53336058..613623be14c4c647e11b20fefb382b3f7438fb3c
@@@ -267,7 -267,7 +267,7 @@@ struct hash_lis
  typedef enum {
        WHENSPEC_RAW = 1,
        WHENSPEC_RFC2822,
 -      WHENSPEC_NOW,
 +      WHENSPEC_NOW
  } whenspec_type;
  
  struct recent_command
@@@ -539,22 -539,17 +539,17 @@@ static struct object_entry *insert_obje
  {
        unsigned int h = sha1[0] << 8 | sha1[1];
        struct object_entry *e = object_table[h];
-       struct object_entry *p = NULL;
  
        while (e) {
                if (!hashcmp(sha1, e->idx.sha1))
                        return e;
-               p = e;
                e = e->next;
        }
  
        e = new_object(sha1);
-       e->next = NULL;
+       e->next = object_table[h];
        e->idx.offset = 0;
-       if (p)
-               p->next = e;
-       else
-               object_table[h] = e;
+       object_table[h] = e;
        return e;
  }
  
@@@ -980,6 -975,29 +975,6 @@@ static void cycle_packfile(void
        start_packfile();
  }
  
 -static size_t encode_header(
 -      enum object_type type,
 -      uintmax_t size,
 -      unsigned char *hdr)
 -{
 -      int n = 1;
 -      unsigned char c;
 -
 -      if (type < OBJ_COMMIT || type > OBJ_REF_DELTA)
 -              die("bad type %d", type);
 -
 -      c = (type << 4) | (size & 15);
 -      size >>= 4;
 -      while (size) {
 -              *hdr++ = c | 0x80;
 -              c = size & 0x7f;
 -              size >>= 7;
 -              n++;
 -      }
 -      *hdr = c;
 -      return n;
 -}
 -
  static int store_object(
        enum object_type type,
        struct strbuf *dat,
                delta_count_by_type[type]++;
                e->depth = last->depth + 1;
  
 -              hdrlen = encode_header(OBJ_OFS_DELTA, deltalen, hdr);
 +              hdrlen = encode_in_pack_object_header(OBJ_OFS_DELTA, deltalen, hdr);
                sha1write(pack_file, hdr, hdrlen);
                pack_size += hdrlen;
  
                pack_size += sizeof(hdr) - pos;
        } else {
                e->depth = 0;
 -              hdrlen = encode_header(type, dat->len, hdr);
 +              hdrlen = encode_in_pack_object_header(type, dat->len, hdr);
                sha1write(pack_file, hdr, hdrlen);
                pack_size += hdrlen;
        }
@@@ -1165,7 -1183,7 +1160,7 @@@ static void stream_blob(uintmax_t len, 
        memset(&s, 0, sizeof(s));
        deflateInit(&s, pack_compression_level);
  
 -      hdrlen = encode_header(OBJ_BLOB, len, out_buf);
 +      hdrlen = encode_in_pack_object_header(OBJ_BLOB, len, out_buf);
        if (out_sz <= hdrlen)
                die("impossibly large object header");
  
@@@ -1528,14 -1546,6 +1523,14 @@@ static int tree_content_remove
        for (i = 0; i < t->entry_count; i++) {
                e = t->entries[i];
                if (e->name->str_len == n && !strncmp(p, e->name->str_dat, n)) {
 +                      if (slash1 && !S_ISDIR(e->versions[1].mode))
 +                              /*
 +                               * If p names a file in some subdirectory, and a
 +                               * file or symlink matching the name of the
 +                               * parent directory of p exists, then p cannot
 +                               * exist and need not be deleted.
 +                               */
 +                              return 1;
                        if (!slash1 || !S_ISDIR(e->versions[1].mode))
                                goto del_entry;
                        if (!e->tree)
@@@ -1674,7 -1684,7 +1669,7 @@@ static void dump_marks_helper(FILE *f
        if (m->shift) {
                for (k = 0; k < 1024; k++) {
                        if (m->data.sets[k])
 -                              dump_marks_helper(f, (base + k) << m->shift,
 +                              dump_marks_helper(f, base + (k << m->shift),
                                        m->data.sets[k]);
                }
        } else {
@@@ -2139,7 -2149,6 +2134,7 @@@ static void file_change_m(struct branc
        case S_IFREG | 0644:
        case S_IFREG | 0755:
        case S_IFLNK:
 +      case S_IFDIR:
        case S_IFGITLINK:
                /* ok */
                break;
                 * another repository.
                 */
        } else if (inline_data) {
 +              if (S_ISDIR(mode))
 +                      die("Directories cannot be specified 'inline': %s",
 +                              command_buf.buf);
                if (p != uq.buf) {
                        strbuf_addstr(&uq, p);
                        p = uq.buf;
                }
                read_next_command();
                parse_and_store_blob(&last_blob, sha1, 0);
 -      } else if (oe) {
 -              if (oe->type != OBJ_BLOB)
 -                      die("Not a blob (actually a %s): %s",
 -                              typename(oe->type), command_buf.buf);
        } else {
 -              enum object_type type = sha1_object_info(sha1, NULL);
 +              enum object_type expected = S_ISDIR(mode) ?
 +                                              OBJ_TREE: OBJ_BLOB;
 +              enum object_type type = oe ? oe->type :
 +                                      sha1_object_info(sha1, NULL);
                if (type < 0)
 -                      die("Blob not found: %s", command_buf.buf);
 -              if (type != OBJ_BLOB)
 -                      die("Not a blob (actually a %s): %s",
 -                          typename(type), command_buf.buf);
 +                      die("%s not found: %s",
 +                                      S_ISDIR(mode) ?  "Tree" : "Blob",
 +                                      command_buf.buf);
 +              if (type != expected)
 +                      die("Not a %s (actually a %s): %s",
 +                              typename(expected), typename(type),
 +                              command_buf.buf);
        }
  
        tree_content_set(&b->branch_tree, p, sha1, mode, NULL);
@@@ -2721,7 -2725,6 +2716,7 @@@ static void option_import_marks(const c
        }
  
        import_marks_file = make_fast_import_path(marks);
 +      safe_create_leading_directories_const(import_marks_file);
        import_marks_file_from_stream = from_stream;
  }
  
@@@ -2752,7 -2755,6 +2747,7 @@@ static void option_active_branches(cons
  static void option_export_marks(const char *marks)
  {
        export_marks_file = make_fast_import_path(marks);
 +      safe_create_leading_directories_const(export_marks_file);
  }
  
  static void option_export_pack_edges(const char *edges)
@@@ -2884,7 -2886,7 +2879,7 @@@ static int git_pack_config(const char *
  }
  
  static const char fast_import_usage[] =
 -"git fast-import [--date-format=f] [--max-pack-size=n] [--big-file-threshold=n] [--depth=n] [--active-branches=n] [--export-marks=marks.file]";
 +"git fast-import [--date-format=<f>] [--max-pack-size=<n>] [--big-file-threshold=<n>] [--depth=<n>] [--active-branches=<n>] [--export-marks=<marks.file>]";
  
  static void parse_argv(void)
  {