]> git.ipfire.org Git - thirdparty/git.git/blobdiff - commit.c
object-name.h: move declarations for object-name.c functions from cache.h
[thirdparty/git.git] / commit.c
index 59b6c3e45525c5f5c1d19577612364992e245a6d..bad31c423a46f0a28c2f576a2d178ece919d4eb1 100644 (file)
--- a/commit.c
+++ b/commit.c
@@ -2,7 +2,11 @@
 #include "tag.h"
 #include "commit.h"
 #include "commit-graph.h"
+#include "environment.h"
+#include "gettext.h"
+#include "hex.h"
 #include "repository.h"
+#include "object-name.h"
 #include "object-store.h"
 #include "pkt-line.h"
 #include "utf8.h"
@@ -20,6 +24,7 @@
 #include "refs.h"
 #include "commit-reach.h"
 #include "run-command.h"
+#include "setup.h"
 #include "shallow.h"
 #include "hook.h"
 
@@ -59,6 +64,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);
@@ -72,10 +85,10 @@ struct commit *lookup_commit_reference_by_name(const char *name)
        struct object_id oid;
        struct commit *commit;
 
-       if (get_oid_committish(name, &oid))
+       if (repo_get_oid_committish(the_repository, name, &oid))
                return NULL;
        commit = lookup_commit_reference(the_repository, &oid);
-       if (parse_commit(commit))
+       if (repo_parse_commit(the_repository, commit))
                return NULL;
        return commit;
 }
@@ -120,6 +133,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 +169,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 +278,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;
 }
@@ -360,7 +387,7 @@ struct tree *repo_get_commit_tree(struct repository *r,
 
 struct object_id *get_commit_tree_oid(const struct commit *commit)
 {
-       struct tree *tree = get_commit_tree(commit);
+       struct tree *tree = repo_get_commit_tree(the_repository, commit);
        return tree ? &tree->object.oid : NULL;
 }
 
@@ -407,17 +434,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 +513,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 +532,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));
@@ -525,7 +560,7 @@ int repo_parse_commit_gently(struct repository *r,
 
 void parse_commit_or_die(struct commit *item)
 {
-       if (parse_commit(item))
+       if (repo_parse_commit(the_repository, item))
                die("unable to parse commit %s",
                    item ? oid_to_hex(&item->object.oid) : "(null)");
 }
@@ -631,10 +666,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 +678,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,
@@ -666,7 +693,7 @@ struct commit *pop_most_recent_commit(struct commit_list **list,
 
        while (parents) {
                struct commit *commit = parents->item;
-               if (!parse_commit(commit) && !(commit->object.flags & mark)) {
+               if (!repo_parse_commit(the_repository, commit) && !(commit->object.flags & mark)) {
                        commit->object.flags |= mark;
                        commit_list_insert_by_date(commit, list);
                }
@@ -690,8 +717,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;
        }
@@ -738,7 +767,8 @@ define_commit_slab(author_date_slab, timestamp_t);
 void record_author_date(struct author_date_slab *author_date,
                        struct commit *commit)
 {
-       const char *buffer = get_commit_buffer(commit, NULL);
+       const char *buffer = repo_get_commit_buffer(the_repository, commit,
+                                                   NULL);
        struct ident_split ident;
        const char *ident_line;
        size_t ident_len;
@@ -758,7 +788,7 @@ void record_author_date(struct author_date_slab *author_date,
        *(author_date_slab_at(author_date, commit)) = date;
 
 fail_exit:
-       unuse_commit_buffer(commit, buffer);
+       repo_unuse_commit_buffer(the_repository, commit, buffer);
 }
 
 int compare_commits_by_author_date(const void *a_, const void *b_,
@@ -777,7 +807,8 @@ int compare_commits_by_author_date(const void *a_, const void *b_,
        return 0;
 }
 
-int compare_commits_by_gen_then_commit_date(const void *a_, const void *b_, void *unused)
+int compare_commits_by_gen_then_commit_date(const void *a_, const void *b_,
+                                           void *unused UNUSED)
 {
        const struct commit *a = a_, *b = b_;
        const timestamp_t generation_a = commit_graph_generation(a),
@@ -797,7 +828,8 @@ int compare_commits_by_gen_then_commit_date(const void *a_, const void *b_, void
        return 0;
 }
 
-int compare_commits_by_commit_date(const void *a_, const void *b_, void *unused)
+int compare_commits_by_commit_date(const void *a_, const void *b_,
+                                  void *unused UNUSED)
 {
        const struct commit *a = a_, *b = b_;
        /* newer commits with larger date first */
@@ -939,7 +971,7 @@ static void add_one_commit(struct object_id *oid, struct rev_collect *revs)
        commit = lookup_commit(the_repository, oid);
        if (!commit ||
            (commit->object.flags & TMP_MARK) ||
-           parse_commit(commit))
+           repo_parse_commit(the_repository, commit))
                return;
 
        ALLOC_GROW(revs->commit, revs->nr + 1, revs->alloc);
@@ -948,8 +980,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;
 
@@ -970,7 +1003,8 @@ struct commit *get_fork_point(const char *refname, struct commit *commit)
        struct commit *ret = NULL;
        char *full_refname;
 
-       switch (dwim_ref(refname, strlen(refname), &oid, &full_refname, 0)) {
+       switch (repo_dwim_ref(the_repository, refname, strlen(refname), &oid,
+                             &full_refname, 0)) {
        case 0:
                die("No such ref: '%s'", refname);
        case 1:
@@ -989,7 +1023,8 @@ struct commit *get_fork_point(const char *refname, struct commit *commit)
        for (i = 0; i < revs.nr; i++)
                revs.commit[i]->object.flags &= ~TMP_MARK;
 
-       bases = get_merge_bases_many(commit, revs.nr, revs.commit);
+       bases = repo_get_merge_bases_many(the_repository, commit, revs.nr,
+                                         revs.commit);
 
        /*
         * There should be one and only one merge base, when we found
@@ -1008,6 +1043,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;
@@ -1069,10 +1105,11 @@ int parse_signed_commit(const struct commit *commit,
                        const struct git_hash_algo *algop)
 {
        unsigned long size;
-       const char *buffer = get_commit_buffer(commit, &size);
+       const char *buffer = repo_get_commit_buffer(the_repository, commit,
+                                                   &size);
        int ret = parse_buffer_signed_by_header(buffer, size, payload, signature, algop);
 
-       unuse_commit_buffer(commit, buffer);
+       repo_unuse_commit_buffer(the_repository, commit, buffer);
        return ret;
 }
 
@@ -1183,7 +1220,8 @@ static void handle_signed_tag(struct commit *parent, struct commit_extra_header
        desc = merge_remote_util(parent);
        if (!desc || !desc->obj)
                return;
-       buf = read_object_file(&desc->obj->oid, &type, &size);
+       buf = repo_read_object_file(the_repository, &desc->obj->oid, &type,
+                                   &size);
        if (!buf || type != OBJ_TAG)
                goto free_return;
        if (!parse_signature(buf, size, &payload, &signature))
@@ -1245,7 +1283,8 @@ void verify_merge_signature(struct commit *commit, int verbosity,
 
        ret = check_commit_signature(commit, &signature_check);
 
-       find_unique_abbrev_r(hex, &commit->object.oid, DEFAULT_ABBREV);
+       repo_find_unique_abbrev_r(the_repository, hex, &commit->object.oid,
+                                 DEFAULT_ABBREV);
        switch (signature_check.result) {
        case 'G':
                if (ret || (check_trust && signature_check.trust_level < TRUST_MARGINAL))
@@ -1290,9 +1329,10 @@ struct commit_extra_header *read_commit_extra_headers(struct commit *commit,
 {
        struct commit_extra_header *extra = NULL;
        unsigned long size;
-       const char *buffer = get_commit_buffer(commit, &size);
+       const char *buffer = repo_get_commit_buffer(the_repository, commit,
+                                                   &size);
        extra = read_commit_extra_header_lines(buffer, size, exclude);
-       unuse_commit_buffer(commit, buffer);
+       repo_unuse_commit_buffer(the_repository, commit, buffer);
        return extra;
 }
 
@@ -1515,7 +1555,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,
@@ -1606,10 +1646,11 @@ struct commit *get_merge_parent(const char *name)
        struct object *obj;
        struct commit *commit;
        struct object_id oid;
-       if (get_oid(name, &oid))
+       if (repo_get_oid(the_repository, name, &oid))
                return NULL;
        obj = parse_object(the_repository, &oid);
-       commit = (struct commit *)peel_to_type(name, 0, obj, OBJ_COMMIT);
+       commit = (struct commit *)repo_peel_to_type(the_repository, name, 0,
+                                                   obj, OBJ_COMMIT);
        if (commit && !merge_remote_util(commit))
                set_merge_remote_desc(commit, name, obj);
        return commit;