]> git.ipfire.org Git - thirdparty/git.git/blobdiff - commit.c
t602[1236], t6034: modernize test formatting
[thirdparty/git.git] / commit.c
index 40890ae7ce8a48a2da06bcde6fc5a9db77260707..434ec030d6b2a0074c46c376c6322c92fd5c8a39 100644 (file)
--- a/commit.c
+++ b/commit.c
@@ -19,6 +19,7 @@
 #include "advice.h"
 #include "refs.h"
 #include "commit-reach.h"
+#include "run-command.h"
 
 static struct commit_extra_header *read_commit_extra_header_lines(const char *buf, size_t len, const char **);
 
@@ -401,10 +402,22 @@ int parse_commit_buffer(struct repository *r, struct commit *item, const void *b
        struct commit_graft *graft;
        const int tree_entry_len = the_hash_algo->hexsz + 5;
        const int parent_entry_len = the_hash_algo->hexsz + 7;
+       struct tree *tree;
 
        if (item->object.parsed)
                return 0;
-       item->object.parsed = 1;
+
+       if (item->parents) {
+               /*
+                * Presumably this is leftover from an earlier failed parse;
+                * clear it out in preparation for us re-parsing (we'll hit the
+                * same error, but that's good, since it lets our caller know
+                * the result cannot be trusted.
+                */
+               free_commit_list(item->parents);
+               item->parents = NULL;
+       }
+
        tail += size;
        if (tail <= bufptr + tree_entry_len + 1 || memcmp(bufptr, "tree ", 5) ||
                        bufptr[tree_entry_len] != '\n')
@@ -412,7 +425,12 @@ int parse_commit_buffer(struct repository *r, struct commit *item, const void *b
        if (get_oid_hex(bufptr + 5, &parent) < 0)
                return error("bad tree pointer in commit %s",
                             oid_to_hex(&item->object.oid));
-       set_commit_tree(item, lookup_tree(r, &parent));
+       tree = lookup_tree(r, &parent);
+       if (!tree)
+               return error("bad tree pointer %s in commit %s",
+                            oid_to_hex(&parent),
+                            oid_to_hex(&item->object.oid));
+       set_commit_tree(item, tree);
        bufptr += tree_entry_len + 1; /* "tree " + "hex sha1" + "\n" */
        pptr = &item->parents;
 
@@ -432,8 +450,11 @@ int parse_commit_buffer(struct repository *r, struct commit *item, const void *b
                if (graft && (graft->nr_parent < 0 || grafts_replace_parents))
                        continue;
                new_parent = lookup_commit(r, &parent);
-               if (new_parent)
-                       pptr = &commit_list_insert(new_parent, pptr)->next;
+               if (!new_parent)
+                       return error("bad parent %s in commit %s",
+                                    oid_to_hex(&parent),
+                                    oid_to_hex(&item->object.oid));
+               pptr = &commit_list_insert(new_parent, pptr)->next;
        }
        if (graft) {
                int i;
@@ -442,7 +463,9 @@ int parse_commit_buffer(struct repository *r, struct commit *item, const void *b
                        new_parent = lookup_commit(r,
                                                   &graft->parent[i]);
                        if (!new_parent)
-                               continue;
+                               return error("bad graft parent %s in commit %s",
+                                            oid_to_hex(&graft->parent[i]),
+                                            oid_to_hex(&item->object.oid));
                        pptr = &commit_list_insert(new_parent, pptr)->next;
                }
        }
@@ -451,6 +474,7 @@ int parse_commit_buffer(struct repository *r, struct commit *item, const void *b
        if (check_graph)
                load_commit_graph_info(r, item);
 
+       item->object.parsed = 1;
        return 0;
 }
 
@@ -1581,3 +1605,26 @@ size_t ignore_non_trailer(const char *buf, size_t len)
        }
        return boc ? len - boc : len - cutoff;
 }
+
+int run_commit_hook(int editor_is_used, const char *index_file,
+                   const char *name, ...)
+{
+       struct argv_array hook_env = ARGV_ARRAY_INIT;
+       va_list args;
+       int ret;
+
+       argv_array_pushf(&hook_env, "GIT_INDEX_FILE=%s", index_file);
+
+       /*
+        * Let the hook know that no editor will be launched.
+        */
+       if (!editor_is_used)
+               argv_array_push(&hook_env, "GIT_EDITOR=:");
+
+       va_start(args, name);
+       ret = run_hook_ve(hook_env.argv,name, args);
+       va_end(args);
+       argv_array_clear(&hook_env);
+
+       return ret;
+}