Merge branch 'maint'
authorJunio C Hamano <gitster@pobox.com>
Tue, 19 Jan 2010 02:16:19 +0000 (18:16 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 19 Jan 2010 02:16:19 +0000 (18:16 -0800)
* maint:
Update draft release notes to 1.6.6.1
grep: NUL terminate input from a file
fast-import: tag may point to any object type

1  2 
builtin-grep.c
fast-import.c
diff --combined builtin-grep.c
index 529461fb8fdf6bdbee86b8cc46fa610696cb9382,c7d74fbb7fe26840d4084ad3fef2c8fd4674df6e..cea973ba6bafff69b72db0923e5b583dc0a3f8bc
@@@ -205,6 -205,7 +205,7 @@@ static int grep_file(struct grep_opt *o
                return 0;
        }
        close(i);
+       data[sz] = 0;
        if (opt->relative && opt->prefix_length)
                filename = quote_path_relative(filename, -1, &buf, opt->prefix);
        i = grep_buffer(opt, filename, data, sz);
@@@ -220,7 -221,6 +221,7 @@@ static int exec_grep(int argc, const ch
        int status;
  
        argv[argc] = NULL;
 +      trace_argv_printf(argv, "trace: grep:");
        pid = fork();
        if (pid < 0)
                return pid;
@@@ -346,21 -346,6 +347,21 @@@ static void grep_add_color(struct strbu
                strbuf_setlen(sb, sb->len - 1);
  }
  
 +static int has_skip_worktree_entry(struct grep_opt *opt, const char **paths)
 +{
 +      int nr;
 +      for (nr = 0; nr < active_nr; nr++) {
 +              struct cache_entry *ce = active_cache[nr];
 +              if (!S_ISREG(ce->ce_mode))
 +                      continue;
 +              if (!pathspec_matches(paths, ce->name, opt->max_depth))
 +                      continue;
 +              if (ce_skip_worktree(ce))
 +                      return 1;
 +      }
 +      return 0;
 +}
 +
  static int external_grep(struct grep_opt *opt, const char **paths, int cached)
  {
        int i, nr, argc, hit, len, status;
        char *argptr = randarg;
        struct grep_pat *p;
  
 -      if (opt->extended || (opt->relative && opt->prefix_length))
 +      if (opt->extended || (opt->relative && opt->prefix_length)
 +          || has_skip_worktree_entry(opt, paths))
                return -1;
        len = nr = 0;
        push_arg("grep");
@@@ -527,7 -511,7 +528,7 @@@ static int grep_cache(struct grep_opt *
                 * are identical, even if worktree file has been modified, so use
                 * cache version instead
                 */
 -              if (cached || (ce->ce_flags & CE_VALID)) {
 +              if (cached || (ce->ce_flags & CE_VALID) || ce_skip_worktree(ce)) {
                        if (ce_stage(ce))
                                continue;
                        hit |= grep_sha1(opt, ce->sha1, ce->name, 0);
diff --combined fast-import.c
index 52d33bcba8c5ca834fc944bbb2d47ae14bf2f7b8,60d0aa2bb45490b90b1d68b26bb7ae5f7d035541..25c3588385af63fdb9782ece39a1a4533b805260
@@@ -295,9 -295,6 +295,9 @@@ static unsigned long branch_count
  static unsigned long branch_load_count;
  static int failure;
  static FILE *pack_edges;
 +static unsigned int show_stats = 1;
 +static int global_argc;
 +static const char **global_argv;
  
  /* Memory pools */
  static size_t mem_pool_alloc = 2*1024*1024 - sizeof(struct mem_pool);
@@@ -320,10 -317,7 +320,10 @@@ static unsigned int object_entry_alloc 
  static struct object_entry_pool *blocks;
  static struct object_entry *object_table[1 << 16];
  static struct mark_set *marks;
 -static const char *mark_file;
 +static const char *export_marks_file;
 +static const char *import_marks_file;
 +static int import_marks_file_from_stream;
 +static int relative_marks_paths;
  
  /* Our last blob */
  static struct last_object last_blob = { STRBUF_INIT, 0, 0, 0 };
@@@ -357,9 -351,6 +357,9 @@@ static struct recent_command *rc_free
  static unsigned int cmd_save = 100;
  static uintmax_t next_mark;
  static struct strbuf new_data = STRBUF_INIT;
 +static int seen_data_command;
 +
 +static void parse_argv(void);
  
  static void write_branch_report(FILE *rpt, struct branch *b)
  {
@@@ -463,8 -454,8 +463,8 @@@ static void write_crash_report(const ch
        fputc('\n', rpt);
        fputs("Marks\n", rpt);
        fputs("-----\n", rpt);
 -      if (mark_file)
 -              fprintf(rpt, "  exported to %s\n", mark_file);
 +      if (export_marks_file)
 +              fprintf(rpt, "  exported to %s\n", export_marks_file);
        else
                dump_marks_helper(rpt, 0, marks);
  
@@@ -1611,13 -1602,13 +1611,13 @@@ static void dump_marks(void
        int mark_fd;
        FILE *f;
  
 -      if (!mark_file)
 +      if (!export_marks_file)
                return;
  
 -      mark_fd = hold_lock_file_for_update(&mark_lock, mark_file, 0);
 +      mark_fd = hold_lock_file_for_update(&mark_lock, export_marks_file, 0);
        if (mark_fd < 0) {
                failure |= error("Unable to write marks file %s: %s",
 -                      mark_file, strerror(errno));
 +                      export_marks_file, strerror(errno));
                return;
        }
  
                int saved_errno = errno;
                rollback_lock_file(&mark_lock);
                failure |= error("Unable to write marks file %s: %s",
 -                      mark_file, strerror(saved_errno));
 +                      export_marks_file, strerror(saved_errno));
                return;
        }
  
                int saved_errno = errno;
                rollback_lock_file(&mark_lock);
                failure |= error("Unable to write marks file %s: %s",
 -                      mark_file, strerror(saved_errno));
 +                      export_marks_file, strerror(saved_errno));
                return;
        }
  
                int saved_errno = errno;
                rollback_lock_file(&mark_lock);
                failure |= error("Unable to commit marks file %s: %s",
 -                      mark_file, strerror(saved_errno));
 +                      export_marks_file, strerror(saved_errno));
                return;
        }
  }
  
 +static void read_marks(void)
 +{
 +      char line[512];
 +      FILE *f = fopen(import_marks_file, "r");
 +      if (!f)
 +              die_errno("cannot read '%s'", import_marks_file);
 +      while (fgets(line, sizeof(line), f)) {
 +              uintmax_t mark;
 +              char *end;
 +              unsigned char sha1[20];
 +              struct object_entry *e;
 +
 +              end = strchr(line, '\n');
 +              if (line[0] != ':' || !end)
 +                      die("corrupt mark line: %s", line);
 +              *end = 0;
 +              mark = strtoumax(line + 1, &end, 10);
 +              if (!mark || end == line + 1
 +                      || *end != ' ' || get_sha1(end + 1, sha1))
 +                      die("corrupt mark line: %s", line);
 +              e = find_object(sha1);
 +              if (!e) {
 +                      enum object_type type = sha1_object_info(sha1, NULL);
 +                      if (type < 0)
 +                              die("object not found: %s", sha1_to_hex(sha1));
 +                      e = insert_object(sha1);
 +                      e->type = type;
 +                      e->pack_id = MAX_PACK_ID;
 +                      e->offset = 1; /* just not zero! */
 +              }
 +              insert_mark(mark, e);
 +      }
 +      fclose(f);
 +}
 +
 +
  static int read_next_command(void)
  {
        static int stdin_eof = 0;
                        if (stdin_eof)
                                return EOF;
  
 +                      if (!seen_data_command
 +                              && prefixcmp(command_buf.buf, "feature ")
 +                              && prefixcmp(command_buf.buf, "option ")) {
 +                              parse_argv();
 +                      }
 +
                        rc = rc_free;
                        if (rc)
                                rc_free = rc->next;
@@@ -2356,6 -2305,7 +2356,7 @@@ static void parse_new_tag(void
        struct tag *t;
        uintmax_t from_mark = 0;
        unsigned char sha1[20];
+       enum object_type type;
  
        /* Obtain the new tag name from the rest of our command */
        sp = strchr(command_buf.buf, ' ') + 1;
        s = lookup_branch(from);
        if (s) {
                hashcpy(sha1, s->sha1);
+               type = OBJ_COMMIT;
        } else if (*from == ':') {
                struct object_entry *oe;
                from_mark = strtoumax(from + 1, NULL, 10);
                oe = find_mark(from_mark);
-               if (oe->type != OBJ_COMMIT)
-                       die("Mark :%" PRIuMAX " not a commit", from_mark);
+               type = oe->type;
                hashcpy(sha1, oe->sha1);
        } else if (!get_sha1(from, sha1)) {
                unsigned long size;
                char *buf;
  
-               buf = read_object_with_reference(sha1,
-                       commit_type, &size, sha1);
+               buf = read_sha1_file(sha1, &type, &size);
                if (!buf || size < 46)
                        die("Not a valid commit: %s", from);
                free(buf);
                    "object %s\n"
                    "type %s\n"
                    "tag %s\n",
-                   sha1_to_hex(sha1), commit_type, t->name);
+                   sha1_to_hex(sha1), typename(type), t->name);
        if (tagger)
                strbuf_addf(&new_data,
                            "tagger %s\n", tagger);
@@@ -2471,140 -2420,39 +2471,140 @@@ static void parse_progress(void
        skip_optional_lf();
  }
  
 -static void import_marks(const char *input_file)
 +static char* make_fast_import_path(const char *path)
  {
 -      char line[512];
 -      FILE *f = fopen(input_file, "r");
 -      if (!f)
 -              die_errno("cannot read '%s'", input_file);
 -      while (fgets(line, sizeof(line), f)) {
 -              uintmax_t mark;
 -              char *end;
 -              unsigned char sha1[20];
 -              struct object_entry *e;
 +      struct strbuf abs_path = STRBUF_INIT;
  
 -              end = strchr(line, '\n');
 -              if (line[0] != ':' || !end)
 -                      die("corrupt mark line: %s", line);
 -              *end = 0;
 -              mark = strtoumax(line + 1, &end, 10);
 -              if (!mark || end == line + 1
 -                      || *end != ' ' || get_sha1(end + 1, sha1))
 -                      die("corrupt mark line: %s", line);
 -              e = find_object(sha1);
 -              if (!e) {
 -                      enum object_type type = sha1_object_info(sha1, NULL);
 -                      if (type < 0)
 -                              die("object not found: %s", sha1_to_hex(sha1));
 -                      e = insert_object(sha1);
 -                      e->type = type;
 -                      e->pack_id = MAX_PACK_ID;
 -                      e->offset = 1; /* just not zero! */
 -              }
 -              insert_mark(mark, e);
 +      if (!relative_marks_paths || is_absolute_path(path))
 +              return xstrdup(path);
 +      strbuf_addf(&abs_path, "%s/info/fast-import/%s", get_git_dir(), path);
 +      return strbuf_detach(&abs_path, NULL);
 +}
 +
 +static void option_import_marks(const char *marks, int from_stream)
 +{
 +      if (import_marks_file) {
 +              if (from_stream)
 +                      die("Only one import-marks command allowed per stream");
 +
 +              /* read previous mark file */
 +              if(!import_marks_file_from_stream)
 +                      read_marks();
        }
 -      fclose(f);
 +
 +      import_marks_file = make_fast_import_path(marks);
 +      import_marks_file_from_stream = from_stream;
 +}
 +
 +static void option_date_format(const char *fmt)
 +{
 +      if (!strcmp(fmt, "raw"))
 +              whenspec = WHENSPEC_RAW;
 +      else if (!strcmp(fmt, "rfc2822"))
 +              whenspec = WHENSPEC_RFC2822;
 +      else if (!strcmp(fmt, "now"))
 +              whenspec = WHENSPEC_NOW;
 +      else
 +              die("unknown --date-format argument %s", fmt);
 +}
 +
 +static void option_max_pack_size(const char *packsize)
 +{
 +      max_packsize = strtoumax(packsize, NULL, 0) * 1024 * 1024;
 +}
 +
 +static void option_depth(const char *depth)
 +{
 +      max_depth = strtoul(depth, NULL, 0);
 +      if (max_depth > MAX_DEPTH)
 +              die("--depth cannot exceed %u", MAX_DEPTH);
 +}
 +
 +static void option_active_branches(const char *branches)
 +{
 +      max_active_branches = strtoul(branches, NULL, 0);
 +}
 +
 +static void option_export_marks(const char *marks)
 +{
 +      export_marks_file = make_fast_import_path(marks);
 +}
 +
 +static void option_export_pack_edges(const char *edges)
 +{
 +      if (pack_edges)
 +              fclose(pack_edges);
 +      pack_edges = fopen(edges, "a");
 +      if (!pack_edges)
 +              die_errno("Cannot open '%s'", edges);
 +}
 +
 +static int parse_one_option(const char *option)
 +{
 +      if (!prefixcmp(option, "max-pack-size=")) {
 +              option_max_pack_size(option + 14);
 +      } else if (!prefixcmp(option, "depth=")) {
 +              option_depth(option + 6);
 +      } else if (!prefixcmp(option, "active-branches=")) {
 +              option_active_branches(option + 16);
 +      } else if (!prefixcmp(option, "export-pack-edges=")) {
 +              option_export_pack_edges(option + 18);
 +      } else if (!prefixcmp(option, "quiet")) {
 +              show_stats = 0;
 +      } else if (!prefixcmp(option, "stats")) {
 +              show_stats = 1;
 +      } else {
 +              return 0;
 +      }
 +
 +      return 1;
 +}
 +
 +static int parse_one_feature(const char *feature, int from_stream)
 +{
 +      if (!prefixcmp(feature, "date-format=")) {
 +              option_date_format(feature + 12);
 +      } else if (!prefixcmp(feature, "import-marks=")) {
 +              option_import_marks(feature + 13, from_stream);
 +      } else if (!prefixcmp(feature, "export-marks=")) {
 +              option_export_marks(feature + 13);
 +      } else if (!prefixcmp(feature, "relative-marks")) {
 +              relative_marks_paths = 1;
 +      } else if (!prefixcmp(feature, "no-relative-marks")) {
 +              relative_marks_paths = 0;
 +      } else if (!prefixcmp(feature, "force")) {
 +              force_update = 1;
 +      } else {
 +              return 0;
 +      }
 +
 +      return 1;
 +}
 +
 +static void parse_feature(void)
 +{
 +      char *feature = command_buf.buf + 8;
 +
 +      if (seen_data_command)
 +              die("Got feature command '%s' after data command", feature);
 +
 +      if (parse_one_feature(feature, 1))
 +              return;
 +
 +      die("This version of fast-import does not support feature %s.", feature);
 +}
 +
 +static void parse_option(void)
 +{
 +      char *option = command_buf.buf + 11;
 +
 +      if (seen_data_command)
 +              die("Got option command '%s' after data command", option);
 +
 +      if (parse_one_option(option))
 +              return;
 +
 +      die("This version of fast-import does not support option: %s", option);
  }
  
  static int git_pack_config(const char *k, const char *v, void *cb)
  static const char fast_import_usage[] =
  "git fast-import [--date-format=f] [--max-pack-size=n] [--depth=n] [--active-branches=n] [--export-marks=marks.file]";
  
 +static void parse_argv(void)
 +{
 +      unsigned int i;
 +
 +      for (i = 1; i < global_argc; i++) {
 +              const char *a = global_argv[i];
 +
 +              if (*a != '-' || !strcmp(a, "--"))
 +                      break;
 +
 +              if (parse_one_option(a + 2))
 +                      continue;
 +
 +              if (parse_one_feature(a + 2, 0))
 +                      continue;
 +
 +              die("unknown option %s", a);
 +      }
 +      if (i != global_argc)
 +              usage(fast_import_usage);
 +
 +      seen_data_command = 1;
 +      if (import_marks_file)
 +              read_marks();
 +}
 +
  int main(int argc, const char **argv)
  {
 -      unsigned int i, show_stats = 1;
 +      unsigned int i;
  
        git_extract_argv0_path(argv[0]);
  
        avail_tree_table = xcalloc(avail_tree_table_sz, sizeof(struct avail_tree_content*));
        marks = pool_calloc(1, sizeof(struct mark_set));
  
 -      for (i = 1; i < argc; i++) {
 -              const char *a = argv[i];
 -
 -              if (*a != '-' || !strcmp(a, "--"))
 -                      break;
 -              else if (!prefixcmp(a, "--date-format=")) {
 -                      const char *fmt = a + 14;
 -                      if (!strcmp(fmt, "raw"))
 -                              whenspec = WHENSPEC_RAW;
 -                      else if (!strcmp(fmt, "rfc2822"))
 -                              whenspec = WHENSPEC_RFC2822;
 -                      else if (!strcmp(fmt, "now"))
 -                              whenspec = WHENSPEC_NOW;
 -                      else
 -                              die("unknown --date-format argument %s", fmt);
 -              }
 -              else if (!prefixcmp(a, "--max-pack-size="))
 -                      max_packsize = strtoumax(a + 16, NULL, 0) * 1024 * 1024;
 -              else if (!prefixcmp(a, "--depth=")) {
 -                      max_depth = strtoul(a + 8, NULL, 0);
 -                      if (max_depth > MAX_DEPTH)
 -                              die("--depth cannot exceed %u", MAX_DEPTH);
 -              }
 -              else if (!prefixcmp(a, "--active-branches="))
 -                      max_active_branches = strtoul(a + 18, NULL, 0);
 -              else if (!prefixcmp(a, "--import-marks="))
 -                      import_marks(a + 15);
 -              else if (!prefixcmp(a, "--export-marks="))
 -                      mark_file = a + 15;
 -              else if (!prefixcmp(a, "--export-pack-edges=")) {
 -                      if (pack_edges)
 -                              fclose(pack_edges);
 -                      pack_edges = fopen(a + 20, "a");
 -                      if (!pack_edges)
 -                              die_errno("Cannot open '%s'", a + 20);
 -              } else if (!strcmp(a, "--force"))
 -                      force_update = 1;
 -              else if (!strcmp(a, "--quiet"))
 -                      show_stats = 0;
 -              else if (!strcmp(a, "--stats"))
 -                      show_stats = 1;
 -              else
 -                      die("unknown option %s", a);
 -      }
 -      if (i != argc)
 -              usage(fast_import_usage);
 +      global_argc = argc;
 +      global_argv = argv;
  
        rc_free = pool_alloc(cmd_save * sizeof(*rc_free));
        for (i = 0; i < (cmd_save - 1); i++)
                        parse_checkpoint();
                else if (!prefixcmp(command_buf.buf, "progress "))
                        parse_progress();
 +              else if (!prefixcmp(command_buf.buf, "feature "))
 +                      parse_feature();
 +              else if (!prefixcmp(command_buf.buf, "option git "))
 +                      parse_option();
 +              else if (!prefixcmp(command_buf.buf, "option "))
 +                      /* ignore non-git options*/;
                else
                        die("Unsupported command: %s", command_buf.buf);
        }
 +
 +      /* argv hasn't been parsed yet, do so */
 +      if (!seen_data_command)
 +              parse_argv();
 +
        end_packfile();
  
        dump_branches();