eftshift0
eftshift0

Reputation: 30307

git api - how to get parents (and their trees) of a commit?

I am working on a new git built-in. I am taking a commit (that I am pulling using lookup_commit_reference_by_name) and then I want to go through the parents to check their trees. I try to get the tree object with get_commit_tree, unfortunately it fails to provide the tree object. What am I doing wrong? Here's the built-in code that you could use to reproduce (working on git repo, by the way):

int cmd_blahblah(int argc, const char **argv, const char *prefix)
{
    struct commit *a_commit;
    struct commit_list *i;
    
    a_commit = lookup_commit_reference_by_name("f64d4ca8d65bdca39da444d24bde94864ac01bb1");
    for (i = a_commit->parents; i; i = i->next) {
        struct tree *tree;
        struct commit *parent_commit = i->item;
        printf("parent commit: %s\n", oid_to_hex(&parent_commit->object.oid));
        tree = get_commit_tree(parent_commit);
        if (tree) {
            printf("Got the tree\n");
            printf("\ttree: %s\n", oid_to_hex(&tree->object.oid));
        } else {
            printf("Don't have a tree\n");
            return -1;
        }
    }
    return 0;
}

The output?

23:12 $ ../git blahblah
parent commit: 3dcec76d9df911ed8321007b1d197c1a206dc164
Don't have a tree

Upvotes: 0

Views: 165

Answers (1)

mmlr
mmlr

Reputation: 2165

The commits in the a_commit->parents commit_list are unparsed. They have none of their pointed to elements allocated or filled out, including their tree objects.

Use parse_commit(parent_commit) to fully parse the parent commit before trying to get its tree. The current parse status can be gleaned from commit->object.parsed.

Adding the parse_commit call to your code before the line get_commit_tree(parent_commit) leads to the desired output:

$ ../git blahblah
parent commit: 3dcec76d9df911ed8321007b1d197c1a206dc164
Got the tree
        tree: 17f1b818715fb25bbdf8c9f83261c9ce9317fd31
parent commit: 83d5e3341b69b3116675f13d2fab208a12c79e27
Got the tree
        tree: 9573b8a92526089f11764672741eb875b73b17c7

If you think about it, the parent commits couldn't really be parsed by default, as that would mean also their parents would need to be parsed and so on...

The call to parse_commit eventually ends up at parse_commit_buffer where the parent commit list, tree and date get set.

Upvotes: 1

Related Questions