Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tag: v1.6.6.1
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 136 lines (114 sloc) 3.742 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
/*
* GIT - The information manager from hell
*
* Copyright (C) Linus Torvalds, 2005
*/
#include "cache.h"
#include "commit.h"
#include "tree.h"
#include "builtin.h"
#include "utf8.h"

#define BLOCKING (1ul << 14)

/*
* FIXME! Share the code with "write-tree.c"
*/
static void check_valid(unsigned char *sha1, enum object_type expect)
{
enum object_type type = sha1_object_info(sha1, NULL);
if (type < 0)
die("%s is not a valid object", sha1_to_hex(sha1));
if (type != expect)
die("%s is not a valid '%s' object", sha1_to_hex(sha1),
typename(expect));
}

static const char commit_tree_usage[] = "git commit-tree <sha1> [-p <sha1>]* < changelog";

static void new_parent(struct commit *parent, struct commit_list **parents_p)
{
unsigned char *sha1 = parent->object.sha1;
struct commit_list *parents;
for (parents = *parents_p; parents; parents = parents->next) {
if (parents->item == parent) {
error("duplicate parent %s ignored", sha1_to_hex(sha1));
return;
}
parents_p = &parents->next;
}
commit_list_insert(parent, parents_p);
}

static const char commit_utf8_warn[] =
"Warning: commit message does 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";

int commit_tree(const char *msg, unsigned char *tree,
struct commit_list *parents, unsigned char *ret,
const char *author)
{
int result;
int encoding_is_utf8;
struct strbuf buffer;

check_valid(tree, OBJ_TREE);

/* Not having i18n.commitencoding is the same as having utf-8 */
encoding_is_utf8 = is_encoding_utf8(git_commit_encoding);

strbuf_init(&buffer, 8192); /* should avoid reallocs for the headers */
strbuf_addf(&buffer, "tree %s\n", sha1_to_hex(tree));

/*
* NOTE! This ordering means that the same exact tree merged with a
* different order of parents will be a _different_ changeset even
* if everything else stays the same.
*/
while (parents) {
struct commit_list *next = parents->next;
strbuf_addf(&buffer, "parent %s\n",
sha1_to_hex(parents->item->object.sha1));
free(parents);
parents = next;
}

/* Person/date information */
if (!author)
author = git_author_info(IDENT_ERROR_ON_NO_NAME);
strbuf_addf(&buffer, "author %s\n", author);
strbuf_addf(&buffer, "committer %s\n", git_committer_info(IDENT_ERROR_ON_NO_NAME));
if (!encoding_is_utf8)
strbuf_addf(&buffer, "encoding %s\n", git_commit_encoding);
strbuf_addch(&buffer, '\n');

/* And add the comment */
strbuf_addstr(&buffer, msg);

/* And check the encoding */
if (encoding_is_utf8 && !is_utf8(buffer.buf))
fprintf(stderr, commit_utf8_warn);

result = write_sha1_file(buffer.buf, buffer.len, commit_type, ret);
strbuf_release(&buffer);
return result;
}

int cmd_commit_tree(int argc, const char **argv, const char *prefix)
{
int i;
struct commit_list *parents = NULL;
unsigned char tree_sha1[20];
unsigned char commit_sha1[20];
struct strbuf buffer = STRBUF_INIT;

git_config(git_default_config, NULL);

if (argc < 2 || !strcmp(argv[1], "-h"))
usage(commit_tree_usage);
if (get_sha1(argv[1], tree_sha1))
die("Not a valid object name %s", argv[1]);

for (i = 2; i < argc; i += 2) {
unsigned char sha1[20];
const char *a, *b;
a = argv[i]; b = argv[i+1];
if (!b || strcmp(a, "-p"))
usage(commit_tree_usage);

if (get_sha1(b, sha1))
die("Not a valid object name %s", b);
check_valid(sha1, OBJ_COMMIT);
new_parent(lookup_commit(sha1), &parents);
}

if (strbuf_read(&buffer, 0, 0) < 0)
die_errno("git commit-tree: failed to read");

if (!commit_tree(buffer.buf, tree_sha1, parents, commit_sha1, NULL)) {
printf("%s\n", sha1_to_hex(commit_sha1));
return 0;
}
else
return 1;
}
Something went wrong with that request. Please try again.