Merge branch 'np/maint-1.6.3-deepen'
authorJunio C Hamano <gitster@pobox.com>
Mon, 7 Sep 2009 22:23:50 +0000 (15:23 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 7 Sep 2009 22:23:50 +0000 (15:23 -0700)
* np/maint-1.6.3-deepen:
pack-objects: free preferred base memory after usage
make shallow repository deepening more network efficient

1  2 
builtin-pack-objects.c
upload-pack.c
diff --combined builtin-pack-objects.c
index 1ff2ce6df4b5efc58612b7fe6d5877319f17724a,b44fa0e06ae894f3fce4ce5d77b8d917cfcfa20f..7a390e1d44f068629b1b03445a37f69847a85aa6
@@@ -86,7 -86,7 +86,7 @@@ static int pack_compression_level = Z_D
  static int pack_compression_seen;
  
  static unsigned long delta_cache_size = 0;
 -static unsigned long max_delta_cache_size = 0;
 +static unsigned long max_delta_cache_size = 256 * 1024 * 1024;
  static unsigned long cache_max_small_delta_size = 1000;
  
  static unsigned long window_memory_limit = 0;
@@@ -536,9 -536,11 +536,9 @@@ static void write_pack_file(void
                                 base_name, sha1_to_hex(sha1));
                        free_pack_by_name(tmpname);
                        if (adjust_perm(pack_tmp_name, mode))
 -                              die("unable to make temporary pack file readable: %s",
 -                                  strerror(errno));
 +                              die_errno("unable to make temporary pack file readable");
                        if (rename(pack_tmp_name, tmpname))
 -                              die("unable to rename temporary pack file: %s",
 -                                  strerror(errno));
 +                              die_errno("unable to rename temporary pack file");
  
                        /*
                         * Packs are runtime accessed in their mtime
                        snprintf(tmpname, sizeof(tmpname), "%s-%s.idx",
                                 base_name, sha1_to_hex(sha1));
                        if (adjust_perm(idx_tmp_name, mode))
 -                              die("unable to make temporary index file readable: %s",
 -                                  strerror(errno));
 +                              die_errno("unable to make temporary index file readable");
                        if (rename(idx_tmp_name, tmpname))
 -                              die("unable to rename temporary index file: %s",
 -                                  strerror(errno));
 +                              die_errno("unable to rename temporary index file");
  
                        free(idx_tmp_name);
                        free(pack_tmp_name);
@@@ -1008,6 -1012,33 +1008,33 @@@ static void add_preferred_base(unsigne
        it->pcache.tree_size = size;
  }
  
+ static void cleanup_preferred_base(void)
+ {
+       struct pbase_tree *it;
+       unsigned i;
+       it = pbase_tree;
+       pbase_tree = NULL;
+       while (it) {
+               struct pbase_tree *this = it;
+               it = this->next;
+               free(this->pcache.tree_data);
+               free(this);
+       }
+       for (i = 0; i < ARRAY_SIZE(pbase_tree_cache); i++) {
+               if (!pbase_tree_cache[i])
+                       continue;
+               free(pbase_tree_cache[i]->tree_data);
+               free(pbase_tree_cache[i]);
+               pbase_tree_cache[i] = NULL;
+       }
+       free(done_pbase_paths);
+       done_pbase_paths = NULL;
+       done_pbase_paths_num = done_pbase_paths_alloc = 0;
+ }
  static void check_object(struct object_entry *entry)
  {
        if (entry->in_pack) {
@@@ -1599,7 -1630,7 +1626,7 @@@ static void *threaded_find_deltas(void 
  static void ll_find_deltas(struct object_entry **list, unsigned list_size,
                           int window, int depth, unsigned *processed)
  {
 -      struct thread_params p[delta_search_threads];
 +      struct thread_params *p;
        int i, ret, active_threads = 0;
  
        if (delta_search_threads <= 1) {
        if (progress > pack_to_stdout)
                fprintf(stderr, "Delta compression using up to %d threads.\n",
                                delta_search_threads);
 +      p = xcalloc(delta_search_threads, sizeof(*p));
  
        /* Partition the work amongst work threads. */
        for (i = 0; i < delta_search_threads; i++) {
                        active_threads--;
                }
        }
 +      free(p);
  }
  
  #else
@@@ -1810,7 -1839,7 +1837,7 @@@ static void prepare_pack(int window, in
  
  static int git_pack_config(const char *k, const char *v, void *cb)
  {
 -      if(!strcmp(k, "pack.window")) {
 +      if (!strcmp(k, "pack.window")) {
                window = git_config_int(k, v);
                return 0;
        }
@@@ -1877,7 -1906,7 +1904,7 @@@ static void read_object_list_from_stdin
                        if (!ferror(stdin))
                                die("fgets returned NULL, not EOF, not error!");
                        if (errno != EINTR)
 -                              die("fgets: %s", strerror(errno));
 +                              die_errno("fgets");
                        clearerr(stdin);
                        continue;
                }
@@@ -2100,8 -2129,6 +2127,8 @@@ int cmd_pack_objects(int argc, const ch
        int rp_ac_alloc = 64;
        int rp_ac;
  
 +      read_replace_refs = 0;
 +
        rp_av = xcalloc(rp_ac_alloc, sizeof(*rp_av));
  
        rp_av[0] = "pack-objects";
                                die("bad %s", arg);
                        continue;
                }
 +              if (!strcmp(arg, "--keep-true-parents")) {
 +                      grafts_replace_parents = 0;
 +                      continue;
 +              }
                usage(pack_usage);
        }
  
                rp_av[rp_ac] = NULL;
                get_object_list(rp_ac, rp_av);
        }
+       cleanup_preferred_base();
        if (include_tag && nr_result)
                for_each_ref(add_ref_tag, NULL);
        stop_progress(&progress_state);
diff --combined upload-pack.c
index dacbc7614b1dc4735ca73ed067aec31463f147d0,7428ff715d7c7429c4a28bbe4cadab07963d6fea..25e222ffaac1d1a855f274d92087e6c7dfbd48b0
@@@ -28,10 -28,10 +28,11 @@@ static unsigned long oldest_have
  
  static int multi_ack, nr_our_refs;
  static int use_thin_pack, use_ofs_delta, use_include_tag;
 -static int no_progress;
 +static int no_progress, daemon_mode;
 +static int shallow_nr;
  static struct object_array have_obj;
  static struct object_array want_obj;
+ static struct object_array extra_edge_obj;
  static unsigned int timeout;
  /* 0 for no sideband,
   * otherwise maximum packet size (up to 65520 bytes).
@@@ -108,6 -108,8 +109,6 @@@ static int do_rev_list(int fd, void *cr
        struct rev_info revs;
  
        pack_pipe = fdopen(fd, "w");
 -      if (create_full_pack)
 -              use_thin_pack = 0; /* no point doing it */
        init_revisions(&revs, NULL);
        revs.tag_objects = 1;
        revs.tree_objects = 1;
        if (prepare_revision_walk(&revs))
                die("revision walk setup failed");
        mark_edges_uninteresting(revs.commits, &revs, show_edge);
+       if (use_thin_pack)
+               for (i = 0; i < extra_edge_obj.nr; i++)
+                       fprintf(pack_pipe, "-%s\n", sha1_to_hex(
+                                       extra_edge_obj.objects[i].item->sha1));
        traverse_commit_list(&revs, show_commit, show_object, NULL);
        fflush(pack_pipe);
        fclose(pack_pipe);
@@@ -154,21 -160,13 +159,21 @@@ static void create_pack_file(void
        const char *argv[10];
        int arg = 0;
  
 -      rev_list.proc = do_rev_list;
 -      /* .data is just a boolean: any non-NULL value will do */
 -      rev_list.data = create_full_pack ? &rev_list : NULL;
 -      if (start_async(&rev_list))
 -              die("git upload-pack: unable to fork git-rev-list");
 +      if (shallow_nr) {
 +              rev_list.proc = do_rev_list;
 +              rev_list.data = 0;
 +              if (start_async(&rev_list))
 +                      die("git upload-pack: unable to fork git-rev-list");
 +              argv[arg++] = "pack-objects";
 +      } else {
 +              argv[arg++] = "pack-objects";
 +              argv[arg++] = "--revs";
 +              if (create_full_pack)
 +                      argv[arg++] = "--all";
 +              else if (use_thin_pack)
 +                      argv[arg++] = "--thin";
 +      }
  
 -      argv[arg++] = "pack-objects";
        argv[arg++] = "--stdout";
        if (!no_progress)
                argv[arg++] = "--progress";
        argv[arg++] = NULL;
  
        memset(&pack_objects, 0, sizeof(pack_objects));
 -      pack_objects.in = rev_list.out; /* start_command closes it */
 +      pack_objects.in = shallow_nr ? rev_list.out : -1;
        pack_objects.out = -1;
        pack_objects.err = -1;
        pack_objects.git_cmd = 1;
        if (start_command(&pack_objects))
                die("git upload-pack: unable to fork git-pack-objects");
  
 +      /* pass on revisions we (don't) want */
 +      if (!shallow_nr) {
 +              FILE *pipe_fd = fdopen(pack_objects.in, "w");
 +              if (!create_full_pack) {
 +                      int i;
 +                      for (i = 0; i < want_obj.nr; i++)
 +                              fprintf(pipe_fd, "%s\n", sha1_to_hex(want_obj.objects[i].item->sha1));
 +                      fprintf(pipe_fd, "--not\n");
 +                      for (i = 0; i < have_obj.nr; i++)
 +                              fprintf(pipe_fd, "%s\n", sha1_to_hex(have_obj.objects[i].item->sha1));
 +              }
 +
 +              fprintf(pipe_fd, "\n");
 +              fflush(pipe_fd);
 +              fclose(pipe_fd);
 +      }
 +
 +
        /* We read from pack_objects.err to capture stderr output for
         * progress bar, and pack_objects.out to capture the pack data.
         */
                error("git upload-pack: git-pack-objects died with error.");
                goto fail;
        }
 -      if (finish_async(&rev_list))
 +      if (shallow_nr && finish_async(&rev_list))
                goto fail;      /* error was already reported */
  
        /* flush the data */
@@@ -427,7 -407,7 +432,7 @@@ static int get_common_commits(void
  
        save_commit_buffer = 0;
  
 -      for(;;) {
 +      for (;;) {
                int len = packet_read_line(0, line, sizeof(line));
                reset_timeout();
  
@@@ -476,7 -456,6 +481,7 @@@ static void receive_needs(void
        static char line[1000];
        int len, depth = 0;
  
 +      shallow_nr = 0;
        if (debug_fd)
                write_in_full(debug_fd, "#S\n", 3);
        for (;;) {
                if (!prefixcmp(line, "shallow ")) {
                        unsigned char sha1[20];
                        struct object *object;
-                       use_thin_pack = 0;
                        if (get_sha1(line + 8, sha1))
                                die("invalid shallow line: %s", line);
                        object = parse_object(sha1);
                }
                if (!prefixcmp(line, "deepen ")) {
                        char *end;
-                       use_thin_pack = 0;
                        depth = strtol(line + 7, &end, 0);
                        if (end == line + 7 || depth <= 0)
                                die("Invalid deepen: %s", line);
        }
        if (debug_fd)
                write_in_full(debug_fd, "#E\n", 3);
 +
 +      if (!use_sideband && daemon_mode)
 +              no_progress = 1;
 +
        if (depth == 0 && shallows.nr == 0)
                return;
        if (depth > 0) {
                                packet_write(1, "shallow %s",
                                                sha1_to_hex(object->sha1));
                                register_shallow(object->sha1);
 +                              shallow_nr++;
                        }
                        result = result->next;
                }
                                                        NULL, &want_obj);
                                        parents = parents->next;
                                }
+                               add_object_array(object, NULL, &extra_edge_obj);
                        }
                        /* make sure commit traversal conforms to client */
                        register_shallow(object->sha1);
                        for (i = 0; i < shallows.nr; i++)
                                register_shallow(shallows.objects[i].item->sha1);
                }
 +
 +      shallow_nr += shallows.nr;
        free(shallows.objects);
  }
  
@@@ -651,7 -622,6 +655,7 @@@ int main(int argc, char **argv
        int strict = 0;
  
        git_extract_argv0_path(argv[0]);
 +      read_replace_refs = 0;
  
        for (i = 1; i < argc; i++) {
                char *arg = argv[i];
                }
                if (!prefixcmp(arg, "--timeout=")) {
                        timeout = atoi(arg+10);
 +                      daemon_mode = 1;
                        continue;
                }
                if (!strcmp(arg, "--")) {