@@ -311,6 +311,7 @@ static void write_head_info(void)
struct command {
struct command *next;
const char *error_string;
+ const char *extra_string;
unsigned int skip_update:1,
did_not_exist:1,
have_special_ref:1;
@@ -868,7 +869,12 @@ static int read_proc_receive_result(struct packet_reader *reader,
else
cmd->error_string = "failed";
code = 1;
- } else if (strcmp("ok", status)) {
+ } else if (!strcmp("ok", status)) {
+ cmd->extra_string = xstrdup_or_null(msg);
+ } else if (!strcmp("ft", status)) {
+ /* Unset "have_special_ref" field, will execute by "receive-pack" */
+ cmd->have_special_ref = 0;
+ } else {
rp_warning("unknown proc-receive status '%s' for '%s'",
status, reader->line);
cmd->error_string = "bad status";
@@ -2133,12 +2139,17 @@ static void report(struct command *commands, const char *unpack_status)
packet_buf_write(&buf, "unpack %s\n",
unpack_status ? unpack_status : "ok");
for (cmd = commands; cmd; cmd = cmd->next) {
- if (!cmd->error_string)
- packet_buf_write(&buf, "ok %s\n",
- cmd->ref_name);
- else
+ if (!cmd->error_string) {
+ if (!cmd->extra_string)
+ packet_buf_write(&buf, "ok %s\n",
+ cmd->ref_name);
+ else
+ packet_buf_write(&buf, "ok %s%c%s\n",
+ cmd->ref_name, ' ', cmd->extra_string);
+ } else {
packet_buf_write(&buf, "ng %s %s\n",
cmd->ref_name, cmd->error_string);
+ }
}
packet_buf_flush(&buf);
@@ -463,11 +463,17 @@ static void print_ref_status(char flag, const char *summary,
struct ref *to, struct ref *from, const char *msg,
int porcelain, int summary_width)
{
+ char *to_name = to->name;
+
+ if (to->remote_status) {
+ if (!strncmp("ref:", to->remote_status, 4))
+ to_name = to->remote_status + 4;
+ }
if (porcelain) {
if (from)
- fprintf(stdout, "%c\t%s:%s\t", flag, from->name, to->name);
+ fprintf(stdout, "%c\t%s:%s\t", flag, from->name, to_name);
else
- fprintf(stdout, "%c\t:%s\t", flag, to->name);
+ fprintf(stdout, "%c\t:%s\t", flag, to_name);
if (msg)
fprintf(stdout, "%s (%s)\n", summary, msg);
else
@@ -481,9 +487,9 @@ static void print_ref_status(char flag, const char *summary,
fprintf(stderr, " %s%c %-*s%s ", red, flag, summary_width,
summary, reset);
if (from)
- fprintf(stderr, "%s -> %s", prettify_refname(from->name), prettify_refname(to->name));
+ fprintf(stderr, "%s -> %s", prettify_refname(from->name), prettify_refname(to_name));
else
- fputs(prettify_refname(to->name), stderr);
+ fputs(prettify_refname(to_name), stderr);
if (msg) {
fputs(" (", stderr);
fputs(msg, stderr);
@@ -498,12 +504,21 @@ static void print_ok_ref_status(struct ref *ref, int porcelain, int summary_widt
if (ref->deletion)
print_ref_status('-', "[deleted]", ref, NULL, NULL,
porcelain, summary_width);
- else if (is_null_oid(&ref->old_oid))
+ else if (is_null_oid(&ref->old_oid)) {
+ char *refname, *summary;
+ if (ref->remote_status && !strncmp(ref->remote_status, "ref:", 4))
+ refname = ref->remote_status + 4;
+ else
+ refname = ref->name;
+ if (starts_with(refname, "refs/tags/"))
+ summary = "[new tag]";
+ else if (starts_with(refname, "refs/heads/"))
+ summary = "[new branch]";
+ else
+ summary = "[new reference]";
print_ref_status('*',
- (starts_with(ref->name, "refs/tags/") ? "[new tag]" :
- "[new branch]"),
- ref, ref->peer_ref, NULL, porcelain, summary_width);
- else {
+ summary, ref, ref->peer_ref, NULL, porcelain, summary_width);
+ } else {
struct strbuf quickref = STRBUF_INIT;
char type;
const char *msg;
The "proc-receive" may update one or more references, and will send its result one by one in pkt-line format. Each line of the result has four fields and one optional message field, as "<old-oid> <new-oid> <ref> <status> [<message>]". See the following example: # OK, run this command successfully. PKT-LINE(old-oid new-oid ref ok) # NO, I reject it. PKT-LINE(old-oid new-oid ref ng reason) # OK, but use an alternate reference. PKT-LINE(old-oid new-oid ref ok ref:alt-ref) # It will fallthrough to receive-pack to execute. PKT-LINE(old-oid new-oid ref ft) The first three fields have the same foramt as a command. The forth field has a two-letter status code. Available status code: * ok: The command runs successfully. If the optional message has a prefix "ref:", the hook has created/updated an alternate reference instead. * ng: Fail to run the command. Error message is in the optional message field. * ft: Will fallthrough to receive-pack to execute. Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com> --- builtin/receive-pack.c | 21 ++++++++++++++++----- transport.c | 33 ++++++++++++++++++++++++--------- 2 files changed, 40 insertions(+), 14 deletions(-)