]> git.ipfire.org Git - thirdparty/git.git/blobdiff - commit.c
config: do not leak excludes_file
[thirdparty/git.git] / commit.c
index 59b6c3e45525c5f5c1d19577612364992e245a6d..e433c33bb01fa6e3688a0b163c44d62f204d62d0 100644 (file)
--- a/commit.c
+++ b/commit.c
@@ -59,6 +59,14 @@ struct commit *lookup_commit_or_die(const struct object_id *oid, const char *ref
        return c;
 }
 
+struct commit *lookup_commit_object(struct repository *r,
+                                   const struct object_id *oid)
+{
+       struct object *obj = parse_object(r, oid);
+       return obj ? object_as_type(obj, OBJ_COMMIT, 0) : NULL;
+
+}
+
 struct commit *lookup_commit(struct repository *r, const struct object_id *oid)
 {
        struct object *obj = lookup_object(r, oid);
@@ -120,6 +128,17 @@ int commit_graft_pos(struct repository *r, const struct object_id *oid)
                       commit_graft_oid_access);
 }
 
+static void unparse_commit(struct repository *r, const struct object_id *oid)
+{
+       struct commit *c = lookup_commit(r, oid);
+
+       if (!c->object.parsed)
+               return;
+       free_commit_list(c->parents);
+       c->parents = NULL;
+       c->object.parsed = 0;
+}
+
 int register_commit_graft(struct repository *r, struct commit_graft *graft,
                          int ignore_dups)
 {
@@ -145,6 +164,7 @@ int register_commit_graft(struct repository *r, struct commit_graft *graft,
                        (r->parsed_objects->grafts_nr - pos - 1) *
                        sizeof(*r->parsed_objects->grafts));
        r->parsed_objects->grafts[pos] = graft;
+       unparse_commit(r, &graft->oid);
        return 0;
 }
 
@@ -253,8 +273,10 @@ void reset_commit_grafts(struct repository *r)
 {
        int i;
 
-       for (i = 0; i < r->parsed_objects->grafts_nr; i++)
+       for (i = 0; i < r->parsed_objects->grafts_nr; i++) {
+               unparse_commit(r, &r->parsed_objects->grafts[i]->oid);
                free(r->parsed_objects->grafts[i]);
+       }
        r->parsed_objects->grafts_nr = 0;
        r->parsed_objects->commit_graft_prepared = 0;
 }
@@ -407,17 +429,14 @@ int parse_commit_buffer(struct repository *r, struct commit *item, const void *b
 
        if (item->object.parsed)
                return 0;
-
-       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;
-       }
+       /*
+        * 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) ||
@@ -489,6 +508,17 @@ int repo_parse_commit_internal(struct repository *r,
        enum object_type type;
        void *buffer;
        unsigned long size;
+       struct object_info oi = {
+               .typep = &type,
+               .sizep = &size,
+               .contentp = &buffer,
+       };
+       /*
+        * Git does not support partial clones that exclude commits, so set
+        * OBJECT_INFO_SKIP_FETCH_OBJECT to fail fast when an object is missing.
+        */
+       int flags = OBJECT_INFO_LOOKUP_REPLACE | OBJECT_INFO_SKIP_FETCH_OBJECT |
+               OBJECT_INFO_DIE_IF_CORRUPT;
        int ret;
 
        if (!item)
@@ -497,8 +527,8 @@ int repo_parse_commit_internal(struct repository *r,
                return 0;
        if (use_commit_graph && parse_commit_in_graph(r, item))
                return 0;
-       buffer = repo_read_object_file(r, &item->object.oid, &type, &size);
-       if (!buffer)
+
+       if (oid_object_info_extended(r, &item->object.oid, &oi, flags) < 0)
                return quiet_on_missing ? -1 :
                        error("Could not read %s",
                             oid_to_hex(&item->object.oid));
@@ -631,10 +661,11 @@ struct commit_list * commit_list_insert_by_date(struct commit *item, struct comm
        return commit_list_insert(item, pp);
 }
 
-static int commit_list_compare_by_date(const void *a, const void *b)
+static int commit_list_compare_by_date(const struct commit_list *a,
+                                      const struct commit_list *b)
 {
-       timestamp_t a_date = ((const struct commit_list *)a)->item->date;
-       timestamp_t b_date = ((const struct commit_list *)b)->item->date;
+       timestamp_t a_date = a->item->date;
+       timestamp_t b_date = b->item->date;
        if (a_date < b_date)
                return 1;
        if (a_date > b_date)
@@ -642,20 +673,11 @@ static int commit_list_compare_by_date(const void *a, const void *b)
        return 0;
 }
 
-static void *commit_list_get_next(const void *a)
-{
-       return ((const struct commit_list *)a)->next;
-}
-
-static void commit_list_set_next(void *a, void *next)
-{
-       ((struct commit_list *)a)->next = next;
-}
+DEFINE_LIST_SORT(static, commit_list_sort, struct commit_list, next);
 
 void commit_list_sort_by_date(struct commit_list **list)
 {
-       *list = llist_mergesort(*list, commit_list_get_next, commit_list_set_next,
-                               commit_list_compare_by_date);
+       commit_list_sort(list, commit_list_compare_by_date);
 }
 
 struct commit *pop_most_recent_commit(struct commit_list **list,
@@ -690,8 +712,10 @@ static void clear_commit_marks_1(struct commit_list **plist,
                if (!parents)
                        return;
 
-               while ((parents = parents->next))
-                       commit_list_insert(parents->item, plist);
+               while ((parents = parents->next)) {
+                       if (parents->item->object.flags & mark)
+                               commit_list_insert(parents->item, plist);
+               }
 
                commit = commit->parents->item;
        }
@@ -948,8 +972,9 @@ static void add_one_commit(struct object_id *oid, struct rev_collect *revs)
 }
 
 static int collect_one_reflog_ent(struct object_id *ooid, struct object_id *noid,
-                                 const char *ident, timestamp_t timestamp,
-                                 int tz, const char *message, void *cbdata)
+                                 const char *ident UNUSED,
+                                 timestamp_t timestamp UNUSED, int tz UNUSED,
+                                 const char *message UNUSED, void *cbdata)
 {
        struct rev_collect *revs = cbdata;
 
@@ -1008,6 +1033,7 @@ struct commit *get_fork_point(const char *refname, struct commit *commit)
        ret = bases->item;
 
 cleanup_return:
+       free(revs.commit);
        free_commit_list(bases);
        free(full_refname);
        return ret;
@@ -1515,7 +1541,7 @@ static int verify_utf8(struct strbuf *buf)
 static const char commit_utf8_warn[] =
 N_("Warning: commit message did not conform to UTF-8.\n"
    "You may want to amend it after fixing the message, or set the config\n"
-   "variable i18n.commitencoding to the encoding your project uses.\n");
+   "variable i18n.commitEncoding to the encoding your project uses.\n");
 
 int commit_tree_extended(const char *msg, size_t msg_len,
                         const struct object_id *tree,