Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can additional data be put into a git commit object?

Tags:

git

git-commit

On every tutorial site about git objects I'll see an example where git cat-file displays what the commit object itself looks like, and it's usually something like the following:

tree 552acd444696ccb1c3afe68a55ae8b20ece2b0e6
parent 6a1d380780a83ef5f49523777c5e8d801b7b9ba2
author John Doe <[email protected]> 1326496982 -0600
committer John Doe <[email protected]> 1326496982 -0600

Some commit message here.

If there were additional (single line) data fields at the top, would this confuse the git tools? I assume that even if it didn't, these fields wouldn't show up in git log.

If it can have additional fields, which git plumbing command would allow you to create that? git commit-tree doesn't seem that flexible.

like image 896
John O Avatar asked Nov 20 '13 15:11

John O


1 Answers

Yes, you can totally put more fields called “git commit extra headers” in there. They’ll show up with git cat-file -p, but the only way I see to get them in there in the first place with the standard git client is by editing the git source and recompiling.

In commit.h, there is a struct for extra headers, along with functions to add them when committing, and to read them out later.

struct commit_extra_header {
        struct commit_extra_header *next;
        char *key;
        char *value;
        size_t len;
};

int commit_tree_extended(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 *);

struct commit_extra_header *read_commit_extra_headers(struct commit *, const char **);

commit.c contains a list of ‘standard’ header fields:

static inline int standard_header_field(const char *field, size_t len)
{
        return ((len == 4 && !memcmp(field, "tree", 4)) ||
                (len == 6 && !memcmp(field, "parent", 6)) ||
                (len == 6 && !memcmp(field, "author", 6)) ||
                (len == 9 && !memcmp(field, "committer", 9)) ||
                (len == 8 && !memcmp(field, "encoding", 8)));
}

with everything else showing up as an ‘extra’ header.

Doing a quick grep of the source code, the only current use I found of this is the gpgsig header used to include GPG signatures on commits.

Kiln Harmony, now discontinued, used fields such as kilnhgusername and kilnhgrawdescription here.

like image 70
andrewdotn Avatar answered Oct 26 '22 07:10

andrewdotn