]> asedeno.scripts.mit.edu Git - git.git/blobdiff - fast-import.c
Merge branch 'maint'
[git.git] / fast-import.c
index f9906586ee252519e65f6d9c4e6a2cff417262bc..98c2bd535957a45e5ef189875859d4788d937e7e 100644 (file)
@@ -153,13 +153,16 @@ Format of STDIN stream:
 
 #define PACK_ID_BITS 16
 #define MAX_PACK_ID ((1<<PACK_ID_BITS)-1)
+#define DEPTH_BITS 13
+#define MAX_DEPTH ((1<<DEPTH_BITS)-1)
 
 struct object_entry
 {
        struct object_entry *next;
        uint32_t offset;
-       unsigned type : TYPE_BITS;
-       unsigned pack_id : PACK_ID_BITS;
+       uint32_t type : TYPE_BITS,
+               pack_id : PACK_ID_BITS,
+               depth : DEPTH_BITS;
        unsigned char sha1[20];
 };
 
@@ -1083,7 +1086,7 @@ static int store_object(
                unsigned pos = sizeof(hdr) - 1;
 
                delta_count_by_type[type]++;
-               last->depth++;
+               e->depth = last->depth + 1;
 
                hdrlen = encode_header(OBJ_OFS_DELTA, deltalen, hdr);
                write_or_die(pack_data->pack_fd, hdr, hdrlen);
@@ -1095,8 +1098,7 @@ static int store_object(
                write_or_die(pack_data->pack_fd, hdr + pos, sizeof(hdr) - pos);
                pack_size += sizeof(hdr) - pos;
        } else {
-               if (last)
-                       last->depth = 0;
+               e->depth = 0;
                hdrlen = encode_header(type, dat->len, hdr);
                write_or_die(pack_data->pack_fd, hdr, hdrlen);
                pack_size += hdrlen;
@@ -1111,11 +1113,10 @@ static int store_object(
                if (last->no_swap) {
                        last->data = *dat;
                } else {
-                       struct strbuf tmp = *dat;
-                       *dat = last->data;
-                       last->data = tmp;
+                       strbuf_swap(&last->data, dat);
                }
                last->offset = e->offset;
+               last->depth = e->depth;
        }
        return 0;
 }
@@ -1162,7 +1163,7 @@ static void load_tree(struct tree_entry *root)
        if (myoe && myoe->pack_id != MAX_PACK_ID) {
                if (myoe->type != OBJ_TREE)
                        die("Not a tree: %s", sha1_to_hex(sha1));
-               t->delta_depth = 0;
+               t->delta_depth = myoe->depth;
                buf = gfi_unpack_entry(myoe, &size);
        } else {
                enum object_type type;
@@ -1564,7 +1565,7 @@ static int read_next_command(void)
                } else {
                        struct recent_command *rc;
 
-                       strbuf_detach(&command_buf);
+                       strbuf_detach(&command_buf, NULL);
                        stdin_eof = strbuf_getline(&command_buf, stdin, '\n');
                        if (stdin_eof)
                                return EOF;
@@ -1618,6 +1619,7 @@ static void cmd_data(struct strbuf *sb)
                char *term = xstrdup(command_buf.buf + 5 + 2);
                size_t term_len = command_buf.len - 5 - 2;
 
+               strbuf_detach(&command_buf, NULL);
                for (;;) {
                        if (strbuf_getline(&command_buf, stdin, '\n') == EOF)
                                die("EOF in data (terminator '%s' not found)", term);
@@ -1761,7 +1763,7 @@ static void load_branch(struct branch *b)
 static void file_change_m(struct branch *b)
 {
        const char *p = command_buf.buf + 2;
-       char *p_uq;
+       static struct strbuf uq = STRBUF_INIT;
        const char *endp;
        struct object_entry *oe = oe;
        unsigned char sha1[20];
@@ -1799,25 +1801,27 @@ static void file_change_m(struct branch *b)
        if (*p++ != ' ')
                die("Missing space after SHA1: %s", command_buf.buf);
 
-       p_uq = unquote_c_style(p, &endp);
-       if (p_uq) {
+       strbuf_reset(&uq);
+       if (!unquote_c_style(&uq, p, &endp)) {
                if (*endp)
                        die("Garbage after path in: %s", command_buf.buf);
-               p = p_uq;
+               p = uq.buf;
        }
 
        if (inline_data) {
                static struct strbuf buf = STRBUF_INIT;
 
-               if (!p_uq)
-                       p = p_uq = xstrdup(p);
+               if (p != uq.buf) {
+                       strbuf_addstr(&uq, p);
+                       p = uq.buf;
+               }
                read_next_command();
                cmd_data(&buf);
                store_object(OBJ_BLOB, &buf, &last_blob, sha1, 0);
        } else if (oe) {
                if (oe->type != OBJ_BLOB)
                        die("Not a blob (actually a %s): %s",
-                               command_buf.buf, typename(oe->type));
+                               typename(oe->type), command_buf.buf);
        } else {
                enum object_type type = sha1_object_info(sha1, NULL);
                if (type < 0)
@@ -1828,56 +1832,54 @@ static void file_change_m(struct branch *b)
        }
 
        tree_content_set(&b->branch_tree, p, sha1, S_IFREG | mode, NULL);
-       free(p_uq);
 }
 
 static void file_change_d(struct branch *b)
 {
        const char *p = command_buf.buf + 2;
-       char *p_uq;
+       static struct strbuf uq = STRBUF_INIT;
        const char *endp;
 
-       p_uq = unquote_c_style(p, &endp);
-       if (p_uq) {
+       strbuf_reset(&uq);
+       if (!unquote_c_style(&uq, p, &endp)) {
                if (*endp)
                        die("Garbage after path in: %s", command_buf.buf);
-               p = p_uq;
+               p = uq.buf;
        }
        tree_content_remove(&b->branch_tree, p, NULL);
-       free(p_uq);
 }
 
 static void file_change_cr(struct branch *b, int rename)
 {
        const char *s, *d;
-       char *s_uq, *d_uq;
+       static struct strbuf s_uq = STRBUF_INIT;
+       static struct strbuf d_uq = STRBUF_INIT;
        const char *endp;
        struct tree_entry leaf;
 
        s = command_buf.buf + 2;
-       s_uq = unquote_c_style(s, &endp);
-       if (s_uq) {
+       strbuf_reset(&s_uq);
+       if (!unquote_c_style(&s_uq, s, &endp)) {
                if (*endp != ' ')
                        die("Missing space after source: %s", command_buf.buf);
-       }
-       else {
+       } else {
                endp = strchr(s, ' ');
                if (!endp)
                        die("Missing space after source: %s", command_buf.buf);
-               s_uq = xmemdupz(s, endp - s);
+               strbuf_add(&s_uq, s, endp - s);
        }
-       s = s_uq;
+       s = s_uq.buf;
 
        endp++;
        if (!*endp)
                die("Missing dest: %s", command_buf.buf);
 
        d = endp;
-       d_uq = unquote_c_style(d, &endp);
-       if (d_uq) {
+       strbuf_reset(&d_uq);
+       if (!unquote_c_style(&d_uq, d, &endp)) {
                if (*endp)
                        die("Garbage after dest in: %s", command_buf.buf);
-               d = d_uq;
+               d = d_uq.buf;
        }
 
        memset(&leaf, 0, sizeof(leaf));
@@ -1891,9 +1893,6 @@ static void file_change_cr(struct branch *b, int rename)
                leaf.versions[1].sha1,
                leaf.versions[1].mode,
                leaf.tree);
-
-       free(s_uq);
-       free(d_uq);
 }
 
 static void file_change_deleteall(struct branch *b)
@@ -2293,8 +2292,11 @@ int main(int argc, const char **argv)
                }
                else if (!prefixcmp(a, "--max-pack-size="))
                        max_packsize = strtoumax(a + 16, NULL, 0) * 1024 * 1024;
-               else if (!prefixcmp(a, "--depth="))
+               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="))