blob: ecf42191da10cd2e87360f001d5493e792b9682e [file] [log] [blame]
Linus Torvalds8bc9a0c2005-04-07 15:16:10 -07001/*
2 * GIT - The information manager from hell
3 *
4 * Copyright (C) Linus Torvalds, 2005
5 */
Linus Torvaldse83c5162005-04-07 15:13:13 -07006#include "cache.h"
Brandon Williamsb2141fc2017-06-14 11:07:36 -07007#include "config.h"
Peter Eriksen8e440252006-04-02 14:44:09 +02008#include "commit.h"
9#include "tree.h"
Peter Eriksen6d96ac12006-05-23 14:15:33 +020010#include "builtin.h"
Johannes Schindelin9e832662006-12-22 22:06:08 +010011#include "utf8.h"
Junio C Hamanoba3c69a2011-10-05 17:23:20 -070012#include "gpg-interface.h"
Linus Torvaldse83c5162005-04-07 15:13:13 -070013
Junio C Hamano33e8fc82015-10-16 11:27:42 -070014static const char commit_tree_usage[] = "git commit-tree [(-p <sha1>)...] [-S[<keyid>]] [-m <message>] [-F <file>] <sha1>";
Junio C Hamanoc5bac172005-04-20 19:49:16 -070015
Nicolas Vigierd95bfb12013-11-05 00:14:41 +010016static const char *sign_commit;
17
Johannes Schindelinef98c5c2008-06-27 13:24:47 +010018static void new_parent(struct commit *parent, struct commit_list **parents_p)
Linus Torvaldsb3892372005-06-19 10:40:10 -070019{
brian m. carlsonf2fd0762015-11-10 02:22:28 +000020 struct object_id *oid = &parent->object.oid;
Johannes Schindelinef98c5c2008-06-27 13:24:47 +010021 struct commit_list *parents;
22 for (parents = *parents_p; parents; parents = parents->next) {
23 if (parents->item == parent) {
brian m. carlsonf2fd0762015-11-10 02:22:28 +000024 error("duplicate parent %s ignored", oid_to_hex(oid));
Johannes Schindelinef98c5c2008-06-27 13:24:47 +010025 return;
Linus Torvaldsb3892372005-06-19 10:40:10 -070026 }
Johannes Schindelinef98c5c2008-06-27 13:24:47 +010027 parents_p = &parents->next;
Linus Torvaldsb3892372005-06-19 10:40:10 -070028 }
Johannes Schindelinef98c5c2008-06-27 13:24:47 +010029 commit_list_insert(parent, parents_p);
Linus Torvaldsb3892372005-06-19 10:40:10 -070030}
31
Junio C Hamanoba3c69a2011-10-05 17:23:20 -070032static int commit_tree_config(const char *var, const char *value, void *cb)
33{
34 int status = git_gpg_config(var, value, NULL);
35 if (status)
36 return status;
37 return git_default_config(var, value, cb);
38}
39
Miklos Vajna7b9c0a62008-07-01 04:37:49 +020040int cmd_commit_tree(int argc, const char **argv, const char *prefix)
41{
Junio C Hamano79a93122011-11-09 11:33:55 -080042 int i, got_tree = 0;
Miklos Vajna7b9c0a62008-07-01 04:37:49 +020043 struct commit_list *parents = NULL;
brian m. carlson031cee52016-09-05 20:08:10 +000044 struct object_id tree_oid;
45 struct object_id commit_oid;
Miklos Vajna7b9c0a62008-07-01 04:37:49 +020046 struct strbuf buffer = STRBUF_INIT;
47
Junio C Hamanoba3c69a2011-10-05 17:23:20 -070048 git_config(commit_tree_config, NULL);
Miklos Vajna7b9c0a62008-07-01 04:37:49 +020049
Jonathan Nieder6e9daef2009-11-09 09:04:44 -060050 if (argc < 2 || !strcmp(argv[1], "-h"))
Miklos Vajna7b9c0a62008-07-01 04:37:49 +020051 usage(commit_tree_usage);
Miklos Vajna7b9c0a62008-07-01 04:37:49 +020052
Junio C Hamano79a93122011-11-09 11:33:55 -080053 for (i = 1; i < argc; i++) {
54 const char *arg = argv[i];
55 if (!strcmp(arg, "-p")) {
brian m. carlson031cee52016-09-05 20:08:10 +000056 struct object_id oid;
Junio C Hamano79a93122011-11-09 11:33:55 -080057 if (argc <= ++i)
58 usage(commit_tree_usage);
brian m. carlsone82caf32017-07-13 23:49:28 +000059 if (get_oid_commit(argv[i], &oid))
Junio C Hamano79a93122011-11-09 11:33:55 -080060 die("Not a valid object name %s", argv[i]);
brian m. carlsone816caa2018-03-12 02:27:42 +000061 assert_oid_type(&oid, OBJ_COMMIT);
brian m. carlsonbc832662017-05-06 22:10:10 +000062 new_parent(lookup_commit(&oid), &parents);
Junio C Hamano79a93122011-11-09 11:33:55 -080063 continue;
64 }
Miklos Vajna7b9c0a62008-07-01 04:37:49 +020065
René Scharfe8547e0f2014-12-24 01:18:11 +010066 if (skip_prefix(arg, "-S", &sign_commit))
Junio C Hamanoba3c69a2011-10-05 17:23:20 -070067 continue;
Junio C Hamanoba3c69a2011-10-05 17:23:20 -070068
Junio C Hamano55ca3f92013-12-13 15:40:35 -080069 if (!strcmp(arg, "--no-gpg-sign")) {
70 sign_commit = NULL;
71 continue;
72 }
73
Junio C Hamano96b8d932011-11-09 11:54:04 -080074 if (!strcmp(arg, "-m")) {
75 if (argc <= ++i)
76 usage(commit_tree_usage);
77 if (buffer.len)
78 strbuf_addch(&buffer, '\n');
79 strbuf_addstr(&buffer, argv[i]);
80 strbuf_complete_line(&buffer);
81 continue;
82 }
83
84 if (!strcmp(arg, "-F")) {
85 int fd;
86
87 if (argc <= ++i)
88 usage(commit_tree_usage);
89 if (buffer.len)
90 strbuf_addch(&buffer, '\n');
91 if (!strcmp(argv[i], "-"))
92 fd = 0;
93 else {
94 fd = open(argv[i], O_RDONLY);
95 if (fd < 0)
96 die_errno("git commit-tree: failed to open '%s'",
97 argv[i]);
98 }
99 if (strbuf_read(&buffer, fd, 0) < 0)
100 die_errno("git commit-tree: failed to read '%s'",
101 argv[i]);
102 if (fd && close(fd))
103 die_errno("git commit-tree: failed to close '%s'",
104 argv[i]);
Junio C Hamano96b8d932011-11-09 11:54:04 -0800105 continue;
106 }
107
brian m. carlsone82caf32017-07-13 23:49:28 +0000108 if (get_oid_tree(arg, &tree_oid))
Junio C Hamano79a93122011-11-09 11:33:55 -0800109 die("Not a valid object name %s", arg);
110 if (got_tree)
111 die("Cannot give more than one trees");
112 got_tree = 1;
Miklos Vajna7b9c0a62008-07-01 04:37:49 +0200113 }
114
Junio C Hamano96b8d932011-11-09 11:54:04 -0800115 if (!buffer.len) {
116 if (strbuf_read(&buffer, 0, 0) < 0)
117 die_errno("git commit-tree: failed to read");
118 }
Miklos Vajna7b9c0a62008-07-01 04:37:49 +0200119
Patryk Obara5078f342018-01-28 01:13:16 +0100120 if (commit_tree(buffer.buf, buffer.len, &tree_oid, parents, &commit_oid,
121 NULL, sign_commit)) {
Jonathan Nieder79bc2af2010-10-02 03:41:00 -0500122 strbuf_release(&buffer);
Junio C Hamano7561d9f2006-03-24 22:23:25 -0800123 return 1;
Jonathan Nieder79bc2af2010-10-02 03:41:00 -0500124 }
125
brian m. carlson031cee52016-09-05 20:08:10 +0000126 printf("%s\n", oid_to_hex(&commit_oid));
Jonathan Nieder79bc2af2010-10-02 03:41:00 -0500127 strbuf_release(&buffer);
128 return 0;
Linus Torvaldse83c5162005-04-07 15:13:13 -0700129}