Merge branch 'dk/gc-idx-wo-pack' into maint
[gitweb.git] / fast-import.c
index ece009662379dd26a523cb082b50c11109c96b14..6c7c3c9b669eb272f4da530aef459c9c39c4d294 100644 (file)
@@ -134,16 +134,17 @@ Format of STDIN stream:
   ts    ::= # time since the epoch in seconds, ascii base10 notation;
   tz    ::= # GIT style timezone;
 
-     # note: comments, ls and cat requests may appear anywhere
-     # in the input, except within a data command.  Any form
-     # of the data command always escapes the related input
-     # from comment processing.
+     # note: comments, get-mark, ls-tree, and cat-blob requests may
+     # appear anywhere in the input, except within a data command. Any
+     # form of the data command always escapes the related input from
+     # comment processing.
      #
      # In case it is not clear, the '#' that starts the comment
      # must be the first character on that line (an lf
      # preceded it).
      #
 
+  get_mark ::= 'get-mark' sp idnum lf;
   cat_blob ::= 'cat-blob' sp (hexsha1 | idnum) lf;
   ls_tree  ::= 'ls' sp (hexsha1 | idnum) sp path_str lf;
 
@@ -372,6 +373,7 @@ static volatile sig_atomic_t checkpoint_requested;
 static int cat_blob_fd = STDOUT_FILENO;
 
 static void parse_argv(void);
+static void parse_get_mark(const char *p);
 static void parse_cat_blob(const char *p);
 static void parse_ls(const char *p, struct branch *b);
 
@@ -405,7 +407,7 @@ static void dump_marks_helper(FILE *, uintmax_t, struct mark_set *);
 
 static void write_crash_report(const char *err)
 {
-       const char *loc = git_path("fast_import_crash_%"PRIuMAX, (uintmax_t) getpid());
+       char *loc = git_pathdup("fast_import_crash_%"PRIuMAX, (uintmax_t) getpid());
        FILE *rpt = fopen(loc, "w");
        struct branch *b;
        unsigned long lu;
@@ -413,6 +415,7 @@ static void write_crash_report(const char *err)
 
        if (!rpt) {
                error("can't write crash report %s: %s", loc, strerror(errno));
+               free(loc);
                return;
        }
 
@@ -421,7 +424,7 @@ static void write_crash_report(const char *err)
        fprintf(rpt, "fast-import crash report:\n");
        fprintf(rpt, "    fast-import process: %"PRIuMAX"\n", (uintmax_t) getpid());
        fprintf(rpt, "    parent process     : %"PRIuMAX"\n", (uintmax_t) getppid());
-       fprintf(rpt, "    at %s\n", show_date(time(NULL), 0, DATE_LOCAL));
+       fprintf(rpt, "    at %s\n", show_date(time(NULL), 0, DATE_MODE(LOCAL)));
        fputc('\n', rpt);
 
        fputs("fatal: ", rpt);
@@ -486,6 +489,7 @@ static void write_crash_report(const char *err)
        fputs("-------------------\n", rpt);
        fputs("END OF CRASH REPORT\n", rpt);
        fclose(rpt);
+       free(loc);
 }
 
 static void end_packfile(void);
@@ -921,12 +925,12 @@ static char *keep_pack(const char *curr_index_name)
 
        snprintf(name, sizeof(name), "%s/pack/pack-%s.pack",
                 get_object_directory(), sha1_to_hex(pack_data->sha1));
-       if (move_temp_to_file(pack_data->pack_name, name))
+       if (finalize_object_file(pack_data->pack_name, name))
                die("cannot store pack file");
 
        snprintf(name, sizeof(name), "%s/pack/pack-%s.idx",
                 get_object_directory(), sha1_to_hex(pack_data->sha1));
-       if (move_temp_to_file(curr_index_name, name))
+       if (finalize_object_file(curr_index_name, name))
                die("cannot store index file");
        free((void *)curr_index_name);
        return name;
@@ -1692,13 +1696,13 @@ static int update_branch(struct branch *b)
        unsigned char old_sha1[20];
        struct strbuf err = STRBUF_INIT;
 
-       if (read_ref(b->name, old_sha1))
-               hashclr(old_sha1);
        if (is_null_sha1(b->sha1)) {
                if (b->delete)
-                       delete_ref(b->name, old_sha1, 0);
+                       delete_ref(b->name, NULL, 0);
                return 0;
        }
+       if (read_ref(b->name, old_sha1))
+               hashclr(old_sha1);
        if (!force_update && !is_null_sha1(old_sha1)) {
                struct commit *old_cmit, *new_cmit;
 
@@ -1907,6 +1911,10 @@ static int read_next_command(void)
                        rc->prev->next = rc;
                        cmd_tail = rc;
                }
+               if (skip_prefix(command_buf.buf, "get-mark ", &p)) {
+                       parse_get_mark(p);
+                       continue;
+               }
                if (skip_prefix(command_buf.buf, "cat-blob ", &p)) {
                        parse_cat_blob(p);
                        continue;
@@ -2924,6 +2932,23 @@ static void cat_blob(struct object_entry *oe, unsigned char sha1[20])
                free(buf);
 }
 
+static void parse_get_mark(const char *p)
+{
+       struct object_entry *oe = oe;
+       char output[42];
+
+       /* get-mark SP <object> LF */
+       if (*p != ':')
+               die("Not a mark: %s", p);
+
+       oe = find_mark(parse_mark_ref_eol(p));
+       if (!oe)
+               die("Unknown mark: %s", command_buf.buf);
+
+       snprintf(output, sizeof(output), "%s\n", sha1_to_hex(oe->idx.sha1));
+       cat_blob_write(output, 41);
+}
+
 static void parse_cat_blob(const char *p)
 {
        struct object_entry *oe = oe;
@@ -3245,6 +3270,8 @@ static int parse_one_feature(const char *feature, int from_stream)
                option_import_marks(arg, from_stream, 1);
        } else if (skip_prefix(feature, "export-marks=", &arg)) {
                option_export_marks(arg);
+       } else if (!strcmp(feature, "get-mark")) {
+               ; /* Don't die - this feature is supported */
        } else if (!strcmp(feature, "cat-blob")) {
                ; /* Don't die - this feature is supported */
        } else if (!strcmp(feature, "relative-marks")) {