t: add means to disable '-x' tracing for individual test scripts
[gitweb.git] / commit.c
index 1a0a9f23e9b4c99c0346e28de7fe58cb67fa0229..e8a49b9c84bf24a6ef1455f975aa9e28e2156d77 100644 (file)
--- a/commit.c
+++ b/commit.c
@@ -126,10 +126,8 @@ int register_commit_graft(struct commit_graft *graft, int ignore_dups)
        ALLOC_GROW(commit_graft, commit_graft_nr + 1, commit_graft_alloc);
        commit_graft_nr++;
        if (pos < commit_graft_nr)
-               memmove(commit_graft + pos + 1,
-                       commit_graft + pos,
-                       (commit_graft_nr - pos - 1) *
-                       sizeof(*commit_graft));
+               MOVE_ARRAY(commit_graft + pos + 1, commit_graft + pos,
+                          commit_graft_nr - pos - 1);
        commit_graft[pos] = graft;
        return 0;
 }
@@ -137,31 +135,38 @@ int register_commit_graft(struct commit_graft *graft, int ignore_dups)
 struct commit_graft *read_graft_line(struct strbuf *line)
 {
        /* The format is just "Commit Parent1 Parent2 ...\n" */
-       int i;
+       int i, phase;
+       const char *tail = NULL;
        struct commit_graft *graft = NULL;
-       const int entry_size = GIT_SHA1_HEXSZ + 1;
+       struct object_id dummy_oid, *oid;
 
        strbuf_rtrim(line);
        if (!line->len || line->buf[0] == '#')
                return NULL;
-       if ((line->len + 1) % entry_size)
-               goto bad_graft_data;
-       i = (line->len + 1) / entry_size - 1;
-       graft = xmalloc(st_add(sizeof(*graft), st_mult(GIT_SHA1_RAWSZ, i)));
-       graft->nr_parent = i;
-       if (get_oid_hex(line->buf, &graft->oid))
-               goto bad_graft_data;
-       for (i = GIT_SHA1_HEXSZ; i < line->len; i += entry_size) {
-               if (line->buf[i] != ' ')
-                       goto bad_graft_data;
-               if (get_sha1_hex(line->buf + i + 1, graft->parent[i/entry_size].hash))
+       /*
+        * phase 0 verifies line, counts hashes in line and allocates graft
+        * phase 1 fills graft
+        */
+       for (phase = 0; phase < 2; phase++) {
+               oid = graft ? &graft->oid : &dummy_oid;
+               if (parse_oid_hex(line->buf, oid, &tail))
                        goto bad_graft_data;
+               for (i = 0; *tail != '\0'; i++) {
+                       oid = graft ? &graft->parent[i] : &dummy_oid;
+                       if (!isspace(*tail++) || parse_oid_hex(tail, oid, &tail))
+                               goto bad_graft_data;
+               }
+               if (!graft) {
+                       graft = xmalloc(st_add(sizeof(*graft),
+                                              st_mult(sizeof(struct object_id), i)));
+                       graft->nr_parent = i;
+               }
        }
        return graft;
 
 bad_graft_data:
        error("bad graft data: %s", line->buf);
-       free(graft);
+       assert(!graft);
        return NULL;
 }
 
@@ -540,7 +545,7 @@ void clear_commit_marks_many(int nr, struct commit **commit, unsigned int mark)
        struct commit_list *list = NULL;
 
        while (nr--) {
-               commit_list_insert(*commit, &list);
+               clear_commit_marks_1(&list, *commit, mark);
                commit++;
        }
        while (list)
@@ -552,20 +557,6 @@ void clear_commit_marks(struct commit *commit, unsigned int mark)
        clear_commit_marks_many(1, &commit, mark);
 }
 
-void clear_commit_marks_for_object_array(struct object_array *a, unsigned mark)
-{
-       struct object *object;
-       struct commit *commit;
-       unsigned int i;
-
-       for (i = 0; i < a->nr; i++) {
-               object = a->objects[i].item;
-               commit = lookup_commit_reference_gently(&object->oid, 1);
-               if (commit)
-                       clear_commit_marks(commit, mark);
-       }
-}
-
 struct commit *pop_commit(struct commit_list **stack)
 {
        struct commit_list *top = *stack;
@@ -922,8 +913,7 @@ static int remove_redundant(struct commit **array, int cnt)
                        if (work[j]->object.flags & PARENT1)
                                redundant[filled_index[j]] = 1;
                clear_commit_marks(array[i], all_flags);
-               for (j = 0; j < filled; j++)
-                       clear_commit_marks(work[j], all_flags);
+               clear_commit_marks_many(filled, work, all_flags);
                free_commit_list(common);
        }
 
@@ -1079,9 +1069,17 @@ struct commit_list *reduce_heads(struct commit_list *heads)
        num_head = remove_redundant(array, num_head);
        for (i = 0; i < num_head; i++)
                tail = &commit_list_insert(array[i], tail)->next;
+       free(array);
        return result;
 }
 
+void reduce_heads_replace(struct commit_list **heads)
+{
+       struct commit_list *result = reduce_heads(*heads);
+       free_commit_list(*heads);
+       *heads = result;
+}
+
 static const char gpg_sig_header[] = "gpgsig";
 static const int gpg_sig_header_len = sizeof(gpg_sig_header) - 1;
 
@@ -1380,9 +1378,8 @@ void free_commit_extra_headers(struct commit_extra_header *extra)
        }
 }
 
-int commit_tree(const char *msg, size_t msg_len,
-               const unsigned char *tree,
-               struct commit_list *parents, unsigned char *ret,
+int commit_tree(const char *msg, size_t msg_len, const struct object_id *tree,
+               struct commit_list *parents, struct object_id *ret,
                const char *author, const char *sign_commit)
 {
        struct commit_extra_header *extra = NULL, **tail = &extra;
@@ -1511,8 +1508,8 @@ N_("Warning: commit message did not conform to UTF-8.\n"
    "variable i18n.commitencoding to the encoding your project uses.\n");
 
 int commit_tree_extended(const char *msg, size_t msg_len,
-                        const unsigned char *tree,
-                        struct commit_list *parents, unsigned char *ret,
+                        const struct object_id *tree,
+                        struct commit_list *parents, struct object_id *ret,
                         const char *author, const char *sign_commit,
                         struct commit_extra_header *extra)
 {
@@ -1520,7 +1517,7 @@ int commit_tree_extended(const char *msg, size_t msg_len,
        int encoding_is_utf8;
        struct strbuf buffer;
 
-       assert_sha1_type(tree, OBJ_TREE);
+       assert_sha1_type(tree->hash, OBJ_TREE);
 
        if (memchr(msg, '\0', msg_len))
                return error("a NUL byte in commit log message not allowed.");
@@ -1529,7 +1526,7 @@ int commit_tree_extended(const char *msg, size_t msg_len,
        encoding_is_utf8 = is_encoding_utf8(git_commit_encoding);
 
        strbuf_init(&buffer, 8192); /* should avoid reallocs for the headers */
-       strbuf_addf(&buffer, "tree %s\n", sha1_to_hex(tree));
+       strbuf_addf(&buffer, "tree %s\n", oid_to_hex(tree));
 
        /*
         * NOTE! This ordering means that the same exact tree merged with a
@@ -1563,10 +1560,13 @@ int commit_tree_extended(const char *msg, size_t msg_len,
        if (encoding_is_utf8 && !verify_utf8(&buffer))
                fprintf(stderr, _(commit_utf8_warn));
 
-       if (sign_commit && do_sign_commit(&buffer, sign_commit))
-               return -1;
+       if (sign_commit && do_sign_commit(&buffer, sign_commit)) {
+               result = -1;
+               goto out;
+       }
 
-       result = write_sha1_file(buffer.buf, buffer.len, commit_type, ret);
+       result = write_object_file(buffer.buf, buffer.len, commit_type, ret);
+out:
        strbuf_release(&buffer);
        return result;
 }