mirror of
https://github.com/git/git
synced 2024-08-27 19:49:21 +00:00
![Junio C Hamano](/assets/img/avatar_default.png)
The synopsys text and the usage string of subcommands that read list of things from the standard input are often shown like this: git gostak [--distim] < <list-of-doshes> This is problematic in a number of ways: * The way to use these commands is more often to feed them the output from another command, not feed them from a file. * Manual pages outside Git, commands that operate on the data read from the standard input, e.g "sort", "grep", "sed", etc., are not described with such a "< redirection-from-file" in their synopsys text. Our doing so introduces inconsistency. * We do not insist on where the output should go, by saying git gostak [--distim] < <list-of-doshes> > <output> * As it is our convention to enclose placeholders inside <braket>, the redirection operator followed by a placeholder filename becomes very hard to read, both in the documentation and in the help text. Let's clean them all up, after making sure that the documentation clearly describes the modes that take information from the standard input and what kind of things are expected on the input. [jc: stole example for fmt-merge-msg from Jonathan] Helped-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
134 lines
3.1 KiB
C
134 lines
3.1 KiB
C
/*
|
|
* 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"
|
|
#include "gpg-interface.h"
|
|
|
|
static const char commit_tree_usage[] = "git commit-tree [(-p <sha1>)...] [-S[<keyid>]] [-m <message>] [-F <file>] <sha1>";
|
|
|
|
static const char *sign_commit;
|
|
|
|
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 int commit_tree_config(const char *var, const char *value, void *cb)
|
|
{
|
|
int status = git_gpg_config(var, value, NULL);
|
|
if (status)
|
|
return status;
|
|
if (!strcmp(var, "commit.gpgsign")) {
|
|
sign_commit = git_config_bool(var, value) ? "" : NULL;
|
|
return 0;
|
|
}
|
|
return git_default_config(var, value, cb);
|
|
}
|
|
|
|
int cmd_commit_tree(int argc, const char **argv, const char *prefix)
|
|
{
|
|
int i, got_tree = 0;
|
|
struct commit_list *parents = NULL;
|
|
unsigned char tree_sha1[20];
|
|
unsigned char commit_sha1[20];
|
|
struct strbuf buffer = STRBUF_INIT;
|
|
|
|
git_config(commit_tree_config, NULL);
|
|
|
|
if (argc < 2 || !strcmp(argv[1], "-h"))
|
|
usage(commit_tree_usage);
|
|
|
|
for (i = 1; i < argc; i++) {
|
|
const char *arg = argv[i];
|
|
if (!strcmp(arg, "-p")) {
|
|
unsigned char sha1[20];
|
|
if (argc <= ++i)
|
|
usage(commit_tree_usage);
|
|
if (get_sha1_commit(argv[i], sha1))
|
|
die("Not a valid object name %s", argv[i]);
|
|
assert_sha1_type(sha1, OBJ_COMMIT);
|
|
new_parent(lookup_commit(sha1), &parents);
|
|
continue;
|
|
}
|
|
|
|
if (skip_prefix(arg, "-S", &sign_commit))
|
|
continue;
|
|
|
|
if (!strcmp(arg, "--no-gpg-sign")) {
|
|
sign_commit = NULL;
|
|
continue;
|
|
}
|
|
|
|
if (!strcmp(arg, "-m")) {
|
|
if (argc <= ++i)
|
|
usage(commit_tree_usage);
|
|
if (buffer.len)
|
|
strbuf_addch(&buffer, '\n');
|
|
strbuf_addstr(&buffer, argv[i]);
|
|
strbuf_complete_line(&buffer);
|
|
continue;
|
|
}
|
|
|
|
if (!strcmp(arg, "-F")) {
|
|
int fd;
|
|
|
|
if (argc <= ++i)
|
|
usage(commit_tree_usage);
|
|
if (buffer.len)
|
|
strbuf_addch(&buffer, '\n');
|
|
if (!strcmp(argv[i], "-"))
|
|
fd = 0;
|
|
else {
|
|
fd = open(argv[i], O_RDONLY);
|
|
if (fd < 0)
|
|
die_errno("git commit-tree: failed to open '%s'",
|
|
argv[i]);
|
|
}
|
|
if (strbuf_read(&buffer, fd, 0) < 0)
|
|
die_errno("git commit-tree: failed to read '%s'",
|
|
argv[i]);
|
|
if (fd && close(fd))
|
|
die_errno("git commit-tree: failed to close '%s'",
|
|
argv[i]);
|
|
strbuf_complete_line(&buffer);
|
|
continue;
|
|
}
|
|
|
|
if (get_sha1_tree(arg, tree_sha1))
|
|
die("Not a valid object name %s", arg);
|
|
if (got_tree)
|
|
die("Cannot give more than one trees");
|
|
got_tree = 1;
|
|
}
|
|
|
|
if (!buffer.len) {
|
|
if (strbuf_read(&buffer, 0, 0) < 0)
|
|
die_errno("git commit-tree: failed to read");
|
|
}
|
|
|
|
if (commit_tree(buffer.buf, buffer.len, tree_sha1, parents,
|
|
commit_sha1, NULL, sign_commit)) {
|
|
strbuf_release(&buffer);
|
|
return 1;
|
|
}
|
|
|
|
printf("%s\n", sha1_to_hex(commit_sha1));
|
|
strbuf_release(&buffer);
|
|
return 0;
|
|
}
|