Merge branch 'jn/fast-import-ondemand-checkpoint'
authorJunio C Hamano <gitster@pobox.com>
Thu, 16 Dec 2010 20:49:11 +0000 (12:49 -0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 16 Dec 2010 20:49:11 +0000 (12:49 -0800)
* jn/fast-import-ondemand-checkpoint:
fast-import: treat SIGUSR1 as a request to access objects early

1  2 
fast-import.c
diff --combined fast-import.c
index 534c68db6fe4d0c34c38e632bd2c442966cf8663,b91470d7cba07c8675a0aa69332c0beded4a3c66..2b23635d607c871a67b7851aec8809822b284807
@@@ -156,7 -156,6 +156,7 @@@ Format of STDIN stream
  #include "csum-file.h"
  #include "quote.h"
  #include "exec_cmd.h"
 +#include "dir.h"
  
  #define PACK_ID_BITS 16
  #define MAX_PACK_ID ((1<<PACK_ID_BITS)-1)
@@@ -362,6 -361,9 +362,9 @@@ static uintmax_t next_mark
  static struct strbuf new_data = STRBUF_INIT;
  static int seen_data_command;
  
+ /* Signal handling */
+ static volatile sig_atomic_t checkpoint_requested;
  static void parse_argv(void);
  
  static void write_branch_report(FILE *rpt, struct branch *b)
@@@ -501,6 -503,32 +504,32 @@@ static NORETURN void die_nicely(const c
        exit(128);
  }
  
+ #ifndef SIGUSR1       /* Windows, for example */
+ static void set_checkpoint_signal(void)
+ {
+ }
+ #else
+ static void checkpoint_signal(int signo)
+ {
+       checkpoint_requested = 1;
+ }
+ static void set_checkpoint_signal(void)
+ {
+       struct sigaction sa;
+       memset(&sa, 0, sizeof(sa));
+       sa.sa_handler = checkpoint_signal;
+       sigemptyset(&sa.sa_mask);
+       sa.sa_flags = SA_RESTART;
+       sigaction(SIGUSR1, &sa, NULL);
+ }
+ #endif
  static void alloc_objects(unsigned int cnt)
  {
        struct object_entry_pool *b;
@@@ -1438,20 -1466,6 +1467,20 @@@ static void store_tree(struct tree_entr
        t->entry_count -= del;
  }
  
 +static void tree_content_replace(
 +      struct tree_entry *root,
 +      const unsigned char *sha1,
 +      const uint16_t mode,
 +      struct tree_content *newtree)
 +{
 +      if (!S_ISDIR(mode))
 +              die("Root cannot be a non-directory");
 +      hashcpy(root->versions[1].sha1, sha1);
 +      if (root->tree)
 +              release_tree_content_recursive(root->tree);
 +      root->tree = newtree;
 +}
 +
  static int tree_content_set(
        struct tree_entry *root,
        const char *p,
        const uint16_t mode,
        struct tree_content *subtree)
  {
 -      struct tree_content *t = root->tree;
 +      struct tree_content *t;
        const char *slash1;
        unsigned int i, n;
        struct tree_entry *e;
                n = slash1 - p;
        else
                n = strlen(p);
 -      if (!slash1 && !n) {
 -              if (!S_ISDIR(mode))
 -                      die("Root cannot be a non-directory");
 -              hashcpy(root->versions[1].sha1, sha1);
 -              if (root->tree)
 -                      release_tree_content_recursive(root->tree);
 -              root->tree = subtree;
 -              return 1;
 -      }
        if (!n)
                die("Empty path component found in input");
        if (!slash1 && !S_ISDIR(mode) && subtree)
                die("Non-directories cannot have subtrees");
  
 +      if (!root->tree)
 +              load_tree(root);
 +      t = root->tree;
        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 (e->name->str_len == n && !strncmp_icase(p, e->name->str_dat, n)) {
                        if (!slash1) {
                                if (!S_ISDIR(mode)
                                                && e->versions[1].mode == mode
@@@ -1532,7 -1552,7 +1561,7 @@@ static int tree_content_remove
        const char *p,
        struct tree_entry *backup_leaf)
  {
 -      struct tree_content *t = root->tree;
 +      struct tree_content *t;
        const char *slash1;
        unsigned int i, n;
        struct tree_entry *e;
        else
                n = strlen(p);
  
 +      if (!root->tree)
 +              load_tree(root);
 +      t = root->tree;
        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 (e->name->str_len == n && !strncmp_icase(p, e->name->str_dat, n)) {
                        if (slash1 && !S_ISDIR(e->versions[1].mode))
                                /*
                                 * If p names a file in some subdirectory, and a
@@@ -1593,7 -1610,7 +1622,7 @@@ static int tree_content_get
        const char *p,
        struct tree_entry *leaf)
  {
 -      struct tree_content *t = root->tree;
 +      struct tree_content *t;
        const char *slash1;
        unsigned int i, n;
        struct tree_entry *e;
        else
                n = strlen(p);
  
 +      if (!root->tree)
 +              load_tree(root);
 +      t = root->tree;
        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 (e->name->str_len == n && !strncmp_icase(p, e->name->str_dat, n)) {
                        if (!slash1) {
                                memcpy(leaf, e, sizeof(*leaf));
                                if (e->tree && is_null_sha1(e->versions[1].sha1))
@@@ -2233,10 -2247,6 +2262,10 @@@ static void file_change_m(struct branc
                                command_buf.buf);
        }
  
 +      if (!*p) {
 +              tree_content_replace(&b->branch_tree, sha1, mode, NULL);
 +              return;
 +      }
        tree_content_set(&b->branch_tree, p, sha1, mode, NULL);
  }
  
@@@ -2295,13 -2305,6 +2324,13 @@@ static void file_change_cr(struct branc
                tree_content_get(&b->branch_tree, s, &leaf);
        if (!leaf.versions[1].mode)
                die("Path %s not in branch", s);
 +      if (!*d) {      /* C "path/to/subdir" "" */
 +              tree_content_replace(&b->branch_tree,
 +                      leaf.versions[1].sha1,
 +                      leaf.versions[1].mode,
 +                      leaf.tree);
 +              return;
 +      }
        tree_content_set(&b->branch_tree, d,
                leaf.versions[1].sha1,
                leaf.versions[1].mode,
@@@ -2715,14 -2718,20 +2744,20 @@@ static void parse_reset_branch(void
                unread_command_buf = 1;
  }
  
- static void parse_checkpoint(void)
+ static void checkpoint(void)
  {
+       checkpoint_requested = 0;
        if (object_count) {
                cycle_packfile();
                dump_branches();
                dump_tags();
                dump_marks();
        }
+ }
+ static void parse_checkpoint(void)
+ {
+       checkpoint_requested = 1;
        skip_optional_lf();
  }
  
@@@ -2979,6 -2988,7 +3014,7 @@@ int main(int argc, const char **argv
        prepare_packed_git();
        start_packfile();
        set_die_routine(die_nicely);
+       set_checkpoint_signal();
        while (read_next_command() != EOF) {
                if (!strcmp("blob", command_buf.buf))
                        parse_new_blob();
                        /* ignore non-git options*/;
                else
                        die("Unsupported command: %s", command_buf.buf);
+               if (checkpoint_requested)
+                       checkpoint();
        }
  
        /* argv hasn't been parsed yet, do so */