Merge branch 'jx/proc-receive-hook' into pu
"git receive-pack" that accepts requests by "git push" learned to outsource most of the ref updates to the new "proc-receive" hook. * jx/proc-receive-hook: doc: add documentation for the proc-receive hook transport: parse report options for tracking refs t5411: test updates of remote-tracking branches receive-pack: new config receive.procReceiveRefs refs.c: refactor to reuse ref_is_hidden() receive-pack: feed report options to post-receive doc: add document for capability report-status-v2 New capability "report-status-v2" for git-push receive-pack: add new proc-receive hook t5411: add basic test cases for proc-receive hook transport: not report a non-head push as a branch
This commit is contained in:
@ -114,6 +114,20 @@ receive.hideRefs::
|
||||
An attempt to update or delete a hidden ref by `git push` is
|
||||
rejected.
|
||||
|
||||
receive.procReceiveRefs::
|
||||
This is a multi-valued variable that defines reference prefixes
|
||||
to match the commands in `receive-pack`. Commands matching the
|
||||
prefixes will be executed by an external hook "proc-receive",
|
||||
instead of the internal `execute_commands` function. If this
|
||||
variable is not defined, the "proc-receive" hook will never be
|
||||
used, and all commands will be executed by the internal
|
||||
`execute_commands` function.
|
||||
|
||||
For example, if this variable is set to "refs/for", pushing to
|
||||
reference such as "refs/for/master" will not create or update a
|
||||
reference named "refs/for/master", but may create or update a
|
||||
pull request directly by running the hook "proc-receive".
|
||||
|
||||
receive.updateServerInfo::
|
||||
If set to true, git-receive-pack will run git-update-server-info
|
||||
after receiving data from git-push and updating refs.
|
||||
|
@ -333,6 +333,68 @@ The default 'update' hook, when enabled--and with
|
||||
`hooks.allowunannotated` config option unset or set to false--prevents
|
||||
unannotated tags to be pushed.
|
||||
|
||||
[[proc-receive]]
|
||||
proc-receive
|
||||
~~~~~~~~~~~~
|
||||
|
||||
This hook is invoked by linkgit:git-receive-pack[1]. If the server has
|
||||
set the multi-valued config variable `receive.procReceiveRefs`, and the
|
||||
commands sent to 'receive-pack' have matching reference names, these
|
||||
commands will be executed by this hook, instead of by the internal
|
||||
`execute_commands()` function. This hook is responsible for updating
|
||||
the relevant references and reporting the results back to 'receive-pack'.
|
||||
|
||||
This hook executes once for the receive operation. It takes no
|
||||
arguments, but uses a pkt-line format protocol to communicate with
|
||||
'receive-pack' to read commands, push-options and send results. In the
|
||||
following example for the protocol, the letter 'S' stands for
|
||||
'receive-pack' and the letter 'H' stands for this hook.
|
||||
|
||||
# Version and features negotiation.
|
||||
S: PKT-LINE(version=1\0push-options atomic...)
|
||||
S: flush-pkt
|
||||
H: PKT-LINE(version=1\0push-options...)
|
||||
H: flush-pkt
|
||||
|
||||
# Send commands from server to the hook.
|
||||
S: PKT-LINE(<old-oid> <new-oid> <ref>)
|
||||
S: ... ...
|
||||
S: flush-pkt
|
||||
# Send push-options only if the 'push-options' feature is enabled.
|
||||
S: PKT-LINE(push-option)
|
||||
S: ... ...
|
||||
S: flush-pkt
|
||||
|
||||
# Receive result from the hook.
|
||||
# OK, run this command successfully.
|
||||
H: PKT-LINE(ok <ref>)
|
||||
# NO, I reject it.
|
||||
H: PKT-LINE(ng <ref> <reason>)
|
||||
# Fall through, let 'receive-pack' to execute it.
|
||||
H: PKT-LINE(ok <ref>)
|
||||
H: PKT-LINE(option fall-through)
|
||||
# OK, but has an alternate reference. The alternate reference name
|
||||
# and other status can be given in options
|
||||
H: PKT-LINE(ok <ref>)
|
||||
H: PKT-LINE(option refname <refname>)
|
||||
H: PKT-LINE(option old-oid <old-oid>)
|
||||
H: PKT-LINE(option new-oid <new-oid>)
|
||||
H: PKT-LINE(option forced-update)
|
||||
H: ... ...
|
||||
H: flush-pkt
|
||||
|
||||
Each command for the 'proc-receive' hook may point to a pseudo-reference
|
||||
and always has a zero-old as its old-oid, while the 'proc-receive' hook
|
||||
may update an alternate reference and the alternate reference may exist
|
||||
already with a non-zero old-oid. For this case, this hook will use
|
||||
"option" directives to report extended attributes for the reference given
|
||||
by the above "ok/ng" directive.
|
||||
|
||||
The report of the commands of this hook should have the same order as
|
||||
the input. The exit status of the 'proc-receive' hook only determines
|
||||
the success or failure of the group of commands sent to it, unless
|
||||
atomic push is in use.
|
||||
|
||||
[[post-receive]]
|
||||
post-receive
|
||||
~~~~~~~~~~~~
|
||||
|
@ -503,8 +503,8 @@ The reference discovery phase is done nearly the same way as it is in the
|
||||
fetching protocol. Each reference obj-id and name on the server is sent
|
||||
in packet-line format to the client, followed by a flush-pkt. The only
|
||||
real difference is that the capability listing is different - the only
|
||||
possible values are 'report-status', 'delete-refs', 'ofs-delta' and
|
||||
'push-options'.
|
||||
possible values are 'report-status', 'report-status-v2', 'delete-refs',
|
||||
'ofs-delta', 'atomic' and 'push-options'.
|
||||
|
||||
Reference Update Request and Packfile Transfer
|
||||
----------------------------------------------
|
||||
@ -625,7 +625,7 @@ Report Status
|
||||
-------------
|
||||
|
||||
After receiving the pack data from the sender, the receiver sends a
|
||||
report if 'report-status' capability is in effect.
|
||||
report if 'report-status' or 'report-status-v2' capability is in effect.
|
||||
It is a short listing of what happened in that update. It will first
|
||||
list the status of the packfile unpacking as either 'unpack ok' or
|
||||
'unpack [error]'. Then it will list the status for each of the references
|
||||
@ -647,6 +647,43 @@ update was successful, or 'ng [refname] [error]' if the update was not.
|
||||
error-msg = 1*(OCTET) ; where not "ok"
|
||||
----
|
||||
|
||||
New capability "report-status-v2" extends the protocol by adding new option
|
||||
lines in order to support reporting of reference rewritten by the
|
||||
"proc-receive" hook. The "proc-receive" hook may handle a command for a
|
||||
pseudo-reference which may create or update one or more references, and each
|
||||
reference may have different name, different new-oid, and different old-oid.
|
||||
|
||||
----
|
||||
report-status-v2 = unpack-status
|
||||
1*(command-status-v2)
|
||||
flush-pkt
|
||||
|
||||
unpack-status = PKT-LINE("unpack" SP unpack-result)
|
||||
unpack-result = "ok" / error-msg
|
||||
|
||||
command-status-v2 = command-ok-v2 / command-fail-v2
|
||||
command-ok-v2 = command-ok
|
||||
*option-line
|
||||
command-fail-v2 = command-fail
|
||||
*option-line
|
||||
|
||||
command-ok = PKT-LINE("ok" SP refname)
|
||||
command-fail = PKT-LINE("ng" SP refname SP error-msg)
|
||||
|
||||
error-msg = 1*(OCTET) ; where not "ok"
|
||||
|
||||
option-line = *1(option-refname)
|
||||
*1(option-old-oid)
|
||||
*1(option-new-oid)
|
||||
*1(option-forced-update)
|
||||
|
||||
option-refname = PKT-LINE("option" SP "refname" SP refname)
|
||||
option-old-oid = PKT-LINE("option" SP "old-oid" SP obj-id)
|
||||
option-new-oid = PKT-LINE("option" SP "new-oid" SP obj-id)
|
||||
option-force = PKT-LINE("option" SP "forced-update")
|
||||
|
||||
----
|
||||
|
||||
Updates can be unsuccessful for a number of reasons. The reference can have
|
||||
changed since the reference discovery phase was originally sent, meaning
|
||||
someone pushed in the meantime. The reference being pushed could be a
|
||||
|
@ -22,9 +22,9 @@ was sent. Server MUST NOT ignore capabilities that client requested
|
||||
and server advertised. As a consequence of these rules, server MUST
|
||||
NOT advertise capabilities it does not understand.
|
||||
|
||||
The 'atomic', 'report-status', 'delete-refs', 'quiet', and 'push-cert'
|
||||
capabilities are sent and recognized by the receive-pack (push to server)
|
||||
process.
|
||||
The 'atomic', 'report-status', 'report-status-v2', 'delete-refs', 'quiet',
|
||||
and 'push-cert' capabilities are sent and recognized by the receive-pack
|
||||
(push to server) process.
|
||||
|
||||
The 'ofs-delta' and 'side-band-64k' capabilities are sent and recognized
|
||||
by both upload-pack and receive-pack protocols. The 'agent' capability
|
||||
@ -284,6 +284,17 @@ each reference was updated successfully. If any of those were not
|
||||
successful, it will send back an error message. See pack-protocol.txt
|
||||
for example messages.
|
||||
|
||||
report-status-v2
|
||||
----------------
|
||||
|
||||
Capability 'report-status-v2' extends capability 'report-status' by
|
||||
adding new option lines in order to support reference rewritten by
|
||||
the"proc-receive" hook. The "proc-receive" hook may handle a command
|
||||
for a pseudo-reference which may create or update a reference with
|
||||
different name, new-oid, and old-oid. While the capability
|
||||
"report-status" cannot report for such case. See pack-protocol.txt
|
||||
for details.
|
||||
|
||||
delete-refs
|
||||
-----------
|
||||
|
||||
|
1
Makefile
1
Makefile
@ -719,6 +719,7 @@ TEST_BUILTINS_OBJS += test-parse-pathspec-file.o
|
||||
TEST_BUILTINS_OBJS += test-path-utils.o
|
||||
TEST_BUILTINS_OBJS += test-pkt-line.o
|
||||
TEST_BUILTINS_OBJS += test-prio-queue.o
|
||||
TEST_BUILTINS_OBJS += test-proc-receive.o
|
||||
TEST_BUILTINS_OBJS += test-progress.o
|
||||
TEST_BUILTINS_OBJS += test-reach.o
|
||||
TEST_BUILTINS_OBJS += test-read-cache.o
|
||||
|
@ -57,6 +57,7 @@ static int advertise_push_options;
|
||||
static int unpack_limit = 100;
|
||||
static off_t max_input_size;
|
||||
static int report_status;
|
||||
static int report_status_v2;
|
||||
static int use_sideband;
|
||||
static int use_atomic;
|
||||
static int use_push_options;
|
||||
@ -77,6 +78,7 @@ static struct object_id push_cert_oid;
|
||||
static struct signature_check sigcheck;
|
||||
static const char *push_cert_nonce;
|
||||
static const char *cert_nonce_seed;
|
||||
static struct string_list proc_receive_refs;
|
||||
|
||||
static const char *NONCE_UNSOLICITED = "UNSOLICITED";
|
||||
static const char *NONCE_BAD = "BAD";
|
||||
@ -229,6 +231,20 @@ static int receive_pack_config(const char *var, const char *value, void *cb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(var, "receive.procreceiverefs") == 0) {
|
||||
char *prefix;
|
||||
int len;
|
||||
|
||||
if (!value)
|
||||
return config_error_nonbool(var);
|
||||
prefix = xstrdup(value);
|
||||
len = strlen(prefix);
|
||||
while (len && prefix[len - 1] == '/')
|
||||
prefix[--len] = '\0';
|
||||
string_list_append(&proc_receive_refs, prefix);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return git_default_config(var, value, cb);
|
||||
}
|
||||
|
||||
@ -240,7 +256,7 @@ static void show_ref(const char *path, const struct object_id *oid)
|
||||
struct strbuf cap = STRBUF_INIT;
|
||||
|
||||
strbuf_addstr(&cap,
|
||||
"report-status delete-refs side-band-64k quiet");
|
||||
"report-status report-status-v2 delete-refs side-band-64k quiet");
|
||||
if (advertise_atomic_push)
|
||||
strbuf_addstr(&cap, " atomic");
|
||||
if (prefer_ofs_delta)
|
||||
@ -310,11 +326,14 @@ static void write_head_info(void)
|
||||
packet_flush(1);
|
||||
}
|
||||
|
||||
#define RUN_PROC_RECEIVE_SCHEDULED 1
|
||||
#define RUN_PROC_RECEIVE_RETURNED 2
|
||||
struct command {
|
||||
struct command *next;
|
||||
const char *error_string;
|
||||
struct ref_push_report report;
|
||||
unsigned int skip_update:1,
|
||||
did_not_exist:1;
|
||||
did_not_exist:1,
|
||||
run_proc_receive:2;
|
||||
int index;
|
||||
struct object_id old_oid;
|
||||
struct object_id new_oid;
|
||||
@ -773,17 +792,38 @@ static int feed_receive_hook(void *state_, const char **bufp, size_t *sizep)
|
||||
{
|
||||
struct receive_hook_feed_state *state = state_;
|
||||
struct command *cmd = state->cmd;
|
||||
static struct ref_push_report_options *options = NULL;
|
||||
|
||||
while (cmd &&
|
||||
state->skip_broken && (cmd->error_string || cmd->did_not_exist))
|
||||
state->skip_broken && (cmd->report.error_message || cmd->did_not_exist))
|
||||
cmd = cmd->next;
|
||||
if (!cmd)
|
||||
return -1; /* EOF */
|
||||
if (!bufp)
|
||||
return 0; /* OK, can feed something. */
|
||||
strbuf_reset(&state->buf);
|
||||
strbuf_addf(&state->buf, "%s %s %s\n",
|
||||
oid_to_hex(&cmd->old_oid), oid_to_hex(&cmd->new_oid),
|
||||
cmd->ref_name);
|
||||
state->cmd = cmd->next;
|
||||
if (!options)
|
||||
options = cmd->report.options;
|
||||
if (options) {
|
||||
struct object_id *old_oid;
|
||||
struct object_id *new_oid;
|
||||
const char *ref_name;
|
||||
|
||||
old_oid = options->old_oid ? options->old_oid : &cmd->old_oid;
|
||||
new_oid = options->new_oid ? options->new_oid : &cmd->new_oid;
|
||||
ref_name = options->ref_name ? options->ref_name : cmd->ref_name;
|
||||
strbuf_addf(&state->buf, "%s %s %s\n",
|
||||
oid_to_hex(old_oid), oid_to_hex(new_oid),
|
||||
ref_name);
|
||||
options = options->next;
|
||||
if (!options)
|
||||
state->cmd = cmd->next;
|
||||
} else {
|
||||
strbuf_addf(&state->buf, "%s %s %s\n",
|
||||
oid_to_hex(&cmd->old_oid), oid_to_hex(&cmd->new_oid),
|
||||
cmd->ref_name);
|
||||
state->cmd = cmd->next;
|
||||
}
|
||||
if (bufp) {
|
||||
*bufp = state->buf.buf;
|
||||
*sizep = state->buf.len;
|
||||
@ -840,6 +880,268 @@ static int run_update_hook(struct command *cmd)
|
||||
return finish_command(&proc);
|
||||
}
|
||||
|
||||
static struct command *find_command_by_refname(const struct command *list,
|
||||
const char *refname)
|
||||
{
|
||||
for (; list; list = list->next)
|
||||
if (!strcmp(list->ref_name, refname))
|
||||
return (struct command *)list;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int read_proc_receive_report(struct packet_reader *reader,
|
||||
struct command *commands,
|
||||
struct strbuf *errmsg)
|
||||
{
|
||||
struct command *cmd;
|
||||
struct command *hint = NULL;
|
||||
int code = 0;
|
||||
int new_options = 1;
|
||||
|
||||
for (;;) {
|
||||
struct object_id old_oid, new_oid;
|
||||
const char *head;
|
||||
const char *refname;
|
||||
char *p;
|
||||
|
||||
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
|
||||
break;
|
||||
|
||||
head = reader->line;
|
||||
p = strchr(head, ' ');
|
||||
if (!p) {
|
||||
strbuf_addf(errmsg, "proc-receive reported incomplete status line: '%s'\n", head);
|
||||
code = -1;
|
||||
continue;
|
||||
}
|
||||
*p++ = '\0';
|
||||
if (!strcmp(head, "option")) {
|
||||
struct ref_push_report_options *options;
|
||||
const char *key, *val;
|
||||
|
||||
if (!hint) {
|
||||
if (new_options) {
|
||||
strbuf_addstr(errmsg, "proc-receive reported 'option' without a matching 'ok/ng' directive\n");
|
||||
new_options = 0;
|
||||
}
|
||||
code = -1;
|
||||
continue;
|
||||
}
|
||||
options = hint->report.options;
|
||||
while (options && options->next)
|
||||
options = options->next;
|
||||
if (new_options) {
|
||||
if (!options) {
|
||||
hint->report.options = xcalloc(1, sizeof(struct ref_push_report_options));
|
||||
options = hint->report.options;
|
||||
} else {
|
||||
options->next = xcalloc(1, sizeof(struct ref_push_report_options));
|
||||
options = options->next;
|
||||
}
|
||||
new_options = 0;
|
||||
}
|
||||
assert(options);
|
||||
key = p;
|
||||
p = strchr(key, ' ');
|
||||
if (p)
|
||||
*p++ = '\0';
|
||||
val = p;
|
||||
if (!strcmp(key, "refname"))
|
||||
options->ref_name = xstrdup_or_null(val);
|
||||
else if (!strcmp(key, "old-oid") && val &&
|
||||
!parse_oid_hex(val, &old_oid, &val))
|
||||
options->old_oid = oiddup(&old_oid);
|
||||
else if (!strcmp(key, "new-oid") && val &&
|
||||
!parse_oid_hex(val, &new_oid, &val))
|
||||
options->new_oid = oiddup(&new_oid);
|
||||
else if (!strcmp(key, "forced-update"))
|
||||
options->forced_update = 1;
|
||||
else if (!strcmp(key, "fall-through"))
|
||||
/* Fall through, let 'receive-pack' to execute it. */
|
||||
hint->run_proc_receive = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
refname = p;
|
||||
p = strchr(refname, ' ');
|
||||
if (p)
|
||||
*p++ = '\0';
|
||||
if (strcmp(head, "ok") && strcmp(head, "ng")) {
|
||||
strbuf_addf(errmsg, "proc-receive reported bad status '%s' on ref '%s'\n",
|
||||
head, refname);
|
||||
code = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* first try searching at our hint, falling back to all refs */
|
||||
if (hint)
|
||||
hint = find_command_by_refname(hint, refname);
|
||||
if (!hint)
|
||||
hint = find_command_by_refname(commands, refname);
|
||||
if (!hint) {
|
||||
strbuf_addf(errmsg, "proc-receive reported status on unknown ref: %s\n",
|
||||
refname);
|
||||
code = -1;
|
||||
continue;
|
||||
}
|
||||
if (!hint->run_proc_receive) {
|
||||
strbuf_addf(errmsg, "proc-receive reported status on unexpected ref: %s\n",
|
||||
refname);
|
||||
code = -1;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(head, "ng")) {
|
||||
if (p)
|
||||
hint->report.error_message = xstrdup(p);
|
||||
else
|
||||
hint->report.error_message = "failed";
|
||||
code = -1;
|
||||
}
|
||||
if (hint->run_proc_receive)
|
||||
hint->run_proc_receive |= RUN_PROC_RECEIVE_RETURNED;
|
||||
new_options = 1;
|
||||
}
|
||||
|
||||
for (cmd = commands; cmd; cmd = cmd->next)
|
||||
if (cmd->run_proc_receive && !cmd->report.error_message &&
|
||||
!(cmd->run_proc_receive & RUN_PROC_RECEIVE_RETURNED)) {
|
||||
cmd->report.error_message = "proc-receive failed to report status";
|
||||
code = -1;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int run_proc_receive_hook(struct command *commands,
|
||||
const struct string_list *push_options)
|
||||
{
|
||||
struct child_process proc = CHILD_PROCESS_INIT;
|
||||
struct async muxer;
|
||||
struct command *cmd;
|
||||
const char *argv[2];
|
||||
struct packet_reader reader;
|
||||
struct strbuf cap = STRBUF_INIT;
|
||||
struct strbuf errmsg = STRBUF_INIT;
|
||||
int hook_use_push_options = 0;
|
||||
int version = 0;
|
||||
int code;
|
||||
|
||||
argv[0] = find_hook("proc-receive");
|
||||
if (!argv[0]) {
|
||||
rp_error("cannot find hook 'proc-receive'");
|
||||
return -1;
|
||||
}
|
||||
argv[1] = NULL;
|
||||
|
||||
proc.argv = argv;
|
||||
proc.in = -1;
|
||||
proc.out = -1;
|
||||
proc.trace2_hook_name = "proc-receive";
|
||||
|
||||
if (use_sideband) {
|
||||
memset(&muxer, 0, sizeof(muxer));
|
||||
muxer.proc = copy_to_sideband;
|
||||
muxer.in = -1;
|
||||
code = start_async(&muxer);
|
||||
if (code)
|
||||
return code;
|
||||
proc.err = muxer.in;
|
||||
} else {
|
||||
proc.err = 0;
|
||||
}
|
||||
|
||||
code = start_command(&proc);
|
||||
if (code) {
|
||||
if (use_sideband)
|
||||
finish_async(&muxer);
|
||||
return code;
|
||||
}
|
||||
|
||||
sigchain_push(SIGPIPE, SIG_IGN);
|
||||
|
||||
/* Version negotiaton */
|
||||
packet_reader_init(&reader, proc.out, NULL, 0,
|
||||
PACKET_READ_CHOMP_NEWLINE |
|
||||
PACKET_READ_GENTLE_ON_EOF);
|
||||
if (use_atomic)
|
||||
strbuf_addstr(&cap, " atomic");
|
||||
if (use_push_options)
|
||||
strbuf_addstr(&cap, " push-options");
|
||||
if (cap.len) {
|
||||
packet_write_fmt(proc.in, "version=1%c%s\n", '\0', cap.buf + 1);
|
||||
strbuf_release(&cap);
|
||||
} else {
|
||||
packet_write_fmt(proc.in, "version=1\n");
|
||||
}
|
||||
packet_flush(proc.in);
|
||||
|
||||
for (;;) {
|
||||
int linelen;
|
||||
|
||||
if (packet_reader_read(&reader) != PACKET_READ_NORMAL)
|
||||
break;
|
||||
|
||||
if (reader.pktlen > 8 && starts_with(reader.line, "version=")) {
|
||||
version = atoi(reader.line + 8);
|
||||
linelen = strlen(reader.line);
|
||||
if (linelen < reader.pktlen) {
|
||||
const char *feature_list = reader.line + linelen + 1;
|
||||
if (parse_feature_request(feature_list, "push-options"))
|
||||
hook_use_push_options = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (version != 1) {
|
||||
strbuf_addf(&errmsg, "proc-receive version '%d' is not supported",
|
||||
version);
|
||||
code = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Send commands */
|
||||
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||
if (!cmd->run_proc_receive || cmd->skip_update || cmd->report.error_message)
|
||||
continue;
|
||||
packet_write_fmt(proc.in, "%s %s %s",
|
||||
oid_to_hex(&cmd->old_oid),
|
||||
oid_to_hex(&cmd->new_oid),
|
||||
cmd->ref_name);
|
||||
}
|
||||
packet_flush(proc.in);
|
||||
|
||||
/* Send push options */
|
||||
if (hook_use_push_options) {
|
||||
struct string_list_item *item;
|
||||
|
||||
for_each_string_list_item(item, push_options)
|
||||
packet_write_fmt(proc.in, "%s", item->string);
|
||||
packet_flush(proc.in);
|
||||
}
|
||||
|
||||
/* Read result from proc-receive */
|
||||
code = read_proc_receive_report(&reader, commands, &errmsg);
|
||||
|
||||
cleanup:
|
||||
close(proc.in);
|
||||
close(proc.out);
|
||||
if (use_sideband)
|
||||
finish_async(&muxer);
|
||||
if (finish_command(&proc))
|
||||
code = -1;
|
||||
if (errmsg.len >0) {
|
||||
char *p = errmsg.buf;
|
||||
|
||||
p += errmsg.len - 1;
|
||||
if (*p == '\n')
|
||||
*p = '\0';
|
||||
rp_error("%s", errmsg.buf);
|
||||
strbuf_release(&errmsg);
|
||||
}
|
||||
sigchain_pop(SIGPIPE);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static char *refuse_unconfigured_deny_msg =
|
||||
N_("By default, updating the current branch in a non-bare repository\n"
|
||||
"is denied, because it will make the index and work tree inconsistent\n"
|
||||
@ -1203,7 +1505,7 @@ static void run_update_post_hook(struct command *commands)
|
||||
return;
|
||||
|
||||
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||
if (cmd->error_string || cmd->did_not_exist)
|
||||
if (cmd->report.error_message || cmd->did_not_exist)
|
||||
continue;
|
||||
if (!proc.args.argc)
|
||||
argv_array_push(&proc.args, hook);
|
||||
@ -1237,7 +1539,7 @@ static void check_aliased_update_internal(struct command *cmd,
|
||||
if (!dst_name) {
|
||||
rp_error("refusing update to broken symref '%s'", cmd->ref_name);
|
||||
cmd->skip_update = 1;
|
||||
cmd->error_string = "broken symref";
|
||||
cmd->report.error_message = "broken symref";
|
||||
return;
|
||||
}
|
||||
dst_name = strip_namespace(dst_name);
|
||||
@ -1264,7 +1566,7 @@ static void check_aliased_update_internal(struct command *cmd,
|
||||
find_unique_abbrev(&dst_cmd->old_oid, DEFAULT_ABBREV),
|
||||
find_unique_abbrev(&dst_cmd->new_oid, DEFAULT_ABBREV));
|
||||
|
||||
cmd->error_string = dst_cmd->error_string =
|
||||
cmd->report.error_message = dst_cmd->report.error_message =
|
||||
"inconsistent aliased update";
|
||||
}
|
||||
|
||||
@ -1293,7 +1595,7 @@ static void check_aliased_updates(struct command *commands)
|
||||
string_list_sort(&ref_list);
|
||||
|
||||
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||
if (!cmd->error_string)
|
||||
if (!cmd->report.error_message)
|
||||
check_aliased_update(cmd, &ref_list);
|
||||
}
|
||||
|
||||
@ -1330,7 +1632,7 @@ static void set_connectivity_errors(struct command *commands,
|
||||
&opt))
|
||||
continue;
|
||||
|
||||
cmd->error_string = "missing necessary objects";
|
||||
cmd->report.error_message = "missing necessary objects";
|
||||
}
|
||||
}
|
||||
|
||||
@ -1369,7 +1671,7 @@ static void reject_updates_to_hidden(struct command *commands)
|
||||
prefix_len = refname_full.len;
|
||||
|
||||
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||
if (cmd->error_string)
|
||||
if (cmd->report.error_message)
|
||||
continue;
|
||||
|
||||
strbuf_setlen(&refname_full, prefix_len);
|
||||
@ -1378,9 +1680,9 @@ static void reject_updates_to_hidden(struct command *commands)
|
||||
if (!ref_is_hidden(cmd->ref_name, refname_full.buf))
|
||||
continue;
|
||||
if (is_null_oid(&cmd->new_oid))
|
||||
cmd->error_string = "deny deleting a hidden ref";
|
||||
cmd->report.error_message = "deny deleting a hidden ref";
|
||||
else
|
||||
cmd->error_string = "deny updating a hidden ref";
|
||||
cmd->report.error_message = "deny updating a hidden ref";
|
||||
}
|
||||
|
||||
strbuf_release(&refname_full);
|
||||
@ -1388,7 +1690,7 @@ static void reject_updates_to_hidden(struct command *commands)
|
||||
|
||||
static int should_process_cmd(struct command *cmd)
|
||||
{
|
||||
return !cmd->error_string && !cmd->skip_update;
|
||||
return !cmd->report.error_message && !cmd->skip_update;
|
||||
}
|
||||
|
||||
static void warn_if_skipped_connectivity_check(struct command *commands,
|
||||
@ -1415,24 +1717,24 @@ static void execute_commands_non_atomic(struct command *commands,
|
||||
struct strbuf err = STRBUF_INIT;
|
||||
|
||||
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||
if (!should_process_cmd(cmd))
|
||||
if (!should_process_cmd(cmd) || cmd->run_proc_receive)
|
||||
continue;
|
||||
|
||||
transaction = ref_transaction_begin(&err);
|
||||
if (!transaction) {
|
||||
rp_error("%s", err.buf);
|
||||
strbuf_reset(&err);
|
||||
cmd->error_string = "transaction failed to start";
|
||||
cmd->report.error_message = "transaction failed to start";
|
||||
continue;
|
||||
}
|
||||
|
||||
cmd->error_string = update(cmd, si);
|
||||
cmd->report.error_message = update(cmd, si);
|
||||
|
||||
if (!cmd->error_string
|
||||
if (!cmd->report.error_message
|
||||
&& ref_transaction_commit(transaction, &err)) {
|
||||
rp_error("%s", err.buf);
|
||||
strbuf_reset(&err);
|
||||
cmd->error_string = "failed to update ref";
|
||||
cmd->report.error_message = "failed to update ref";
|
||||
}
|
||||
ref_transaction_free(transaction);
|
||||
}
|
||||
@ -1455,12 +1757,12 @@ static void execute_commands_atomic(struct command *commands,
|
||||
}
|
||||
|
||||
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||
if (!should_process_cmd(cmd))
|
||||
if (!should_process_cmd(cmd) || cmd->run_proc_receive)
|
||||
continue;
|
||||
|
||||
cmd->error_string = update(cmd, si);
|
||||
cmd->report.error_message = update(cmd, si);
|
||||
|
||||
if (cmd->error_string)
|
||||
if (cmd->report.error_message)
|
||||
goto failure;
|
||||
}
|
||||
|
||||
@ -1473,8 +1775,8 @@ static void execute_commands_atomic(struct command *commands,
|
||||
|
||||
failure:
|
||||
for (cmd = commands; cmd; cmd = cmd->next)
|
||||
if (!cmd->error_string)
|
||||
cmd->error_string = reported_error;
|
||||
if (!cmd->report.error_message)
|
||||
cmd->report.error_message = reported_error;
|
||||
|
||||
cleanup:
|
||||
ref_transaction_free(transaction);
|
||||
@ -1491,10 +1793,11 @@ static void execute_commands(struct command *commands,
|
||||
struct iterate_data data;
|
||||
struct async muxer;
|
||||
int err_fd = 0;
|
||||
int run_proc_receive = 0;
|
||||
|
||||
if (unpacker_error) {
|
||||
for (cmd = commands; cmd; cmd = cmd->next)
|
||||
cmd->error_string = "unpacker error";
|
||||
cmd->report.error_message = "unpacker error";
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1520,10 +1823,36 @@ static void execute_commands(struct command *commands,
|
||||
|
||||
reject_updates_to_hidden(commands);
|
||||
|
||||
/*
|
||||
* Try to find commands that have special prefix in their reference names,
|
||||
* and mark them to run an external "proc-receive" hook later.
|
||||
*/
|
||||
if (proc_receive_refs.nr > 0) {
|
||||
struct strbuf refname_full = STRBUF_INIT;
|
||||
size_t prefix_len;
|
||||
|
||||
strbuf_addstr(&refname_full, get_git_namespace());
|
||||
prefix_len = refname_full.len;
|
||||
|
||||
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||
if (!should_process_cmd(cmd))
|
||||
continue;
|
||||
|
||||
strbuf_setlen(&refname_full, prefix_len);
|
||||
strbuf_addstr(&refname_full, cmd->ref_name);
|
||||
if (ref_matches(&proc_receive_refs, cmd->ref_name, refname_full.buf)) {
|
||||
cmd->run_proc_receive = RUN_PROC_RECEIVE_SCHEDULED;
|
||||
run_proc_receive = 1;
|
||||
}
|
||||
}
|
||||
|
||||
strbuf_release(&refname_full);
|
||||
}
|
||||
|
||||
if (run_receive_hook(commands, "pre-receive", 0, push_options)) {
|
||||
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||
if (!cmd->error_string)
|
||||
cmd->error_string = "pre-receive hook declined";
|
||||
if (!cmd->report.error_message)
|
||||
cmd->report.error_message = "pre-receive hook declined";
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1534,8 +1863,8 @@ static void execute_commands(struct command *commands,
|
||||
*/
|
||||
if (tmp_objdir_migrate(tmp_objdir) < 0) {
|
||||
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||
if (!cmd->error_string)
|
||||
cmd->error_string = "unable to migrate objects to permanent storage";
|
||||
if (!cmd->report.error_message)
|
||||
cmd->report.error_message = "unable to migrate objects to permanent storage";
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1546,6 +1875,14 @@ static void execute_commands(struct command *commands,
|
||||
free(head_name_to_free);
|
||||
head_name = head_name_to_free = resolve_refdup("HEAD", 0, NULL, NULL);
|
||||
|
||||
if (run_proc_receive &&
|
||||
run_proc_receive_hook(commands, push_options))
|
||||
for (cmd = commands; cmd; cmd = cmd->next)
|
||||
if (!cmd->report.error_message &&
|
||||
!(cmd->run_proc_receive & RUN_PROC_RECEIVE_RETURNED) &&
|
||||
(cmd->run_proc_receive || use_atomic))
|
||||
cmd->report.error_message = "fail to run proc-receive hook";
|
||||
|
||||
if (use_atomic)
|
||||
execute_commands_atomic(commands, si);
|
||||
else
|
||||
@ -1629,6 +1966,8 @@ static struct command *read_head_info(struct packet_reader *reader,
|
||||
int len = 0;
|
||||
if (parse_feature_request(feature_list, "report-status"))
|
||||
report_status = 1;
|
||||
if (parse_feature_request(feature_list, "report-status-v2"))
|
||||
report_status_v2 = 1;
|
||||
if (parse_feature_request(feature_list, "side-band-64k"))
|
||||
use_sideband = LARGE_PACKET_MAX;
|
||||
if (parse_feature_request(feature_list, "quiet"))
|
||||
@ -1916,7 +2255,7 @@ static void update_shallow_info(struct command *commands,
|
||||
if (is_null_oid(&cmd->new_oid))
|
||||
continue;
|
||||
if (ref_status[cmd->index]) {
|
||||
cmd->error_string = "shallow update not allowed";
|
||||
cmd->report.error_message = "shallow update not allowed";
|
||||
cmd->skip_update = 1;
|
||||
}
|
||||
}
|
||||
@ -1931,12 +2270,55 @@ 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)
|
||||
if (!cmd->report.error_message)
|
||||
packet_buf_write(&buf, "ok %s\n",
|
||||
cmd->ref_name);
|
||||
else
|
||||
packet_buf_write(&buf, "ng %s %s\n",
|
||||
cmd->ref_name, cmd->error_string);
|
||||
cmd->ref_name, cmd->report.error_message);
|
||||
}
|
||||
packet_buf_flush(&buf);
|
||||
|
||||
if (use_sideband)
|
||||
send_sideband(1, 1, buf.buf, buf.len, use_sideband);
|
||||
else
|
||||
write_or_die(1, buf.buf, buf.len);
|
||||
strbuf_release(&buf);
|
||||
}
|
||||
|
||||
static void report_v2(struct command *commands, const char *unpack_status)
|
||||
{
|
||||
struct command *cmd;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
struct ref_push_report_options *options;
|
||||
|
||||
packet_buf_write(&buf, "unpack %s\n",
|
||||
unpack_status ? unpack_status : "ok");
|
||||
for (cmd = commands; cmd; cmd = cmd->next) {
|
||||
int count = 0;
|
||||
|
||||
if (!cmd->report.error_message)
|
||||
packet_buf_write(&buf, "ok %s\n",
|
||||
cmd->ref_name);
|
||||
else
|
||||
packet_buf_write(&buf, "ng %s %s\n",
|
||||
cmd->ref_name,
|
||||
cmd->report.error_message);
|
||||
for (options = cmd->report.options; options; options = options->next) {
|
||||
if (count++ > 0)
|
||||
packet_buf_write(&buf, "ok %s\n", cmd->ref_name);
|
||||
if (options->ref_name)
|
||||
packet_buf_write(&buf, "option refname %s\n",
|
||||
options->ref_name);
|
||||
if (options->old_oid)
|
||||
packet_buf_write(&buf, "option old-oid %s\n",
|
||||
oid_to_hex(options->old_oid));
|
||||
if (options->new_oid)
|
||||
packet_buf_write(&buf, "option new-oid %s\n",
|
||||
oid_to_hex(options->new_oid));
|
||||
if (options->forced_update)
|
||||
packet_buf_write(&buf, "option forced-update\n");
|
||||
}
|
||||
}
|
||||
packet_buf_flush(&buf);
|
||||
|
||||
@ -1974,6 +2356,8 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
string_list_init(&proc_receive_refs, 0);
|
||||
|
||||
packet_trace_identity("receive-pack");
|
||||
|
||||
argc = parse_options(argc, argv, prefix, options, receive_pack_usage, 0);
|
||||
@ -2040,7 +2424,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
|
||||
if (!check_cert_push_options(&push_options)) {
|
||||
struct command *cmd;
|
||||
for (cmd = commands; cmd; cmd = cmd->next)
|
||||
cmd->error_string = "inconsistent push options";
|
||||
cmd->report.error_message = "inconsistent push options";
|
||||
}
|
||||
|
||||
prepare_shallow_info(&si, &shallow);
|
||||
@ -2055,7 +2439,9 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
|
||||
&push_options);
|
||||
if (pack_lockfile)
|
||||
unlink_or_warn(pack_lockfile);
|
||||
if (report_status)
|
||||
if (report_status_v2)
|
||||
report_v2(commands, unpack_status);
|
||||
else if (report_status)
|
||||
report(commands, unpack_status);
|
||||
run_receive_hook(commands, "post-receive", 1,
|
||||
&push_options);
|
||||
@ -2089,5 +2475,6 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
|
||||
oid_array_clear(&shallow);
|
||||
oid_array_clear(&ref);
|
||||
free((void *)push_cert_nonce);
|
||||
string_list_clear(&proc_receive_refs, 0);
|
||||
return 0;
|
||||
}
|
||||
|
@ -29,10 +29,12 @@ static struct send_pack_args args;
|
||||
static void print_helper_status(struct ref *ref)
|
||||
{
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
struct ref_push_report_options *options;
|
||||
|
||||
for (; ref; ref = ref->next) {
|
||||
const char *msg = NULL;
|
||||
const char *res;
|
||||
int count = 0;
|
||||
|
||||
switch(ref->status) {
|
||||
case REF_STATUS_NONE:
|
||||
@ -86,14 +88,29 @@ static void print_helper_status(struct ref *ref)
|
||||
|
||||
strbuf_reset(&buf);
|
||||
strbuf_addf(&buf, "%s %s", res, ref->name);
|
||||
if (ref->remote_status)
|
||||
msg = ref->remote_status;
|
||||
if (ref->report.error_message)
|
||||
msg = ref->report.error_message;
|
||||
if (msg) {
|
||||
strbuf_addch(&buf, ' ');
|
||||
quote_two_c_style(&buf, "", msg, 0);
|
||||
}
|
||||
strbuf_addch(&buf, '\n');
|
||||
|
||||
for (options = ref->report.options; options; options = options->next) {
|
||||
if (count++ > 0)
|
||||
strbuf_addf(&buf, "ok %s\n", ref->name);
|
||||
if (options->ref_name)
|
||||
strbuf_addf(&buf, "option refname %s\n",
|
||||
options->ref_name);
|
||||
if (options->old_oid)
|
||||
strbuf_addf(&buf, "option old-oid %s\n",
|
||||
oid_to_hex(options->old_oid));
|
||||
if (options->new_oid)
|
||||
strbuf_addf(&buf, "option new-oid %s\n",
|
||||
oid_to_hex(options->new_oid));
|
||||
if (options->forced_update)
|
||||
strbuf_addstr(&buf, "option forced-update\n");
|
||||
}
|
||||
write_or_die(1, buf.buf, buf.len);
|
||||
}
|
||||
strbuf_release(&buf);
|
||||
|
13
refs.c
13
refs.c
@ -1346,14 +1346,14 @@ int parse_hide_refs_config(const char *var, const char *value, const char *secti
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ref_is_hidden(const char *refname, const char *refname_full)
|
||||
int ref_matches(struct string_list *match_refs, const char *refname, const char *refname_full)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!hide_refs)
|
||||
if (!match_refs)
|
||||
return 0;
|
||||
for (i = hide_refs->nr - 1; i >= 0; i--) {
|
||||
const char *match = hide_refs->items[i].string;
|
||||
for (i = match_refs->nr - 1; i >= 0; i--) {
|
||||
const char *match = match_refs->items[i].string;
|
||||
const char *subject;
|
||||
int neg = 0;
|
||||
const char *p;
|
||||
@ -1379,6 +1379,11 @@ int ref_is_hidden(const char *refname, const char *refname_full)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ref_is_hidden(const char *refname, const char *refname_full)
|
||||
{
|
||||
return ref_matches(hide_refs, refname, refname_full);
|
||||
}
|
||||
|
||||
const char *find_descendant_ref(const char *dirname,
|
||||
const struct string_list *extras,
|
||||
const struct string_list *skip)
|
||||
|
1
refs.h
1
refs.h
@ -743,6 +743,7 @@ int parse_hide_refs_config(const char *var, const char *value, const char *);
|
||||
* parameter always points to the full ref name.
|
||||
*/
|
||||
int ref_is_hidden(const char *, const char *);
|
||||
int ref_matches(struct string_list *, const char *, const char *);
|
||||
|
||||
enum ref_type {
|
||||
REF_TYPE_PER_WORKTREE, /* refs inside refs/ but not shared */
|
||||
|
4
remote.c
4
remote.c
@ -767,7 +767,7 @@ struct ref *copy_ref(const struct ref *ref)
|
||||
memcpy(cpy, ref, len);
|
||||
cpy->next = NULL;
|
||||
cpy->symref = xstrdup_or_null(ref->symref);
|
||||
cpy->remote_status = xstrdup_or_null(ref->remote_status);
|
||||
cpy->report.error_message = xstrdup_or_null(ref->report.error_message);
|
||||
cpy->peer_ref = copy_ref(ref->peer_ref);
|
||||
return cpy;
|
||||
}
|
||||
@ -789,7 +789,7 @@ void free_one_ref(struct ref *ref)
|
||||
if (!ref)
|
||||
return;
|
||||
free_one_ref(ref->peer_ref);
|
||||
free(ref->remote_status);
|
||||
free((void *)ref->report.error_message);
|
||||
free(ref->symref);
|
||||
free(ref);
|
||||
}
|
||||
|
16
remote.h
16
remote.h
@ -93,6 +93,20 @@ int for_each_remote(each_remote_fn fn, void *priv);
|
||||
|
||||
int remote_has_url(struct remote *remote, const char *url);
|
||||
|
||||
struct ref_push_report_options {
|
||||
const char *ref_name;
|
||||
struct object_id *old_oid;
|
||||
struct object_id *new_oid;
|
||||
unsigned int forced_update:1;
|
||||
struct ref_push_report_options *next;
|
||||
};
|
||||
|
||||
struct ref_push_report {
|
||||
const char *message;
|
||||
const char *error_message;
|
||||
struct ref_push_report_options *options;
|
||||
};
|
||||
|
||||
struct ref {
|
||||
struct ref *next;
|
||||
struct object_id old_oid;
|
||||
@ -139,7 +153,7 @@ struct ref {
|
||||
REF_STATUS_EXPECTING_REPORT,
|
||||
REF_STATUS_ATOMIC_PUSH_FAILED
|
||||
} status;
|
||||
char *remote_status;
|
||||
struct ref_push_report report;
|
||||
struct ref *peer_ref; /* when renaming */
|
||||
char name[FLEX_ARRAY]; /* more */
|
||||
};
|
||||
|
97
send-pack.c
97
send-pack.c
@ -154,25 +154,79 @@ static int receive_status(struct packet_reader *reader, struct ref *refs)
|
||||
{
|
||||
struct ref *hint;
|
||||
int ret;
|
||||
int new_options = 1;
|
||||
|
||||
hint = NULL;
|
||||
ret = receive_unpack_status(reader);
|
||||
while (1) {
|
||||
struct object_id old_oid, new_oid;
|
||||
const char *head;
|
||||
const char *refname;
|
||||
char *msg;
|
||||
char *p;
|
||||
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
|
||||
break;
|
||||
if (!starts_with(reader->line, "ok ") && !starts_with(reader->line, "ng ")) {
|
||||
error("invalid ref status from remote: %s", reader->line);
|
||||
head = reader->line;
|
||||
p = strchr(head, ' ');
|
||||
if (!p) {
|
||||
error("invalid status line from remote: %s", reader->line);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
*p++ = '\0';
|
||||
|
||||
refname = reader->line + 3;
|
||||
msg = strchr(refname, ' ');
|
||||
if (msg)
|
||||
*msg++ = '\0';
|
||||
if (!strcmp(head, "option")) {
|
||||
struct ref_push_report_options *options;
|
||||
const char *key, *val;
|
||||
|
||||
if (!hint) {
|
||||
if (new_options) {
|
||||
error("'option' without a matching 'ok/ng' directive");
|
||||
new_options = 0;
|
||||
}
|
||||
ret = -1;
|
||||
continue;
|
||||
}
|
||||
options = hint->report.options;
|
||||
while (options && options->next)
|
||||
options = options->next;
|
||||
if (new_options) {
|
||||
if (!options) {
|
||||
hint->report.options = xcalloc(1, sizeof(struct ref_push_report_options));
|
||||
options = hint->report.options;
|
||||
} else {
|
||||
options->next = xcalloc(1, sizeof(struct ref_push_report_options));
|
||||
options = options->next;
|
||||
}
|
||||
new_options = 0;
|
||||
}
|
||||
assert(options);
|
||||
key = p;
|
||||
p = strchr(key, ' ');
|
||||
if (p)
|
||||
*p++ = '\0';
|
||||
val = p;
|
||||
if (!strcmp(key, "refname"))
|
||||
options->ref_name = xstrdup_or_null(val);
|
||||
else if (!strcmp(key, "old-oid") && val &&
|
||||
!parse_oid_hex(val, &old_oid, &val))
|
||||
options->old_oid = oiddup(&old_oid);
|
||||
else if (!strcmp(key, "new-oid") && val &&
|
||||
!parse_oid_hex(val, &new_oid, &val))
|
||||
options->new_oid = oiddup(&new_oid);
|
||||
else if (!strcmp(key, "forced-update"))
|
||||
options->forced_update = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(head, "ok") && strcmp(head, "ng")) {
|
||||
error("invalid ref status from remote: %s", head);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
refname = p;
|
||||
p = strchr(refname, ' ');
|
||||
if (p)
|
||||
*p++ = '\0';
|
||||
/* first try searching at our hint, falling back to all refs */
|
||||
if (hint)
|
||||
hint = find_ref_by_name(hint, refname);
|
||||
@ -183,19 +237,24 @@ static int receive_status(struct packet_reader *reader, struct ref *refs)
|
||||
refname);
|
||||
continue;
|
||||
}
|
||||
if (hint->status != REF_STATUS_EXPECTING_REPORT) {
|
||||
if (hint->status != REF_STATUS_EXPECTING_REPORT &&
|
||||
hint->status != REF_STATUS_OK &&
|
||||
hint->status != REF_STATUS_REMOTE_REJECT) {
|
||||
warning("remote reported status on unexpected ref: %s",
|
||||
refname);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reader->line[0] == 'o' && reader->line[1] == 'k')
|
||||
hint->status = REF_STATUS_OK;
|
||||
else
|
||||
if (!strcmp(head, "ng")) {
|
||||
hint->status = REF_STATUS_REMOTE_REJECT;
|
||||
hint->remote_status = xstrdup_or_null(msg);
|
||||
/* start our next search from the next ref */
|
||||
hint = hint->next;
|
||||
if (p)
|
||||
hint->report.error_message = xstrdup(p);
|
||||
else
|
||||
hint->report.error_message = "failed";
|
||||
} else {
|
||||
hint->status = REF_STATUS_OK;
|
||||
hint->report.message = xstrdup_or_null(p);
|
||||
}
|
||||
new_options = 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -371,7 +430,9 @@ int send_pack(struct send_pack_args *args,
|
||||
struct packet_reader reader;
|
||||
|
||||
/* Does the other end support the reporting? */
|
||||
if (server_supports("report-status"))
|
||||
if (server_supports("report-status-v2"))
|
||||
status_report = 2;
|
||||
else if (server_supports("report-status"))
|
||||
status_report = 1;
|
||||
if (server_supports("delete-refs"))
|
||||
allow_deleting_refs = 1;
|
||||
@ -423,8 +484,10 @@ int send_pack(struct send_pack_args *args,
|
||||
|
||||
use_push_options = push_options_supported && args->push_options;
|
||||
|
||||
if (status_report)
|
||||
if (status_report == 1)
|
||||
strbuf_addstr(&cap_buf, " report-status");
|
||||
else if (status_report == 2)
|
||||
strbuf_addstr(&cap_buf, " report-status-v2");
|
||||
if (use_sideband)
|
||||
strbuf_addstr(&cap_buf, " side-band-64k");
|
||||
if (quiet_supported && (args->quiet || !args->progress))
|
||||
|
174
t/helper/test-proc-receive.c
Normal file
174
t/helper/test-proc-receive.c
Normal file
@ -0,0 +1,174 @@
|
||||
#include "cache.h"
|
||||
#include "connect.h"
|
||||
#include "parse-options.h"
|
||||
#include "pkt-line.h"
|
||||
#include "sigchain.h"
|
||||
#include "test-tool.h"
|
||||
|
||||
static const char *proc_receive_usage[] = {
|
||||
"test-tool proc-receive [<options>...]",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int die_version = 0;
|
||||
static int die_readline = 0;
|
||||
static int no_push_options = 0;
|
||||
static int use_atomic = 0;
|
||||
static int use_push_options = 0;
|
||||
static int verbose = 0;
|
||||
static int version = 1;
|
||||
static struct string_list returns = STRING_LIST_INIT_NODUP;
|
||||
|
||||
struct command {
|
||||
struct command *next;
|
||||
const char *error_string;
|
||||
unsigned int skip_update:1,
|
||||
did_not_exist:1;
|
||||
int index;
|
||||
struct object_id old_oid;
|
||||
struct object_id new_oid;
|
||||
char ref_name[FLEX_ARRAY]; /* more */
|
||||
};
|
||||
|
||||
static void proc_receive_verison(struct packet_reader *reader) {
|
||||
int server_version = 0;
|
||||
|
||||
for (;;) {
|
||||
int linelen;
|
||||
|
||||
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
|
||||
break;
|
||||
|
||||
if (reader->pktlen > 8 && starts_with(reader->line, "version=")) {
|
||||
server_version = atoi(reader->line+8);
|
||||
linelen = strlen(reader->line);
|
||||
if (linelen < reader->pktlen) {
|
||||
const char *feature_list = reader->line + linelen + 1;
|
||||
if (parse_feature_request(feature_list, "atomic"))
|
||||
use_atomic= 1;
|
||||
if (parse_feature_request(feature_list, "push-options"))
|
||||
use_push_options = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (server_version != 1 || die_version)
|
||||
die("bad protocol version: %d", server_version);
|
||||
|
||||
packet_write_fmt(1, "version=%d%c%s\n",
|
||||
version, '\0',
|
||||
use_push_options && !no_push_options ? "push-options": "");
|
||||
packet_flush(1);
|
||||
}
|
||||
|
||||
static void proc_receive_read_commands(struct packet_reader *reader,
|
||||
struct command **commands)
|
||||
{
|
||||
struct command **tail = commands;
|
||||
|
||||
for (;;) {
|
||||
struct object_id old_oid, new_oid;
|
||||
struct command *cmd;
|
||||
const char *refname;
|
||||
const char *p;
|
||||
|
||||
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
|
||||
break;
|
||||
|
||||
if (parse_oid_hex(reader->line, &old_oid, &p) ||
|
||||
*p++ != ' ' ||
|
||||
parse_oid_hex(p, &new_oid, &p) ||
|
||||
*p++ != ' ' ||
|
||||
die_readline)
|
||||
die("protocol error: expected 'old new ref', got '%s'",
|
||||
reader->line);
|
||||
refname = p;
|
||||
FLEX_ALLOC_STR(cmd, ref_name, refname);
|
||||
oidcpy(&cmd->old_oid, &old_oid);
|
||||
oidcpy(&cmd->new_oid, &new_oid);
|
||||
|
||||
*tail = cmd;
|
||||
tail = &cmd->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void proc_receive_read_push_options(struct packet_reader *reader,
|
||||
struct string_list *options)
|
||||
{
|
||||
|
||||
if (no_push_options || !use_push_options)
|
||||
return;
|
||||
|
||||
while (1) {
|
||||
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
|
||||
break;
|
||||
|
||||
string_list_append(options, reader->line);
|
||||
}
|
||||
}
|
||||
|
||||
int cmd__proc_receive(int argc, const char **argv)
|
||||
{
|
||||
struct packet_reader reader;
|
||||
struct command *commands = NULL;
|
||||
struct string_list push_options = STRING_LIST_INIT_DUP;
|
||||
struct string_list_item *item;
|
||||
struct option options[] = {
|
||||
OPT_BOOL(0, "no-push-options", &no_push_options,
|
||||
"disable push options"),
|
||||
OPT_BOOL(0, "die-version", &die_version,
|
||||
"die during version negotiation"),
|
||||
OPT_BOOL(0, "die-readline", &die_readline,
|
||||
"die when readline"),
|
||||
OPT_STRING_LIST('r', "return", &returns, "old/new/ref/status/msg",
|
||||
"return of results"),
|
||||
OPT__VERBOSE(&verbose, "be verbose"),
|
||||
OPT_INTEGER('V', "version", &version,
|
||||
"use this protocol version number"),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
argc = parse_options(argc, argv, "test-tools", options, proc_receive_usage, 0);
|
||||
if (argc > 0)
|
||||
usage_msg_opt("Too many arguments.", proc_receive_usage, options);
|
||||
|
||||
packet_reader_init(&reader, 0, NULL, 0,
|
||||
PACKET_READ_CHOMP_NEWLINE |
|
||||
PACKET_READ_DIE_ON_ERR_PACKET);
|
||||
|
||||
sigchain_push(SIGPIPE, SIG_IGN);
|
||||
proc_receive_verison(&reader);
|
||||
proc_receive_read_commands(&reader, &commands);
|
||||
proc_receive_read_push_options(&reader, &push_options);
|
||||
|
||||
if (verbose) {
|
||||
struct command *cmd;
|
||||
|
||||
if (use_push_options || use_atomic)
|
||||
fprintf(stderr, "proc-receive:%s%s\n",
|
||||
use_atomic? " atomic": "",
|
||||
use_push_options ? " push_options": "");
|
||||
|
||||
for (cmd = commands; cmd; cmd = cmd->next)
|
||||
fprintf(stderr, "proc-receive< %s %s %s\n",
|
||||
oid_to_hex(&cmd->old_oid),
|
||||
oid_to_hex(&cmd->new_oid),
|
||||
cmd->ref_name);
|
||||
|
||||
if (push_options.nr > 0)
|
||||
for_each_string_list_item(item, &push_options)
|
||||
fprintf(stderr, "proc-receive< %s\n", item->string);
|
||||
|
||||
if (returns.nr)
|
||||
for_each_string_list_item(item, &returns)
|
||||
fprintf(stderr, "proc-receive> %s\n", item->string);
|
||||
}
|
||||
|
||||
if (returns.nr)
|
||||
for_each_string_list_item(item, &returns)
|
||||
packet_write_fmt(1, "%s\n", item->string);
|
||||
packet_flush(1);
|
||||
sigchain_pop(SIGPIPE);
|
||||
|
||||
return 0;
|
||||
}
|
@ -46,6 +46,7 @@ static struct test_cmd cmds[] = {
|
||||
{ "path-utils", cmd__path_utils },
|
||||
{ "pkt-line", cmd__pkt_line },
|
||||
{ "prio-queue", cmd__prio_queue },
|
||||
{ "proc-receive", cmd__proc_receive},
|
||||
{ "progress", cmd__progress },
|
||||
{ "reach", cmd__reach },
|
||||
{ "read-cache", cmd__read_cache },
|
||||
|
@ -35,6 +35,7 @@ int cmd__parse_pathspec_file(int argc, const char** argv);
|
||||
int cmd__path_utils(int argc, const char **argv);
|
||||
int cmd__pkt_line(int argc, const char **argv);
|
||||
int cmd__prio_queue(int argc, const char **argv);
|
||||
int cmd__proc_receive(int argc, const char **argv);
|
||||
int cmd__progress(int argc, const char **argv);
|
||||
int cmd__reach(int argc, const char **argv);
|
||||
int cmd__read_cache(int argc, const char **argv);
|
||||
|
117
t/t5411-proc-receive-hook.sh
Executable file
117
t/t5411-proc-receive-hook.sh
Executable file
@ -0,0 +1,117 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2020 Jiang Xin
|
||||
#
|
||||
|
||||
test_description='Test proc-receive hook'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
. "$TEST_DIRECTORY"/t5411/common-functions.sh
|
||||
|
||||
setup_upstream_and_workbench () {
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
test_expect_success "setup upstream and workbench" '
|
||||
rm -rf upstream.git &&
|
||||
rm -rf workbench &&
|
||||
git init --bare upstream.git &&
|
||||
git init workbench &&
|
||||
create_commits_in workbench A B &&
|
||||
(
|
||||
cd workbench &&
|
||||
# Try to make a stable fixed width for abbreviated commit ID,
|
||||
# this fixed-width oid will be replaced with "<OID>".
|
||||
git config core.abbrev 7 &&
|
||||
git tag -m "v123" v123 $A &&
|
||||
git remote add origin ../upstream.git &&
|
||||
git push origin master &&
|
||||
git update-ref refs/heads/master $A $B &&
|
||||
git -C ../upstream.git update-ref \
|
||||
refs/heads/master $A $B
|
||||
) &&
|
||||
TAG=$(git -C workbench rev-parse v123) &&
|
||||
|
||||
# setup pre-receive hook
|
||||
write_script upstream.git/hooks/pre-receive <<-\EOF &&
|
||||
exec >&2
|
||||
echo "# pre-receive hook"
|
||||
while read old new ref
|
||||
do
|
||||
echo "pre-receive< $old $new $ref"
|
||||
done
|
||||
EOF
|
||||
|
||||
# setup post-receive hook
|
||||
write_script upstream.git/hooks/post-receive <<-\EOF &&
|
||||
exec >&2
|
||||
echo "# post-receive hook"
|
||||
while read old new ref
|
||||
do
|
||||
echo "post-receive< $old $new $ref"
|
||||
done
|
||||
EOF
|
||||
|
||||
upstream=upstream.git
|
||||
'
|
||||
}
|
||||
|
||||
run_proc_receive_hook_test() {
|
||||
case $1 in
|
||||
http)
|
||||
PROTOCOL="HTTP protocol"
|
||||
URL_PREFIX="http://.*"
|
||||
;;
|
||||
local)
|
||||
PROTOCOL="builtin protocol"
|
||||
URL_PREFIX="\.\."
|
||||
;;
|
||||
esac
|
||||
|
||||
# Include test cases for both file and HTTP protocol
|
||||
for t in "$TEST_DIRECTORY"/t5411/test-*.sh
|
||||
do
|
||||
. "$t"
|
||||
done
|
||||
}
|
||||
|
||||
# Initialize the upstream repository and local workbench.
|
||||
setup_upstream_and_workbench
|
||||
|
||||
# Load test cases that only need to be executed once.
|
||||
for t in "$TEST_DIRECTORY"/t5411/once-*.sh
|
||||
do
|
||||
. "$t"
|
||||
done
|
||||
|
||||
# Initialize the upstream repository and local workbench.
|
||||
setup_upstream_and_workbench
|
||||
|
||||
# Run test cases for 'proc-receive' hook on local file protocol.
|
||||
run_proc_receive_hook_test local
|
||||
|
||||
ROOT_PATH="$PWD"
|
||||
. "$TEST_DIRECTORY"/lib-gpg.sh
|
||||
. "$TEST_DIRECTORY"/lib-httpd.sh
|
||||
. "$TEST_DIRECTORY"/lib-terminal.sh
|
||||
start_httpd
|
||||
|
||||
# Re-initialize the upstream repository and local workbench.
|
||||
setup_upstream_and_workbench
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
test_expect_success "setup for HTTP protocol" '
|
||||
git -C upstream.git config http.receivepack true &&
|
||||
upstream="$HTTPD_DOCUMENT_ROOT_PATH/upstream.git" &&
|
||||
mv upstream.git "$upstream" &&
|
||||
git -C workbench remote set-url origin "$HTTPD_URL/auth-push/smart/upstream.git" &&
|
||||
set_askpass user@host pass@host
|
||||
'
|
||||
|
||||
setup_askpass_helper
|
||||
|
||||
# Run test cases for 'proc-receive' hook on HTTP protocol.
|
||||
run_proc_receive_hook_test http
|
||||
|
||||
test_done
|
56
t/t5411/common-functions.sh
Normal file
56
t/t5411/common-functions.sh
Normal file
@ -0,0 +1,56 @@
|
||||
# Create commits in <repo> and assign each commit's oid to shell variables
|
||||
# given in the arguments (A, B, and C). E.g.:
|
||||
#
|
||||
# create_commits_in <repo> A B C
|
||||
#
|
||||
# NOTE: Never calling this function from a subshell since variable
|
||||
# assignments will disappear when subshell exits.
|
||||
create_commits_in () {
|
||||
repo="$1" &&
|
||||
if ! parent=$(git -C "$repo" rev-parse HEAD^{} --)
|
||||
then
|
||||
parent=
|
||||
fi &&
|
||||
T=$(git -C "$repo" write-tree) &&
|
||||
shift &&
|
||||
while test $# -gt 0
|
||||
do
|
||||
name=$1 &&
|
||||
test_tick &&
|
||||
if test -z "$parent"
|
||||
then
|
||||
oid=$(echo $name | git -C "$repo" commit-tree $T)
|
||||
else
|
||||
oid=$(echo $name | git -C "$repo" commit-tree -p $parent $T)
|
||||
fi &&
|
||||
eval $name=$oid &&
|
||||
parent=$oid &&
|
||||
shift ||
|
||||
return 1
|
||||
done &&
|
||||
git -C "$repo" update-ref refs/heads/master $oid
|
||||
}
|
||||
|
||||
# Format the output of git-push, git-show-ref and other commands to make a
|
||||
# user-friendly and stable text. We can easily prepare the expect text
|
||||
# without having to worry about future changes of the commit ID and spaces
|
||||
# of the output. Single quotes are replaced with double quotes, because
|
||||
# it is boring to prepare unquoted single quotes in expect text. We also
|
||||
# remove some locale error messages, which break test if we turn on
|
||||
# `GIT_TEST_GETTEXT_POISON=true` in order to test unintentional translations
|
||||
# on plumbing commands.
|
||||
make_user_friendly_and_stable_output () {
|
||||
sed \
|
||||
-e "s/ *\$//" \
|
||||
-e "s/ */ /g" \
|
||||
-e "s/'/\"/g" \
|
||||
-e "s/ / /g" \
|
||||
-e "s/$A/<COMMIT-A>/g" \
|
||||
-e "s/$B/<COMMIT-B>/g" \
|
||||
-e "s/$TAG/<TAG-v123>/g" \
|
||||
-e "s/$ZERO_OID/<ZERO-OID>/g" \
|
||||
-e "s/$(echo $A | cut -c1-7)[0-9a-f]*/<OID-A>/g" \
|
||||
-e "s/$(echo $B | cut -c1-7)[0-9a-f]*/<OID-B>/g" \
|
||||
-e "s#To $URL_PREFIX/upstream.git#To <URL/of/upstream.git>#" \
|
||||
-e "/^error: / d"
|
||||
}
|
88
t/t5411/once-0010-report-status-v1.sh
Normal file
88
t/t5411/once-0010-report-status-v1.sh
Normal file
@ -0,0 +1,88 @@
|
||||
test_expect_success "setup receive.procReceiveRefs" '
|
||||
git -C "$upstream" config --add receive.procReceiveRefs refs/for
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic1" \
|
||||
-r "option fall-through" \
|
||||
-r "ok refs/for/master/topic2" \
|
||||
-r "option refname refs/for/changes/23/123/1" \
|
||||
-r "option new-oid $A" \
|
||||
-r "ok refs/for/master/topic2" \
|
||||
-r "option refname refs/for/changes/24/124/2" \
|
||||
-r "option old-oid $B" \
|
||||
-r "option new-oid $A" \
|
||||
-r "option forced-update" \
|
||||
-r "ng refs/for/next/topic target branch not exist"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : (B) refs/for/master/topic1(A) foo(A) refs/for/next/topic(A) refs/for/master/topic2(A)
|
||||
test_expect_success "proc-receive: report status v1" '
|
||||
{
|
||||
printf "%s %s refs/heads/master\0report-status\n" \
|
||||
$A $B | packetize &&
|
||||
printf "%s %s refs/for/master/topic1\n" \
|
||||
$ZERO_OID $A | packetize &&
|
||||
printf "%s %s refs/heads/foo\n" \
|
||||
$ZERO_OID $A | packetize &&
|
||||
printf "%s %s refs/for/next/topic\n" \
|
||||
$ZERO_OID $A | packetize &&
|
||||
printf "%s %s refs/for/master/topic2\n" \
|
||||
$ZERO_OID $A | packetize &&
|
||||
printf 0000 &&
|
||||
printf "" | git -C "$upstream" pack-objects --stdout
|
||||
} | git receive-pack "$upstream" --stateless-rpc \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
# pre-receive hook
|
||||
pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
|
||||
pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic1
|
||||
pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/foo
|
||||
pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
|
||||
pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic2
|
||||
# proc-receive hook
|
||||
proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic1
|
||||
proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
|
||||
proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic2
|
||||
proc-receive> ok refs/for/master/topic1
|
||||
proc-receive> option fall-through
|
||||
proc-receive> ok refs/for/master/topic2
|
||||
proc-receive> option refname refs/for/changes/23/123/1
|
||||
proc-receive> option new-oid <COMMIT-A>
|
||||
proc-receive> ok refs/for/master/topic2
|
||||
proc-receive> option refname refs/for/changes/24/124/2
|
||||
proc-receive> option old-oid <COMMIT-B>
|
||||
proc-receive> option new-oid <COMMIT-A>
|
||||
proc-receive> option forced-update
|
||||
proc-receive> ng refs/for/next/topic target branch not exist
|
||||
000eunpack ok
|
||||
0019ok refs/heads/master
|
||||
001eok refs/for/master/topic1
|
||||
0016ok refs/heads/foo
|
||||
0033ng refs/for/next/topic target branch not exist
|
||||
001eok refs/for/master/topic2
|
||||
0000# post-receive hook
|
||||
post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
|
||||
post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic1
|
||||
post-receive< <ZERO-OID> <COMMIT-A> refs/heads/foo
|
||||
post-receive< <ZERO-OID> <COMMIT-A> refs/for/changes/23/123/1
|
||||
post-receive< <COMMIT-B> <COMMIT-A> refs/for/changes/24/124/2
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/for/master/topic1
|
||||
<COMMIT-A> refs/heads/foo
|
||||
<COMMIT-B> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
143
t/t5411/test-0000-standard-git-push.sh
Normal file
143
t/t5411/test-0000-standard-git-push.sh
Normal file
@ -0,0 +1,143 @@
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git-push : master(B) next(A)
|
||||
test_expect_success "git-push ($PROTOCOL)" '
|
||||
git -C workbench push origin \
|
||||
$B:refs/heads/master \
|
||||
HEAD:refs/heads/next \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||
To <URL/of/upstream.git>
|
||||
<OID-A>..<OID-B> <COMMIT-B> -> master
|
||||
* [new branch] HEAD -> next
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-B> refs/heads/master
|
||||
<COMMIT-A> refs/heads/next
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Refs of upstream : master(B) next(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git-push --atomic: master(A) next(B)
|
||||
test_expect_success "git-push --atomic ($PROTOCOL)" '
|
||||
test_must_fail git -C workbench push --atomic origin \
|
||||
master \
|
||||
$B:refs/heads/next \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out |
|
||||
sed -n \
|
||||
-e "/^To / { s/ */ /g; p; }" \
|
||||
-e "/^ ! / { s/ */ /g; p; }" \
|
||||
>actual &&
|
||||
cat >expect <<-EOF &&
|
||||
To <URL/of/upstream.git>
|
||||
! [rejected] master -> master (non-fast-forward)
|
||||
! [rejected] <COMMIT-B> -> next (atomic push failed)
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-B> refs/heads/master
|
||||
<COMMIT-A> refs/heads/next
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Refs of upstream : master(B) next(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git-push : master(A) next(B)
|
||||
test_expect_success "non-fast-forward git-push ($PROTOCOL)" '
|
||||
test_must_fail git \
|
||||
-C workbench \
|
||||
-c advice.pushUpdateRejected=false \
|
||||
push origin \
|
||||
master \
|
||||
$B:refs/heads/next \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/next
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/next
|
||||
To <URL/of/upstream.git>
|
||||
<OID-A>..<OID-B> <COMMIT-B> -> next
|
||||
! [rejected] master -> master (non-fast-forward)
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-B> refs/heads/master
|
||||
<COMMIT-B> refs/heads/next
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Refs of upstream : master(B) next(B)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git-push -f : master(A) NULL tags/v123 refs/review/master/topic(A) a/b/c(A)
|
||||
test_expect_success "git-push -f ($PROTOCOL)" '
|
||||
git -C workbench push -f origin \
|
||||
refs/tags/v123 \
|
||||
:refs/heads/next \
|
||||
master \
|
||||
master:refs/review/master/topic \
|
||||
HEAD:refs/heads/a/b/c \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <COMMIT-B> <COMMIT-A> refs/heads/master
|
||||
remote: pre-receive< <COMMIT-B> <ZERO-OID> refs/heads/next
|
||||
remote: pre-receive< <ZERO-OID> <TAG-v123> refs/tags/v123
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/review/master/topic
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/a/b/c
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/heads/master
|
||||
remote: post-receive< <COMMIT-B> <ZERO-OID> refs/heads/next
|
||||
remote: post-receive< <ZERO-OID> <TAG-v123> refs/tags/v123
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/review/master/topic
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/a/b/c
|
||||
To <URL/of/upstream.git>
|
||||
+ <OID-B>...<OID-A> master -> master (forced update)
|
||||
- [deleted] next
|
||||
* [new tag] v123 -> v123
|
||||
* [new reference] master -> refs/review/master/topic
|
||||
* [new branch] HEAD -> a/b/c
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/a/b/c
|
||||
<COMMIT-A> refs/heads/master
|
||||
<COMMIT-A> refs/review/master/topic
|
||||
<TAG-v123> refs/tags/v123
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A) tags/v123 refs/review/master/topic(A) a/b/c(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
test_expect_success "cleanup ($PROTOCOL)" '
|
||||
(
|
||||
cd "$upstream" &&
|
||||
git update-ref -d refs/review/master/topic &&
|
||||
git update-ref -d refs/tags/v123 &&
|
||||
git update-ref -d refs/heads/a/b/c
|
||||
)
|
||||
'
|
147
t/t5411/test-0001-standard-git-push--porcelain.sh
Normal file
147
t/t5411/test-0001-standard-git-push--porcelain.sh
Normal file
@ -0,0 +1,147 @@
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git-push : master(B) next(A)
|
||||
test_expect_success "git-push ($PROTOCOL/porcelain)" '
|
||||
git -C workbench push --porcelain origin \
|
||||
$B:refs/heads/master \
|
||||
HEAD:refs/heads/next \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||
To <URL/of/upstream.git>
|
||||
<COMMIT-B>:refs/heads/master <OID-A>..<OID-B>
|
||||
* HEAD:refs/heads/next [new branch]
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-B> refs/heads/master
|
||||
<COMMIT-A> refs/heads/next
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Refs of upstream : master(B) next(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git-push --atomic: master(A) next(B)
|
||||
test_expect_success "git-push --atomic ($PROTOCOL/porcelain)" '
|
||||
test_must_fail git -C workbench push --atomic --porcelain origin \
|
||||
master \
|
||||
$B:refs/heads/next \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out |
|
||||
sed -n \
|
||||
-e "s/^# GETTEXT POISON #//" \
|
||||
-e "/^To / { s/ */ /g; p; }" \
|
||||
-e "/^! / { s/ */ /g; p; }" \
|
||||
>actual &&
|
||||
cat >expect <<-EOF &&
|
||||
To <URL/of/upstream.git>
|
||||
! refs/heads/master:refs/heads/master [rejected] (non-fast-forward)
|
||||
! <COMMIT-B>:refs/heads/next [rejected] (atomic push failed)
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-B> refs/heads/master
|
||||
<COMMIT-A> refs/heads/next
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Refs of upstream : master(B) next(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git-push : master(A) next(B)
|
||||
test_expect_success "non-fast-forward git-push ($PROTOCOL/porcelain)" '
|
||||
test_must_fail git \
|
||||
-C workbench \
|
||||
-c advice.pushUpdateRejected=false \
|
||||
push --porcelain origin \
|
||||
master \
|
||||
$B:refs/heads/next \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/next
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/next
|
||||
To <URL/of/upstream.git>
|
||||
<COMMIT-B>:refs/heads/next <OID-A>..<OID-B>
|
||||
! refs/heads/master:refs/heads/master [rejected] (non-fast-forward)
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-B> refs/heads/master
|
||||
<COMMIT-B> refs/heads/next
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Refs of upstream : master(B) next(B)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git-push -f : master(A) NULL tags/v123 refs/review/master/topic(A) a/b/c(A)
|
||||
test_expect_success "git-push -f ($PROTOCOL/porcelain)" '
|
||||
git -C workbench push --porcelain -f origin \
|
||||
refs/tags/v123 \
|
||||
:refs/heads/next \
|
||||
master \
|
||||
master:refs/review/master/topic \
|
||||
HEAD:refs/heads/a/b/c \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <COMMIT-B> <COMMIT-A> refs/heads/master
|
||||
remote: pre-receive< <COMMIT-B> <ZERO-OID> refs/heads/next
|
||||
remote: pre-receive< <ZERO-OID> <TAG-v123> refs/tags/v123
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/review/master/topic
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/a/b/c
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/heads/master
|
||||
remote: post-receive< <COMMIT-B> <ZERO-OID> refs/heads/next
|
||||
remote: post-receive< <ZERO-OID> <TAG-v123> refs/tags/v123
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/review/master/topic
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/a/b/c
|
||||
To <URL/of/upstream.git>
|
||||
+ refs/heads/master:refs/heads/master <OID-B>...<OID-A> (forced update)
|
||||
- :refs/heads/next [deleted]
|
||||
* refs/tags/v123:refs/tags/v123 [new tag]
|
||||
* refs/heads/master:refs/review/master/topic [new reference]
|
||||
* HEAD:refs/heads/a/b/c [new branch]
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/a/b/c
|
||||
<COMMIT-A> refs/heads/master
|
||||
<COMMIT-A> refs/review/master/topic
|
||||
<TAG-v123> refs/tags/v123
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A) tags/v123 refs/review/master/topic(A) a/b/c(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
test_expect_success "cleanup ($PROTOCOL/porcelain)" '
|
||||
(
|
||||
cd "$upstream" &&
|
||||
git update-ref -d refs/review/master/topic &&
|
||||
git update-ref -d refs/tags/v123 &&
|
||||
git update-ref -d refs/heads/a/b/c
|
||||
)
|
||||
'
|
33
t/t5411/test-0002-pre-receive-declined.sh
Normal file
33
t/t5411/test-0002-pre-receive-declined.sh
Normal file
@ -0,0 +1,33 @@
|
||||
test_expect_success "setup pre-receive hook ($PROTOCOL)" '
|
||||
mv "$upstream/hooks/pre-receive" "$upstream/hooks/pre-receive.ok" &&
|
||||
write_script "$upstream/hooks/pre-receive" <<-EOF
|
||||
exit 1
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git-push : master(B) next(A)
|
||||
test_expect_success "git-push is declined ($PROTOCOL)" '
|
||||
test_must_fail git -C workbench push origin \
|
||||
$B:refs/heads/master \
|
||||
HEAD:refs/heads/next \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
To <URL/of/upstream.git>
|
||||
! [remote rejected] <COMMIT-B> -> master (pre-receive hook declined)
|
||||
! [remote rejected] HEAD -> next (pre-receive hook declined)
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "cleanup ($PROTOCOL)" '
|
||||
mv "$upstream/hooks/pre-receive.ok" "$upstream/hooks/pre-receive"
|
||||
'
|
34
t/t5411/test-0003-pre-receive-declined--porcelain.sh
Normal file
34
t/t5411/test-0003-pre-receive-declined--porcelain.sh
Normal file
@ -0,0 +1,34 @@
|
||||
test_expect_success "setup pre-receive hook ($PROTOCOL/porcelain)" '
|
||||
mv "$upstream/hooks/pre-receive" "$upstream/hooks/pre-receive.ok" &&
|
||||
write_script "$upstream/hooks/pre-receive" <<-EOF
|
||||
exit 1
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git-push : master(B) next(A)
|
||||
test_expect_success "git-push is declined ($PROTOCOL/porcelain)" '
|
||||
test_must_fail git -C workbench push --porcelain origin \
|
||||
$B:refs/heads/master \
|
||||
HEAD:refs/heads/next \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
To <URL/of/upstream.git>
|
||||
! <COMMIT-B>:refs/heads/master [remote rejected] (pre-receive hook declined)
|
||||
! HEAD:refs/heads/next [remote rejected] (pre-receive hook declined)
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "cleanup ($PROTOCOL/porcelain)" '
|
||||
mv "$upstream/hooks/pre-receive.ok" "$upstream/hooks/pre-receive"
|
||||
'
|
7
t/t5411/test-0010-proc-receive-settings.sh
Normal file
7
t/t5411/test-0010-proc-receive-settings.sh
Normal file
@ -0,0 +1,7 @@
|
||||
test_expect_success "add two receive.procReceiveRefs settings" '
|
||||
(
|
||||
cd "$upstream" &&
|
||||
git config --add receive.procReceiveRefs refs/for &&
|
||||
git config --add receive.procReceiveRefs refs/review/
|
||||
)
|
||||
'
|
64
t/t5411/test-0011-no-hook-error.sh
Normal file
64
t/t5411/test-0011-no-hook-error.sh
Normal file
@ -0,0 +1,64 @@
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : next(A) refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: no hook, fail to push special ref ($PROTOCOL)" '
|
||||
test_must_fail git -C workbench push origin \
|
||||
HEAD:next \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: error: cannot find hook "proc-receive"
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||
To <URL/of/upstream.git>
|
||||
* [new branch] HEAD -> next
|
||||
! [remote rejected] HEAD -> refs/for/master/topic (fail to run proc-receive hook)
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
<COMMIT-A> refs/heads/next
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A) next(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
test_expect_success "cleanup ($PROTOCOL)" '
|
||||
git -C "$upstream" update-ref -d refs/heads/next
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push --atomic: (B) next(A) refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: no hook, all failed for atomic push ($PROTOCOL)" '
|
||||
test_must_fail git -C workbench push --atomic origin \
|
||||
$B:master \
|
||||
HEAD:next \
|
||||
HEAD:refs/for/master/topic >out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: error: cannot find hook "proc-receive"
|
||||
To <URL/of/upstream.git>
|
||||
! [remote rejected] <COMMIT-B> -> master (fail to run proc-receive hook)
|
||||
! [remote rejected] HEAD -> next (fail to run proc-receive hook)
|
||||
! [remote rejected] HEAD -> refs/for/master/topic (fail to run proc-receive hook)
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
66
t/t5411/test-0012-no-hook-error--porcelain.sh
Normal file
66
t/t5411/test-0012-no-hook-error--porcelain.sh
Normal file
@ -0,0 +1,66 @@
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : next(A) refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: no hook, fail to push special ref ($PROTOCOL/porcelain)" '
|
||||
test_must_fail git -C workbench push --porcelain origin \
|
||||
HEAD:next \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: error: cannot find hook "proc-receive"
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||
To <URL/of/upstream.git>
|
||||
* HEAD:refs/heads/next [new branch]
|
||||
! HEAD:refs/for/master/topic [remote rejected] (fail to run proc-receive hook)
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
<COMMIT-A> refs/heads/next
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A) next(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
test_expect_success "cleanup ($PROTOCOL/porcelain)" '
|
||||
git -C "$upstream" update-ref -d refs/heads/next
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push --atomic: (B) next(A) refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: no hook, all failed for atomic push ($PROTOCOL/porcelain)" '
|
||||
test_must_fail git -C workbench push --porcelain --atomic origin \
|
||||
$B:master \
|
||||
HEAD:next \
|
||||
HEAD:refs/for/master/topic >out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: error: cannot find hook "proc-receive"
|
||||
To <URL/of/upstream.git>
|
||||
! <COMMIT-B>:refs/heads/master [remote rejected] (fail to run proc-receive hook)
|
||||
! HEAD:refs/heads/next [remote rejected] (fail to run proc-receive hook)
|
||||
! HEAD:refs/for/master/topic [remote rejected] (fail to run proc-receive hook)
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
217
t/t5411/test-0013-bad-protocol.sh
Normal file
217
t/t5411/test-0013-bad-protocol.sh
Normal file
@ -0,0 +1,217 @@
|
||||
test_expect_success "setup proc-receive hook (unknown version, $PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v --version 2
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: bad protocol (unknown version, $PROTOCOL)" '
|
||||
test_must_fail git -C workbench push origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
|
||||
# Check status report for git-push
|
||||
sed -n \
|
||||
-e "/^To / { p; n; p; }" \
|
||||
<actual >actual-report &&
|
||||
cat >expect <<-EOF &&
|
||||
To <URL/of/upstream.git>
|
||||
! [remote rejected] HEAD -> refs/for/master/topic (fail to run proc-receive hook)
|
||||
EOF
|
||||
test_cmp expect actual-report &&
|
||||
|
||||
# Check error message from "receive-pack", but ignore unstable fatal error
|
||||
# message ("remote: fatal: the remote end hung up unexpectedly") which
|
||||
# is different from the remote HTTP server with different locale settings.
|
||||
grep "^remote: error:" <actual >actual-error &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: error: proc-receive version "2" is not supported
|
||||
EOF
|
||||
test_cmp expect actual-error &&
|
||||
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (hook --die-version, $PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v --die-version
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: bad protocol (hook --die-version, $PROTOCOL)" '
|
||||
test_must_fail git -C workbench push origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: fatal: bad protocol version: 1
|
||||
remote: error: proc-receive version "0" is not supported
|
||||
To <URL/of/upstream.git>
|
||||
! [remote rejected] HEAD -> refs/for/master/topic (fail to run proc-receive hook)
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (hook --die-readline, $PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v --die-readline
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: bad protocol (hook --die-readline, $PROTOCOL)" '
|
||||
test_must_fail git -C workbench push origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
|
||||
grep "remote: fatal: protocol error: expected \"old new ref\", got \"<ZERO-OID> <COMMIT-A> refs/for/master/topic\"" actual &&
|
||||
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (no report, $PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : next(A) refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: bad protocol (no report, $PROTOCOL)" '
|
||||
test_must_fail git -C workbench push origin \
|
||||
HEAD:refs/heads/next \
|
||||
HEAD:refs/for/master/topic >out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||
To <URL/of/upstream.git>
|
||||
* [new branch] HEAD -> next
|
||||
! [remote rejected] HEAD -> refs/for/master/topic (proc-receive failed to report status)
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
<COMMIT-A> refs/heads/next
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A) next(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
test_expect_success "cleanup ($PROTOCOL)" '
|
||||
git -C "$upstream" update-ref -d refs/heads/next
|
||||
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (no ref, $PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/master/topic
|
||||
test_expect_success "proc-receive: bad protocol (no ref, $PROTOCOL)" '
|
||||
test_must_fail git -C workbench push origin \
|
||||
HEAD:refs/for/master/topic\
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok
|
||||
remote: error: proc-receive reported incomplete status line: "ok"
|
||||
To <URL/of/upstream.git>
|
||||
! [remote rejected] HEAD -> refs/for/master/topic (proc-receive failed to report status)
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (unknown status, $PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "xx refs/for/master/topic"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/master/topic
|
||||
test_expect_success "proc-receive: bad protocol (unknown status, $PROTOCOL)" '
|
||||
test_must_fail git -C workbench push origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> xx refs/for/master/topic
|
||||
remote: error: proc-receive reported bad status "xx" on ref "refs/for/master/topic"
|
||||
To <URL/of/upstream.git>
|
||||
! [remote rejected] HEAD -> refs/for/master/topic (proc-receive failed to report status)
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
160
t/t5411/test-0014-bad-protocol--porcelain.sh
Normal file
160
t/t5411/test-0014-bad-protocol--porcelain.sh
Normal file
@ -0,0 +1,160 @@
|
||||
test_expect_success "setup proc-receive hook (unknown version, $PROTOCOL/porcelain)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v --version 2
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: bad protocol (unknown version, $PROTOCOL/porcelain)" '
|
||||
test_must_fail git -C workbench push --porcelain origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
|
||||
# Check status report for git-push
|
||||
sed -n \
|
||||
-e "/^To / { p; n; p; n; p; }" \
|
||||
<actual >actual-report &&
|
||||
cat >expect <<-EOF &&
|
||||
To <URL/of/upstream.git>
|
||||
! HEAD:refs/for/master/topic [remote rejected] (fail to run proc-receive hook)
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual-report &&
|
||||
|
||||
# Check error message from "receive-pack", but ignore unstable fatal error
|
||||
# message ("remote: fatal: the remote end hung up unexpectedly") which
|
||||
# is different from the remote HTTP server with different locale settings.
|
||||
grep "^remote: error:" <actual >actual-error &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: error: proc-receive version "2" is not supported
|
||||
EOF
|
||||
test_cmp expect actual-error &&
|
||||
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (no report, $PROTOCOL/porcelain)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : next(A) refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: bad protocol (no report, $PROTOCOL/porcelain)" '
|
||||
test_must_fail git -C workbench push --porcelain origin \
|
||||
HEAD:refs/heads/next \
|
||||
HEAD:refs/for/master/topic >out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||
To <URL/of/upstream.git>
|
||||
* HEAD:refs/heads/next [new branch]
|
||||
! HEAD:refs/for/master/topic [remote rejected] (proc-receive failed to report status)
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
<COMMIT-A> refs/heads/next
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A) next(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
test_expect_success "cleanup ($PROTOCOL/porcelain)" '
|
||||
git -C "$upstream" update-ref -d refs/heads/next
|
||||
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (no ref, $PROTOCOL/porcelain)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/master/topic
|
||||
test_expect_success "proc-receive: bad protocol (no ref, $PROTOCOL/porcelain)" '
|
||||
test_must_fail git -C workbench push --porcelain origin \
|
||||
HEAD:refs/for/master/topic\
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok
|
||||
remote: error: proc-receive reported incomplete status line: "ok"
|
||||
To <URL/of/upstream.git>
|
||||
! HEAD:refs/for/master/topic [remote rejected] (proc-receive failed to report status)
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (unknown status, $PROTOCOL/porcelain)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "xx refs/for/master/topic"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/master/topic
|
||||
test_expect_success "proc-receive: bad protocol (unknown status, $PROTOCOL/porcelain)" '
|
||||
test_must_fail git -C workbench push --porcelain origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> xx refs/for/master/topic
|
||||
remote: error: proc-receive reported bad status "xx" on ref "refs/for/master/topic"
|
||||
To <URL/of/upstream.git>
|
||||
! HEAD:refs/for/master/topic [remote rejected] (proc-receive failed to report status)
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
67
t/t5411/test-0020-report-ng.sh
Normal file
67
t/t5411/test-0020-report-ng.sh
Normal file
@ -0,0 +1,67 @@
|
||||
test_expect_success "setup proc-receive hook (ng, no message, $PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ng refs/for/master/topic"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/master/topic
|
||||
test_expect_success "proc-receive: fail to update (ng, no message, $PROTOCOL)" '
|
||||
test_must_fail git -C workbench push origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ng refs/for/master/topic
|
||||
To <URL/of/upstream.git>
|
||||
! [remote rejected] HEAD -> refs/for/master/topic (failed)
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (ng message, $PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ng refs/for/master/topic error msg"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/master/topic
|
||||
test_expect_success "proc-receive: fail to update (ng, with message, $PROTOCOL)" '
|
||||
test_must_fail git -C workbench push origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ng refs/for/master/topic error msg
|
||||
To <URL/of/upstream.git>
|
||||
! [remote rejected] HEAD -> refs/for/master/topic (error msg)
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
69
t/t5411/test-0021-report-ng--porcelain.sh
Normal file
69
t/t5411/test-0021-report-ng--porcelain.sh
Normal file
@ -0,0 +1,69 @@
|
||||
test_expect_success "setup proc-receive hook (ng, no message, $PROTOCOL/porcelain)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ng refs/for/master/topic"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/master/topic
|
||||
test_expect_success "proc-receive: fail to update (ng, no message, $PROTOCOL/porcelain)" '
|
||||
test_must_fail git -C workbench push --porcelain origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ng refs/for/master/topic
|
||||
To <URL/of/upstream.git>
|
||||
! HEAD:refs/for/master/topic [remote rejected] (failed)
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (ng message, $PROTOCOL/porcelain)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ng refs/for/master/topic error msg"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/master/topic
|
||||
test_expect_success "proc-receive: fail to update (ng, with message, $PROTOCOL/porcelain)" '
|
||||
test_must_fail git -C workbench push --porcelain origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ng refs/for/master/topic error msg
|
||||
To <URL/of/upstream.git>
|
||||
! HEAD:refs/for/master/topic [remote rejected] (error msg)
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
45
t/t5411/test-0022-report-unexpect-ref.sh
Normal file
45
t/t5411/test-0022-report-unexpect-ref.sh
Normal file
@ -0,0 +1,45 @@
|
||||
test_expect_success "setup proc-receive hook (unexpected ref, $PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/heads/master"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : (B) refs/for/master/topic
|
||||
test_expect_success "proc-receive: report unexpected ref ($PROTOCOL)" '
|
||||
test_must_fail git -C workbench push origin \
|
||||
$B:refs/heads/master \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/heads/master
|
||||
remote: error: proc-receive reported status on unexpected ref: refs/heads/master
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
|
||||
To <URL/of/upstream.git>
|
||||
<OID-A>..<OID-B> <COMMIT-B> -> master
|
||||
! [remote rejected] HEAD -> refs/for/master/topic (proc-receive failed to report status)
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-B> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Refs of upstream : master(B)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
test_expect_success "cleanup ($PROTOCOL)" '
|
||||
git -C "$upstream" update-ref refs/heads/master $A
|
||||
'
|
46
t/t5411/test-0023-report-unexpect-ref--porcelain.sh
Normal file
46
t/t5411/test-0023-report-unexpect-ref--porcelain.sh
Normal file
@ -0,0 +1,46 @@
|
||||
test_expect_success "setup proc-receive hook (unexpected ref, $PROTOCOL/porcelain)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/heads/master"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : (B) refs/for/master/topic
|
||||
test_expect_success "proc-receive: report unexpected ref ($PROTOCOL/porcelain)" '
|
||||
test_must_fail git -C workbench push --porcelain origin \
|
||||
$B:refs/heads/master \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/heads/master
|
||||
remote: error: proc-receive reported status on unexpected ref: refs/heads/master
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
|
||||
To <URL/of/upstream.git>
|
||||
<COMMIT-B>:refs/heads/master <OID-A>..<OID-B>
|
||||
! HEAD:refs/for/master/topic [remote rejected] (proc-receive failed to report status)
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-B> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Refs of upstream : master(B)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
test_expect_success "cleanup ($PROTOCOL/porcelain)" '
|
||||
git -C "$upstream" update-ref refs/heads/master $A
|
||||
'
|
34
t/t5411/test-0024-report-unknown-ref.sh
Normal file
34
t/t5411/test-0024-report-unknown-ref.sh
Normal file
@ -0,0 +1,34 @@
|
||||
test_expect_success "setup proc-receive hook (unexpected ref, $PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/a/b/c/my/topic
|
||||
test_expect_success "proc-receive: report unknown reference ($PROTOCOL)" '
|
||||
test_must_fail git -C workbench push origin \
|
||||
HEAD:refs/for/a/b/c/my/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/my/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/my/topic
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: error: proc-receive reported status on unknown ref: refs/for/master/topic
|
||||
To <URL/of/upstream.git>
|
||||
! [remote rejected] HEAD -> refs/for/a/b/c/my/topic (proc-receive failed to report status)
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
35
t/t5411/test-0025-report-unknown-ref--porcelain.sh
Normal file
35
t/t5411/test-0025-report-unknown-ref--porcelain.sh
Normal file
@ -0,0 +1,35 @@
|
||||
test_expect_success "setup proc-receive hook (unexpected ref, $PROTOCOL/porcelain)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/a/b/c/my/topic
|
||||
test_expect_success "proc-receive: report unknown reference ($PROTOCOL/porcelain)" '
|
||||
test_must_fail git -C workbench push --porcelain origin \
|
||||
HEAD:refs/for/a/b/c/my/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/my/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/my/topic
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: error: proc-receive reported status on unknown ref: refs/for/master/topic
|
||||
To <URL/of/upstream.git>
|
||||
! HEAD:refs/for/a/b/c/my/topic [remote rejected] (proc-receive failed to report status)
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
79
t/t5411/test-0026-push-options.sh
Normal file
79
t/t5411/test-0026-push-options.sh
Normal file
@ -0,0 +1,79 @@
|
||||
test_expect_success "setup proc-receive hook and disable push-options ($PROTOCOL)" '
|
||||
git -C "$upstream" config receive.advertisePushOptions false &&
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push -o ... : refs/for/master/topic
|
||||
test_expect_success "proc-receive: not support push options ($PROTOCOL)" '
|
||||
test_must_fail git -C workbench push \
|
||||
-o issue=123 \
|
||||
-o reviewer=user1 \
|
||||
origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
test_i18ngrep "fatal: the receiving end does not support push options" \
|
||||
actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "enable push options ($PROTOCOL)" '
|
||||
git -C "$upstream" config receive.advertisePushOptions true
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push -o ... : next(A) refs/for/master/topic
|
||||
test_expect_success "proc-receive: push with options ($PROTOCOL)" '
|
||||
git -C workbench push \
|
||||
--atomic \
|
||||
-o issue=123 \
|
||||
-o reviewer=user1 \
|
||||
origin \
|
||||
HEAD:refs/heads/next \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive: atomic push_options
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive< issue=123
|
||||
remote: proc-receive< reviewer=user1
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
To <URL/of/upstream.git>
|
||||
* [new branch] HEAD -> next
|
||||
* [new reference] HEAD -> refs/for/master/topic
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
<COMMIT-A> refs/heads/next
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A) next(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
test_expect_success "cleanup ($PROTOCOL)" '
|
||||
git -C "$upstream" update-ref -d refs/heads/next
|
||||
'
|
82
t/t5411/test-0027-push-options--porcelain.sh
Normal file
82
t/t5411/test-0027-push-options--porcelain.sh
Normal file
@ -0,0 +1,82 @@
|
||||
test_expect_success "setup proc-receive hook and disable push-options ($PROTOCOL/porcelain)" '
|
||||
git -C "$upstream" config receive.advertisePushOptions false &&
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push -o ... : refs/for/master/topic
|
||||
test_expect_success "proc-receive: not support push options ($PROTOCOL/porcelain)" '
|
||||
test_must_fail git -C workbench push \
|
||||
--porcelain \
|
||||
-o issue=123 \
|
||||
-o reviewer=user1 \
|
||||
origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
test_i18ngrep "fatal: the receiving end does not support push options" \
|
||||
actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "enable push options ($PROTOCOL/porcelain)" '
|
||||
git -C "$upstream" config receive.advertisePushOptions true
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push -o ... : next(A) refs/for/master/topic
|
||||
test_expect_success "proc-receive: push with options ($PROTOCOL/porcelain)" '
|
||||
git -C workbench push \
|
||||
--porcelain \
|
||||
--atomic \
|
||||
-o issue=123 \
|
||||
-o reviewer=user1 \
|
||||
origin \
|
||||
HEAD:refs/heads/next \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive: atomic push_options
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive< issue=123
|
||||
remote: proc-receive< reviewer=user1
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/next
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
To <URL/of/upstream.git>
|
||||
* HEAD:refs/heads/next [new branch]
|
||||
* HEAD:refs/for/master/topic [new reference]
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
<COMMIT-A> refs/heads/next
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A) next(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
test_expect_success "cleanup ($PROTOCOL/porcelain)" '
|
||||
git -C "$upstream" update-ref -d refs/heads/next
|
||||
'
|
35
t/t5411/test-0030-report-ok.sh
Normal file
35
t/t5411/test-0030-report-ok.sh
Normal file
@ -0,0 +1,35 @@
|
||||
test_expect_success "setup proc-receive hook (ok, $PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/master/topic
|
||||
test_expect_success "proc-receive: ok ($PROTOCOL)" '
|
||||
git -C workbench push origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
To <URL/of/upstream.git>
|
||||
* [new reference] HEAD -> refs/for/master/topic
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
36
t/t5411/test-0031-report-ok--porcelain.sh
Normal file
36
t/t5411/test-0031-report-ok--porcelain.sh
Normal file
@ -0,0 +1,36 @@
|
||||
test_expect_success "setup proc-receive hook (ok, $PROTOCOL/porcelain)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/master/topic
|
||||
test_expect_success "proc-receive: ok ($PROTOCOL/porcelain)" '
|
||||
git -C workbench push --porcelain origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
To <URL/of/upstream.git>
|
||||
* HEAD:refs/for/master/topic [new reference]
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
256
t/t5411/test-0032-report-with-options.sh
Normal file
256
t/t5411/test-0032-report-with-options.sh
Normal file
@ -0,0 +1,256 @@
|
||||
test_expect_success "setup proc-receive hook (option without matching ok, $PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "option refname refs/pull/123/head" \
|
||||
-r "option old-oid $B"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: report option without matching ok ($PROTOCOL)" '
|
||||
test_must_fail git -C workbench push origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/pull/123/head
|
||||
remote: proc-receive> option old-oid <COMMIT-B>
|
||||
remote: error: proc-receive reported "option" without a matching "ok/ng" directive
|
||||
To <URL/of/upstream.git>
|
||||
! [remote rejected] HEAD -> refs/for/master/topic (proc-receive failed to report status)
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (option refname, $PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/pull/123/head"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: report option refname ($PROTOCOL)" '
|
||||
git -C workbench push origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/pull/123/head
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/pull/123/head
|
||||
To <URL/of/upstream.git>
|
||||
* [new reference] HEAD -> refs/pull/123/head
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (option refname and forced-update, $PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/pull/123/head" \
|
||||
-r "option forced-update"
|
||||
EOF
|
||||
'
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: report option refname and forced-update ($PROTOCOL)" '
|
||||
git -C workbench push origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/pull/123/head
|
||||
remote: proc-receive> option forced-update
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/pull/123/head
|
||||
To <URL/of/upstream.git>
|
||||
* [new reference] HEAD -> refs/pull/123/head
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (option refname and old-oid, $PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/pull/123/head" \
|
||||
-r "option old-oid $B"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: report option refname and old-oid ($PROTOCOL)" '
|
||||
git -C workbench push origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/pull/123/head
|
||||
remote: proc-receive> option old-oid <COMMIT-B>
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/pull/123/head
|
||||
To <URL/of/upstream.git>
|
||||
<OID-B>..<OID-A> HEAD -> refs/pull/123/head
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (option old-oid, $PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option old-oid $B"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: report option old-oid ($PROTOCOL)" '
|
||||
git -C workbench push origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option old-oid <COMMIT-B>
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/for/master/topic
|
||||
To <URL/of/upstream.git>
|
||||
<OID-B>..<OID-A> HEAD -> refs/for/master/topic
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (option old-oid and new-oid, $PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option old-oid $A" \
|
||||
-r "option new-oid $B"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: report option old-oid and new-oid ($PROTOCOL)" '
|
||||
git -C workbench push origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option old-oid <COMMIT-A>
|
||||
remote: proc-receive> option new-oid <COMMIT-B>
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic
|
||||
To <URL/of/upstream.git>
|
||||
<OID-A>..<OID-B> HEAD -> refs/for/master/topic
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (report with multiple rewrites, $PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/a/b/c/topic" \
|
||||
-r "ok refs/for/next/topic" \
|
||||
-r "option refname refs/pull/123/head" \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/pull/124/head" \
|
||||
-r "option old-oid $B" \
|
||||
-r "option forced-update" \
|
||||
-r "option new-oid $A"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: report with multiple rewrites ($PROTOCOL)" '
|
||||
git -C workbench push origin \
|
||||
HEAD:refs/for/next/topic \
|
||||
HEAD:refs/for/a/b/c/topic \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/for/a/b/c/topic
|
||||
remote: proc-receive> ok refs/for/next/topic
|
||||
remote: proc-receive> option refname refs/pull/123/head
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/pull/124/head
|
||||
remote: proc-receive> option old-oid <COMMIT-B>
|
||||
remote: proc-receive> option forced-update
|
||||
remote: proc-receive> option new-oid <COMMIT-A>
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/pull/123/head
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic
|
||||
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/pull/124/head
|
||||
To <URL/of/upstream.git>
|
||||
* [new reference] HEAD -> refs/pull/123/head
|
||||
* [new reference] HEAD -> refs/for/a/b/c/topic
|
||||
+ <OID-B>...<OID-A> HEAD -> refs/pull/124/head (forced update)
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
265
t/t5411/test-0033-report-with-options--porcelain.sh
Normal file
265
t/t5411/test-0033-report-with-options--porcelain.sh
Normal file
@ -0,0 +1,265 @@
|
||||
test_expect_success "setup proc-receive hook (option without matching ok, $PROTOCOL/porcelain)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "option refname refs/pull/123/head" \
|
||||
-r "option old-oid $B"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: report option without matching ok ($PROTOCOL/porcelain)" '
|
||||
test_must_fail git -C workbench push --porcelain origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/pull/123/head
|
||||
remote: proc-receive> option old-oid <COMMIT-B>
|
||||
remote: error: proc-receive reported "option" without a matching "ok/ng" directive
|
||||
To <URL/of/upstream.git>
|
||||
! HEAD:refs/for/master/topic [remote rejected] (proc-receive failed to report status)
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (option refname, $PROTOCOL/porcelain)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/pull/123/head"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: report option refname ($PROTOCOL/porcelain)" '
|
||||
git -C workbench push --porcelain origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/pull/123/head
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/pull/123/head
|
||||
To <URL/of/upstream.git>
|
||||
* HEAD:refs/pull/123/head [new reference]
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (option refname and forced-update, $PROTOCOL/porcelain)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/pull/123/head" \
|
||||
-r "option forced-update"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: report option refname and forced-update ($PROTOCOL/porcelain)" '
|
||||
git -C workbench push --porcelain origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/pull/123/head
|
||||
remote: proc-receive> option forced-update
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/pull/123/head
|
||||
To <URL/of/upstream.git>
|
||||
* HEAD:refs/pull/123/head [new reference]
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (option refname and old-oid, $PROTOCOL/porcelain)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/pull/123/head" \
|
||||
-r "option old-oid $B"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: report option refname and old-oid ($PROTOCOL/porcelain)" '
|
||||
git -C workbench push --porcelain origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/pull/123/head
|
||||
remote: proc-receive> option old-oid <COMMIT-B>
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/pull/123/head
|
||||
To <URL/of/upstream.git>
|
||||
HEAD:refs/pull/123/head <OID-B>..<OID-A>
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (option old-oid, $PROTOCOL/porcelain)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option old-oid $B"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: report option old-oid ($PROTOCOL/porcelain)" '
|
||||
git -C workbench push --porcelain origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option old-oid <COMMIT-B>
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/for/master/topic
|
||||
To <URL/of/upstream.git>
|
||||
HEAD:refs/for/master/topic <OID-B>..<OID-A>
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (option old-oid and new-oid, $PROTOCOL/porcelain)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option old-oid $A" \
|
||||
-r "option new-oid $B"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: report option old-oid and new-oid ($PROTOCOL/porcelain)" '
|
||||
git -C workbench push --porcelain origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option old-oid <COMMIT-A>
|
||||
remote: proc-receive> option new-oid <COMMIT-B>
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic
|
||||
To <URL/of/upstream.git>
|
||||
HEAD:refs/for/master/topic <OID-A>..<OID-B>
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (report with multiple rewrites, $PROTOCOL/porcelain)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/a/b/c/topic" \
|
||||
-r "ok refs/for/next/topic" \
|
||||
-r "option refname refs/pull/123/head" \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/pull/124/head" \
|
||||
-r "option old-oid $B" \
|
||||
-r "option forced-update" \
|
||||
-r "option new-oid $A"
|
||||
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/next/topic(A) refs/for/a/b/c/topic(A) refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: report with multiple rewrites ($PROTOCOL/porcelain)" '
|
||||
git -C workbench push --porcelain origin \
|
||||
HEAD:refs/for/next/topic \
|
||||
HEAD:refs/for/a/b/c/topic \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/for/a/b/c/topic
|
||||
remote: proc-receive> ok refs/for/next/topic
|
||||
remote: proc-receive> option refname refs/pull/123/head
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/pull/124/head
|
||||
remote: proc-receive> option old-oid <COMMIT-B>
|
||||
remote: proc-receive> option forced-update
|
||||
remote: proc-receive> option new-oid <COMMIT-A>
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/pull/123/head
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/a/b/c/topic
|
||||
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/pull/124/head
|
||||
To <URL/of/upstream.git>
|
||||
* HEAD:refs/pull/123/head [new reference]
|
||||
* HEAD:refs/for/a/b/c/topic [new reference]
|
||||
+ HEAD:refs/pull/124/head <OID-B>...<OID-A> (forced update)
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
44
t/t5411/test-0034-report-ft.sh
Normal file
44
t/t5411/test-0034-report-ft.sh
Normal file
@ -0,0 +1,44 @@
|
||||
test_expect_success "setup proc-receive hook (ft, $PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option fall-through"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/master/topic(B)
|
||||
test_expect_success "proc-receive: fall throught, let receive-pack to execute ($PROTOCOL)" '
|
||||
git -C workbench push origin \
|
||||
$B:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-B> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-B> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option fall-through
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-B> refs/for/master/topic
|
||||
To <URL/of/upstream.git>
|
||||
* [new reference] <COMMIT-B> -> refs/for/master/topic
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-B> refs/for/master/topic
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A) refs/for/master/topic(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
test_expect_success "cleanup ($PROTOCOL)" '
|
||||
git -C "$upstream" update-ref -d refs/for/master/topic
|
||||
'
|
45
t/t5411/test-0035-report-ft--porcelain.sh
Normal file
45
t/t5411/test-0035-report-ft--porcelain.sh
Normal file
@ -0,0 +1,45 @@
|
||||
test_expect_success "setup proc-receive hook (fall-through, $PROTOCOL/porcelain)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option fall-through"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/master/topic(B)
|
||||
test_expect_success "proc-receive: fall throught, let receive-pack to execute ($PROTOCOL/porcelain)" '
|
||||
git -C workbench push --porcelain origin \
|
||||
$B:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-B> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-B> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option fall-through
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-B> refs/for/master/topic
|
||||
To <URL/of/upstream.git>
|
||||
* <COMMIT-B>:refs/for/master/topic [new reference]
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-B> refs/for/master/topic
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A) refs/for/master/topic(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
test_expect_success "cleanup ($PROTOCOL/porcelain)" '
|
||||
git -C "$upstream" update-ref -d refs/for/master/topic
|
||||
'
|
227
t/t5411/test-0036-report-multi-rewrite-for-one-ref.sh
Normal file
227
t/t5411/test-0036-report-multi-rewrite-for-one-ref.sh
Normal file
@ -0,0 +1,227 @@
|
||||
test_expect_success "setup git config for remote-tracking of special refs" '
|
||||
(
|
||||
cd workbench &&
|
||||
if ! git config --get-all remote.origin.fetch | grep refs/for/
|
||||
then
|
||||
git config --add remote.origin.fetch \
|
||||
"+refs/for/*:refs/t/for/*" &&
|
||||
git config --add remote.origin.fetch \
|
||||
"+refs/pull/*:refs/t/pull/*" &&
|
||||
git config --add remote.origin.fetch \
|
||||
"+refs/changes/*:refs/t/changes/*"
|
||||
fi
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (multiple rewrites for one ref, no refname for the 1st rewrite, $PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option old-oid $A" \
|
||||
-r "option new-oid $B" \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/changes/24/124/1" \
|
||||
-r "option old-oid $ZERO_OID" \
|
||||
-r "option new-oid $A" \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/changes/25/125/1" \
|
||||
-r "option old-oid $A" \
|
||||
-r "option new-oid $B"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: multiple rewrite for one ref, no refname for the 1st rewrite ($PROTOCOL)" '
|
||||
git -C workbench push origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option old-oid <COMMIT-A>
|
||||
remote: proc-receive> option new-oid <COMMIT-B>
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/changes/24/124/1
|
||||
remote: proc-receive> option old-oid <ZERO-OID>
|
||||
remote: proc-receive> option new-oid <COMMIT-A>
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/changes/25/125/1
|
||||
remote: proc-receive> option old-oid <COMMIT-A>
|
||||
remote: proc-receive> option new-oid <COMMIT-B>
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/changes/24/124/1
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/changes/25/125/1
|
||||
To <URL/of/upstream.git>
|
||||
<OID-A>..<OID-B> HEAD -> refs/for/master/topic
|
||||
* [new reference] HEAD -> refs/changes/24/124/1
|
||||
<OID-A>..<OID-B> HEAD -> refs/changes/25/125/1
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "proc-receive: check remote-tracking #1 ($PROTOCOL)" '
|
||||
git -C workbench show-ref |
|
||||
grep -v -e refs/remotes -e refs/heads -e refs/tags >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/t/changes/24/124/1
|
||||
<COMMIT-B> refs/t/changes/25/125/1
|
||||
<COMMIT-B> refs/t/for/master/topic
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C workbench update-ref -d refs/t/for/master/topic &&
|
||||
git -C workbench update-ref -d refs/t/changes/24/124/1 &&
|
||||
git -C workbench update-ref -d refs/t/changes/25/125/1
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (multiple rewrites for one ref, no refname for the 2nd rewrite, $PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/changes/24/124/1" \
|
||||
-r "option old-oid $ZERO_OID" \
|
||||
-r "option new-oid $A" \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option old-oid $A" \
|
||||
-r "option new-oid $B" \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/changes/25/125/1" \
|
||||
-r "option old-oid $B" \
|
||||
-r "option new-oid $A" \
|
||||
-r "option forced-update"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: multiple rewrites for one ref, no refname for the 2nd rewrite ($PROTOCOL)" '
|
||||
git -C workbench push origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/changes/24/124/1
|
||||
remote: proc-receive> option old-oid <ZERO-OID>
|
||||
remote: proc-receive> option new-oid <COMMIT-A>
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option old-oid <COMMIT-A>
|
||||
remote: proc-receive> option new-oid <COMMIT-B>
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/changes/25/125/1
|
||||
remote: proc-receive> option old-oid <COMMIT-B>
|
||||
remote: proc-receive> option new-oid <COMMIT-A>
|
||||
remote: proc-receive> option forced-update
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/changes/24/124/1
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic
|
||||
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/changes/25/125/1
|
||||
To <URL/of/upstream.git>
|
||||
* [new reference] HEAD -> refs/changes/24/124/1
|
||||
<OID-A>..<OID-B> HEAD -> refs/for/master/topic
|
||||
+ <OID-B>...<OID-A> HEAD -> refs/changes/25/125/1 (forced update)
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "proc-receive: check remote-tracking #2 ($PROTOCOL)" '
|
||||
git -C workbench show-ref |
|
||||
grep -v -e refs/remotes -e refs/heads -e refs/tags >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/t/changes/24/124/1
|
||||
<COMMIT-A> refs/t/changes/25/125/1
|
||||
<COMMIT-B> refs/t/for/master/topic
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C workbench update-ref -d refs/t/for/master/topic &&
|
||||
git -C workbench update-ref -d refs/t/changes/24/124/1 &&
|
||||
git -C workbench update-ref -d refs/t/changes/25/125/1
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (multiple rewrites for one ref, $PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/changes/23/123/1" \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/changes/24/124/2" \
|
||||
-r "option old-oid $A" \
|
||||
-r "option new-oid $B"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: multiple rewrites for one ref ($PROTOCOL)" '
|
||||
git -C workbench push origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/changes/23/123/1
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/changes/24/124/2
|
||||
remote: proc-receive> option old-oid <COMMIT-A>
|
||||
remote: proc-receive> option new-oid <COMMIT-B>
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/changes/23/123/1
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/changes/24/124/2
|
||||
To <URL/of/upstream.git>
|
||||
* [new reference] HEAD -> refs/changes/23/123/1
|
||||
<OID-A>..<OID-B> HEAD -> refs/changes/24/124/2
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "proc-receive: check remote-tracking #3 ($PROTOCOL)" '
|
||||
git -C workbench show-ref |
|
||||
grep -v -e refs/remotes -e refs/heads -e refs/tags >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/t/changes/23/123/1
|
||||
<COMMIT-B> refs/t/changes/24/124/2
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C workbench update-ref -d refs/t/changes/24/124/1 &&
|
||||
git -C workbench update-ref -d refs/t/changes/25/125/2
|
||||
'
|
172
t/t5411/test-0037-report-multi-rewrite-for-one-ref--porcelain.sh
Normal file
172
t/t5411/test-0037-report-multi-rewrite-for-one-ref--porcelain.sh
Normal file
@ -0,0 +1,172 @@
|
||||
test_expect_success "setup proc-receive hook (multiple rewrites for one ref, no refname for the 1st rewrite, $PROTOCOL/porcelain)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option old-oid $A" \
|
||||
-r "option new-oid $B" \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/changes/24/124/1" \
|
||||
-r "option old-oid $ZERO_OID" \
|
||||
-r "option new-oid $A" \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/changes/25/125/1" \
|
||||
-r "option old-oid $A" \
|
||||
-r "option new-oid $B"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: multiple rewrite for one ref, no refname for the 1st rewrite ($PROTOCOL/porcelain)" '
|
||||
git -C workbench push --porcelain origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option old-oid <COMMIT-A>
|
||||
remote: proc-receive> option new-oid <COMMIT-B>
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/changes/24/124/1
|
||||
remote: proc-receive> option old-oid <ZERO-OID>
|
||||
remote: proc-receive> option new-oid <COMMIT-A>
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/changes/25/125/1
|
||||
remote: proc-receive> option old-oid <COMMIT-A>
|
||||
remote: proc-receive> option new-oid <COMMIT-B>
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/changes/24/124/1
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/changes/25/125/1
|
||||
To <URL/of/upstream.git>
|
||||
HEAD:refs/for/master/topic <OID-A>..<OID-B>
|
||||
* HEAD:refs/changes/24/124/1 [new reference]
|
||||
HEAD:refs/changes/25/125/1 <OID-A>..<OID-B>
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (multiple rewrites for one ref, no refname for the 2nd rewrite, $PROTOCOL/porcelain)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/changes/24/124/1" \
|
||||
-r "option old-oid $ZERO_OID" \
|
||||
-r "option new-oid $A" \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option old-oid $A" \
|
||||
-r "option new-oid $B" \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/changes/25/125/1" \
|
||||
-r "option old-oid $B" \
|
||||
-r "option new-oid $A" \
|
||||
-r "option forced-update"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: multiple rewrites for one ref, no refname for the 2nd rewrite ($PROTOCOL/porcelain)" '
|
||||
git -C workbench push --porcelain origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/changes/24/124/1
|
||||
remote: proc-receive> option old-oid <ZERO-OID>
|
||||
remote: proc-receive> option new-oid <COMMIT-A>
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option old-oid <COMMIT-A>
|
||||
remote: proc-receive> option new-oid <COMMIT-B>
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/changes/25/125/1
|
||||
remote: proc-receive> option old-oid <COMMIT-B>
|
||||
remote: proc-receive> option new-oid <COMMIT-A>
|
||||
remote: proc-receive> option forced-update
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/changes/24/124/1
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic
|
||||
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/changes/25/125/1
|
||||
To <URL/of/upstream.git>
|
||||
* HEAD:refs/changes/24/124/1 [new reference]
|
||||
HEAD:refs/for/master/topic <OID-A>..<OID-B>
|
||||
+ HEAD:refs/changes/25/125/1 <OID-B>...<OID-A> (forced update)
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook (multiple rewrites for one ref, $PROTOCOL/porcelain)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/changes/23/123/1" \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/changes/24/124/2" \
|
||||
-r "option old-oid $A" \
|
||||
-r "option new-oid $B"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: multiple rewrites for one ref ($PROTOCOL/porcelain)" '
|
||||
git -C workbench push --porcelain origin \
|
||||
HEAD:refs/for/master/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/changes/23/123/1
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/changes/24/124/2
|
||||
remote: proc-receive> option old-oid <COMMIT-A>
|
||||
remote: proc-receive> option new-oid <COMMIT-B>
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/changes/23/123/1
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/changes/24/124/2
|
||||
To <URL/of/upstream.git>
|
||||
* HEAD:refs/changes/23/123/1 [new reference]
|
||||
HEAD:refs/changes/24/124/2 <OID-A>..<OID-B>
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
89
t/t5411/test-0038-report-mixed-refs.sh
Normal file
89
t/t5411/test-0038-report-mixed-refs.sh
Normal file
@ -0,0 +1,89 @@
|
||||
test_expect_success "setup proc-receive hook ($PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/next/topic2" \
|
||||
-r "ng refs/for/next/topic1 fail to call Web API" \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/for/master/topic" \
|
||||
-r "option old-oid $A" \
|
||||
-r "option new-oid $B"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : (B) bar(A) baz(A) refs/for/next/topic(A) foo(A) refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: report update of mixed refs ($PROTOCOL)" '
|
||||
test_must_fail git -C workbench push origin \
|
||||
$B:refs/heads/master \
|
||||
HEAD:refs/heads/bar \
|
||||
HEAD:refs/heads/baz \
|
||||
HEAD:refs/for/next/topic2 \
|
||||
HEAD:refs/for/next/topic1 \
|
||||
HEAD:refs/heads/foo \
|
||||
HEAD:refs/for/master/topic \
|
||||
HEAD:refs/for/next/topic3 \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/bar
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/baz
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic2
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic1
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/foo
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic3
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic2
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic1
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic3
|
||||
remote: proc-receive> ok refs/for/next/topic2
|
||||
remote: proc-receive> ng refs/for/next/topic1 fail to call Web API
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/for/master/topic
|
||||
remote: proc-receive> option old-oid <COMMIT-A>
|
||||
remote: proc-receive> option new-oid <COMMIT-B>
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/bar
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/baz
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic2
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/foo
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic
|
||||
To <URL/of/upstream.git>
|
||||
<OID-A>..<OID-B> <COMMIT-B> -> master
|
||||
* [new branch] HEAD -> bar
|
||||
* [new branch] HEAD -> baz
|
||||
* [new reference] HEAD -> refs/for/next/topic2
|
||||
* [new branch] HEAD -> foo
|
||||
<OID-A>..<OID-B> HEAD -> refs/for/master/topic
|
||||
! [remote rejected] HEAD -> refs/for/next/topic1 (fail to call Web API)
|
||||
! [remote rejected] HEAD -> refs/for/next/topic3 (proc-receive failed to report status)
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/bar
|
||||
<COMMIT-A> refs/heads/baz
|
||||
<COMMIT-A> refs/heads/foo
|
||||
<COMMIT-B> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Refs of upstream : master(B) foo(A) bar(A)) baz(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
test_expect_success "cleanup ($PROTOCOL)" '
|
||||
(
|
||||
cd "$upstream" &&
|
||||
git update-ref refs/heads/master $A &&
|
||||
git update-ref -d refs/heads/foo &&
|
||||
git update-ref -d refs/heads/bar &&
|
||||
git update-ref -d refs/heads/baz
|
||||
)
|
||||
'
|
91
t/t5411/test-0039-report-mixed-refs--porcelain.sh
Normal file
91
t/t5411/test-0039-report-mixed-refs--porcelain.sh
Normal file
@ -0,0 +1,91 @@
|
||||
test_expect_success "setup proc-receive hook ($PROTOCOL/porcelain)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/for/next/topic2" \
|
||||
-r "ng refs/for/next/topic1 fail to call Web API" \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/for/master/topic" \
|
||||
-r "option old-oid $A" \
|
||||
-r "option new-oid $B"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push : (B) bar(A) baz(A) refs/for/next/topic(A) foo(A) refs/for/master/topic(A)
|
||||
test_expect_success "proc-receive: report update of mixed refs ($PROTOCOL/porcelain)" '
|
||||
test_must_fail git -C workbench push --porcelain origin \
|
||||
$B:refs/heads/master \
|
||||
HEAD:refs/heads/bar \
|
||||
HEAD:refs/heads/baz \
|
||||
HEAD:refs/for/next/topic2 \
|
||||
HEAD:refs/for/next/topic1 \
|
||||
HEAD:refs/heads/foo \
|
||||
HEAD:refs/for/master/topic \
|
||||
HEAD:refs/for/next/topic3 \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/bar
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/baz
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic2
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic1
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/heads/foo
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic3
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic2
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic1
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic3
|
||||
remote: proc-receive> ok refs/for/next/topic2
|
||||
remote: proc-receive> ng refs/for/next/topic1 fail to call Web API
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/for/master/topic
|
||||
remote: proc-receive> option old-oid <COMMIT-A>
|
||||
remote: proc-receive> option new-oid <COMMIT-B>
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/master
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/bar
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/baz
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic2
|
||||
remote: post-receive< <ZERO-OID> <COMMIT-A> refs/heads/foo
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/for/master/topic
|
||||
To <URL/of/upstream.git>
|
||||
<COMMIT-B>:refs/heads/master <OID-A>..<OID-B>
|
||||
* HEAD:refs/heads/bar [new branch]
|
||||
* HEAD:refs/heads/baz [new branch]
|
||||
* HEAD:refs/for/next/topic2 [new reference]
|
||||
* HEAD:refs/heads/foo [new branch]
|
||||
HEAD:refs/for/master/topic <OID-A>..<OID-B>
|
||||
! HEAD:refs/for/next/topic1 [remote rejected] (fail to call Web API)
|
||||
! HEAD:refs/for/next/topic3 [remote rejected] (proc-receive failed to report status)
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-A> refs/heads/bar
|
||||
<COMMIT-A> refs/heads/baz
|
||||
<COMMIT-A> refs/heads/foo
|
||||
<COMMIT-B> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Refs of upstream : master(B) foo(A) bar(A)) baz(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
test_expect_success "cleanup ($PROTOCOL/porcelain)" '
|
||||
(
|
||||
cd "$upstream" &&
|
||||
git update-ref refs/heads/master $A &&
|
||||
git update-ref -d refs/heads/foo &&
|
||||
git update-ref -d refs/heads/bar &&
|
||||
git update-ref -d refs/heads/baz
|
||||
)
|
||||
|
||||
'
|
113
t/t5411/test-0040-process-all-refs.sh
Normal file
113
t/t5411/test-0040-process-all-refs.sh
Normal file
@ -0,0 +1,113 @@
|
||||
test_expect_success "config receive.procReceiveRefs = refs ($PROTOCOL)" '
|
||||
git -C "$upstream" config --unset-all receive.procReceiveRefs &&
|
||||
git -C "$upstream" config --add receive.procReceiveRefs refs
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
test_expect_success "setup upstream branches ($PROTOCOL)" '
|
||||
(
|
||||
cd "$upstream" &&
|
||||
git update-ref refs/heads/master $B &&
|
||||
git update-ref refs/heads/foo $A &&
|
||||
git update-ref refs/heads/bar $A &&
|
||||
git update-ref refs/heads/baz $A
|
||||
)
|
||||
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook ($PROTOCOL)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/heads/master" \
|
||||
-r "option fall-through" \
|
||||
-r "ok refs/heads/foo" \
|
||||
-r "option fall-through" \
|
||||
-r "ok refs/heads/bar" \
|
||||
-r "option fall-through" \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/pull/123/head" \
|
||||
-r "option old-oid $A" \
|
||||
-r "option new-oid $B" \
|
||||
-r "ok refs/for/next/topic" \
|
||||
-r "option refname refs/pull/124/head" \
|
||||
-r "option old-oid $B" \
|
||||
-r "option new-oid $A" \
|
||||
-r "option forced-update"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(B) foo(A) bar(A)) baz(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push -f : master(A) (NULL) (B) refs/for/master/topic(A) refs/for/next/topic(A)
|
||||
test_expect_success "proc-receive: process all refs ($PROTOCOL)" '
|
||||
git -C workbench push -f origin \
|
||||
HEAD:refs/heads/master \
|
||||
:refs/heads/foo \
|
||||
$B:refs/heads/bar \
|
||||
HEAD:refs/for/master/topic \
|
||||
HEAD:refs/for/next/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/bar
|
||||
remote: pre-receive< <COMMIT-A> <ZERO-OID> refs/heads/foo
|
||||
remote: pre-receive< <COMMIT-B> <COMMIT-A> refs/heads/master
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <COMMIT-A> <COMMIT-B> refs/heads/bar
|
||||
remote: proc-receive< <COMMIT-A> <ZERO-OID> refs/heads/foo
|
||||
remote: proc-receive< <COMMIT-B> <COMMIT-A> refs/heads/master
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
|
||||
remote: proc-receive> ok refs/heads/master
|
||||
remote: proc-receive> option fall-through
|
||||
remote: proc-receive> ok refs/heads/foo
|
||||
remote: proc-receive> option fall-through
|
||||
remote: proc-receive> ok refs/heads/bar
|
||||
remote: proc-receive> option fall-through
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/pull/123/head
|
||||
remote: proc-receive> option old-oid <COMMIT-A>
|
||||
remote: proc-receive> option new-oid <COMMIT-B>
|
||||
remote: proc-receive> ok refs/for/next/topic
|
||||
remote: proc-receive> option refname refs/pull/124/head
|
||||
remote: proc-receive> option old-oid <COMMIT-B>
|
||||
remote: proc-receive> option new-oid <COMMIT-A>
|
||||
remote: proc-receive> option forced-update
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/bar
|
||||
remote: post-receive< <COMMIT-A> <ZERO-OID> refs/heads/foo
|
||||
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/heads/master
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/pull/123/head
|
||||
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/pull/124/head
|
||||
To <URL/of/upstream.git>
|
||||
<OID-A>..<OID-B> <COMMIT-B> -> bar
|
||||
- [deleted] foo
|
||||
+ <OID-B>...<OID-A> HEAD -> master (forced update)
|
||||
<OID-A>..<OID-B> HEAD -> refs/pull/123/head
|
||||
+ <OID-B>...<OID-A> HEAD -> refs/pull/124/head (forced update)
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-B> refs/heads/bar
|
||||
<COMMIT-A> refs/heads/baz
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A) bar(A) baz(B)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
test_expect_success "cleanup ($PROTOCOL)" '
|
||||
(
|
||||
cd "$upstream" &&
|
||||
git update-ref -d refs/heads/bar &&
|
||||
git update-ref -d refs/heads/baz
|
||||
)
|
||||
'
|
114
t/t5411/test-0041-process-all-refs--porcelain.sh
Normal file
114
t/t5411/test-0041-process-all-refs--porcelain.sh
Normal file
@ -0,0 +1,114 @@
|
||||
test_expect_success "config receive.procReceiveRefs = refs ($PROTOCOL/porcelain)" '
|
||||
git -C "$upstream" config --unset-all receive.procReceiveRefs &&
|
||||
git -C "$upstream" config --add receive.procReceiveRefs refs
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
test_expect_success "setup upstream branches ($PROTOCOL/porcelain)" '
|
||||
(
|
||||
cd "$upstream" &&
|
||||
git update-ref refs/heads/master $B &&
|
||||
git update-ref refs/heads/foo $A &&
|
||||
git update-ref refs/heads/bar $A &&
|
||||
git update-ref refs/heads/baz $A
|
||||
)
|
||||
|
||||
'
|
||||
|
||||
test_expect_success "setup proc-receive hook ($PROTOCOL/porcelain)" '
|
||||
write_script "$upstream/hooks/proc-receive" <<-EOF
|
||||
printf >&2 "# proc-receive hook\n"
|
||||
test-tool proc-receive -v \
|
||||
-r "ok refs/heads/master" \
|
||||
-r "option fall-through" \
|
||||
-r "ok refs/heads/foo" \
|
||||
-r "option fall-through" \
|
||||
-r "ok refs/heads/bar" \
|
||||
-r "option fall-through" \
|
||||
-r "ok refs/for/master/topic" \
|
||||
-r "option refname refs/pull/123/head" \
|
||||
-r "option old-oid $A" \
|
||||
-r "option new-oid $B" \
|
||||
-r "ok refs/for/next/topic" \
|
||||
-r "option refname refs/pull/124/head" \
|
||||
-r "option old-oid $B" \
|
||||
-r "option new-oid $A" \
|
||||
-r "option forced-update"
|
||||
EOF
|
||||
'
|
||||
|
||||
# Refs of upstream : master(B) foo(A) bar(A)) baz(A)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
# git push -f : master(A) (NULL) (B) refs/for/master/topic(A) refs/for/next/topic(A)
|
||||
test_expect_success "proc-receive: process all refs ($PROTOCOL/porcelain)" '
|
||||
git -C workbench push --porcelain -f origin \
|
||||
HEAD:refs/heads/master \
|
||||
:refs/heads/foo \
|
||||
$B:refs/heads/bar \
|
||||
HEAD:refs/for/master/topic \
|
||||
HEAD:refs/for/next/topic \
|
||||
>out 2>&1 &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
remote: # pre-receive hook
|
||||
remote: pre-receive< <COMMIT-A> <COMMIT-B> refs/heads/bar
|
||||
remote: pre-receive< <COMMIT-A> <ZERO-OID> refs/heads/foo
|
||||
remote: pre-receive< <COMMIT-B> <COMMIT-A> refs/heads/master
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: pre-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
|
||||
remote: # proc-receive hook
|
||||
remote: proc-receive< <COMMIT-A> <COMMIT-B> refs/heads/bar
|
||||
remote: proc-receive< <COMMIT-A> <ZERO-OID> refs/heads/foo
|
||||
remote: proc-receive< <COMMIT-B> <COMMIT-A> refs/heads/master
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/master/topic
|
||||
remote: proc-receive< <ZERO-OID> <COMMIT-A> refs/for/next/topic
|
||||
remote: proc-receive> ok refs/heads/master
|
||||
remote: proc-receive> option fall-through
|
||||
remote: proc-receive> ok refs/heads/foo
|
||||
remote: proc-receive> option fall-through
|
||||
remote: proc-receive> ok refs/heads/bar
|
||||
remote: proc-receive> option fall-through
|
||||
remote: proc-receive> ok refs/for/master/topic
|
||||
remote: proc-receive> option refname refs/pull/123/head
|
||||
remote: proc-receive> option old-oid <COMMIT-A>
|
||||
remote: proc-receive> option new-oid <COMMIT-B>
|
||||
remote: proc-receive> ok refs/for/next/topic
|
||||
remote: proc-receive> option refname refs/pull/124/head
|
||||
remote: proc-receive> option old-oid <COMMIT-B>
|
||||
remote: proc-receive> option new-oid <COMMIT-A>
|
||||
remote: proc-receive> option forced-update
|
||||
remote: # post-receive hook
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/heads/bar
|
||||
remote: post-receive< <COMMIT-A> <ZERO-OID> refs/heads/foo
|
||||
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/heads/master
|
||||
remote: post-receive< <COMMIT-A> <COMMIT-B> refs/pull/123/head
|
||||
remote: post-receive< <COMMIT-B> <COMMIT-A> refs/pull/124/head
|
||||
To <URL/of/upstream.git>
|
||||
<COMMIT-B>:refs/heads/bar <OID-A>..<OID-B>
|
||||
- :refs/heads/foo [deleted]
|
||||
+ HEAD:refs/heads/master <OID-B>...<OID-A> (forced update)
|
||||
HEAD:refs/pull/123/head <OID-A>..<OID-B>
|
||||
+ HEAD:refs/pull/124/head <OID-B>...<OID-A> (forced update)
|
||||
Done
|
||||
EOF
|
||||
test_cmp expect actual &&
|
||||
git -C "$upstream" show-ref >out &&
|
||||
make_user_friendly_and_stable_output <out >actual &&
|
||||
cat >expect <<-EOF &&
|
||||
<COMMIT-B> refs/heads/bar
|
||||
<COMMIT-A> refs/heads/baz
|
||||
<COMMIT-A> refs/heads/master
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
# Refs of upstream : master(A) bar(A) baz(B)
|
||||
# Refs of workbench: master(A) tags/v123
|
||||
test_expect_success "cleanup ($PROTOCOL/porcelain)" '
|
||||
(
|
||||
cd "$upstream" &&
|
||||
git update-ref -d refs/heads/bar &&
|
||||
git update-ref -d refs/heads/baz
|
||||
)
|
||||
'
|
@ -1039,7 +1039,7 @@ test_force_fetch_tag "annotated tag" "-f -a -m'tag message'"
|
||||
test_expect_success 'push --porcelain' '
|
||||
mk_empty testrepo &&
|
||||
echo >.git/foo "To testrepo" &&
|
||||
echo >>.git/foo "* refs/heads/master:refs/remotes/origin/master [new branch]" &&
|
||||
echo >>.git/foo "* refs/heads/master:refs/remotes/origin/master [new reference]" &&
|
||||
echo >>.git/foo "Done" &&
|
||||
git push >.git/bar --porcelain testrepo refs/heads/master:refs/remotes/origin/master &&
|
||||
(
|
||||
|
@ -729,6 +729,49 @@ static int push_update_ref_status(struct strbuf *buf,
|
||||
{
|
||||
char *refname, *msg;
|
||||
int status, forced = 0;
|
||||
static struct ref *hint = NULL;
|
||||
static int new_options = 1;
|
||||
|
||||
if (starts_with(buf->buf, "option ")) {
|
||||
struct ref_push_report_options *options;
|
||||
struct object_id old_oid, new_oid;
|
||||
const char *key, *val;
|
||||
char *p;
|
||||
|
||||
if (!hint)
|
||||
die(_("'option' without a matching 'ok/error' directive"));
|
||||
options = hint->report.options;
|
||||
while (options && options->next)
|
||||
options = options->next;
|
||||
if (new_options) {
|
||||
if (!options) {
|
||||
hint->report.options = xcalloc(1, sizeof(struct ref_push_report_options));
|
||||
options = hint->report.options;
|
||||
} else {
|
||||
options->next = xcalloc(1, sizeof(struct ref_push_report_options));
|
||||
options = options->next;
|
||||
}
|
||||
new_options = 0;
|
||||
}
|
||||
assert(options);
|
||||
key = buf->buf + 7;
|
||||
p = strchr(key, ' ');
|
||||
if (p)
|
||||
*p++ = '\0';
|
||||
val = p;
|
||||
if (!strcmp(key, "refname"))
|
||||
options->ref_name = xstrdup_or_null(val);
|
||||
else if (!strcmp(key, "old-oid") && val &&
|
||||
!parse_oid_hex(val, &old_oid, &val))
|
||||
options->old_oid = oiddup(&old_oid);
|
||||
else if (!strcmp(key, "new-oid") && val &&
|
||||
!parse_oid_hex(val, &new_oid, &val))
|
||||
options->new_oid = oiddup(&new_oid);
|
||||
else if (!strcmp(key, "forced-update"))
|
||||
options->forced_update = 1;
|
||||
/* Not update remote namespace again. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (starts_with(buf->buf, "ok ")) {
|
||||
status = REF_STATUS_OK;
|
||||
@ -791,8 +834,11 @@ static int push_update_ref_status(struct strbuf *buf,
|
||||
*ref = find_ref_by_name(remote_refs, refname);
|
||||
if (!*ref) {
|
||||
warning(_("helper reported unexpected status of %s"), refname);
|
||||
hint = NULL;
|
||||
return 1;
|
||||
}
|
||||
hint = *ref;
|
||||
new_options = 1;
|
||||
|
||||
if ((*ref)->status != REF_STATUS_NONE) {
|
||||
/*
|
||||
@ -805,7 +851,12 @@ static int push_update_ref_status(struct strbuf *buf,
|
||||
|
||||
(*ref)->status = status;
|
||||
(*ref)->forced_update |= forced;
|
||||
(*ref)->remote_status = msg;
|
||||
if (msg) {
|
||||
if (status == REF_STATUS_OK)
|
||||
(*ref)->report.message = msg;
|
||||
else
|
||||
(*ref)->report.error_message = msg;
|
||||
}
|
||||
return !(status == REF_STATUS_OK);
|
||||
}
|
||||
|
||||
|
161
transport.c
161
transport.c
@ -436,37 +436,65 @@ int transport_refs_pushed(struct ref *ref)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void transport_update_tracking_ref(struct remote *remote, struct ref *ref, int verbose)
|
||||
static void update_tracking_ref(struct remote *remote, char *refname,
|
||||
struct object_id *new_oid, int deletion,
|
||||
int verbose)
|
||||
{
|
||||
struct refspec_item rs;
|
||||
|
||||
if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE)
|
||||
return;
|
||||
|
||||
rs.src = ref->name;
|
||||
rs.src = refname;
|
||||
rs.dst = NULL;
|
||||
|
||||
if (!remote_find_tracking(remote, &rs)) {
|
||||
if (verbose)
|
||||
fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst);
|
||||
if (ref->deletion) {
|
||||
if (deletion)
|
||||
delete_ref(NULL, rs.dst, NULL, 0);
|
||||
} else
|
||||
update_ref("update by push", rs.dst, &ref->new_oid,
|
||||
NULL, 0, 0);
|
||||
else
|
||||
update_ref("update by push", rs.dst, new_oid,
|
||||
NULL, 0, 0);
|
||||
free(rs.dst);
|
||||
}
|
||||
}
|
||||
|
||||
void transport_update_tracking_ref(struct remote *remote, struct ref *ref, int verbose)
|
||||
{
|
||||
char *refname;
|
||||
struct object_id *new_oid;
|
||||
struct ref_push_report_options *options;
|
||||
|
||||
if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE)
|
||||
return;
|
||||
|
||||
options = ref->report.options;
|
||||
if (!options)
|
||||
update_tracking_ref(remote, ref->name, &ref->new_oid,
|
||||
ref->deletion, verbose);
|
||||
else
|
||||
for (; options; options = options->next) {
|
||||
refname = options->ref_name ? (char *)options->ref_name : ref->name;
|
||||
new_oid = options->new_oid ? options->new_oid : &ref->new_oid;
|
||||
update_tracking_ref(remote, refname, new_oid,
|
||||
is_null_oid(new_oid), verbose);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_ref_status(char flag, const char *summary,
|
||||
struct ref *to, struct ref *from, const char *msg,
|
||||
struct ref_push_report_options *options,
|
||||
int porcelain, int summary_width)
|
||||
{
|
||||
const char *to_name;
|
||||
|
||||
if (options && options->ref_name)
|
||||
to_name = options->ref_name;
|
||||
else
|
||||
to_name = to->name;
|
||||
|
||||
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
|
||||
@ -480,9 +508,11 @@ 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);
|
||||
@ -492,24 +522,52 @@ static void print_ref_status(char flag, const char *summary,
|
||||
}
|
||||
}
|
||||
|
||||
static void print_ok_ref_status(struct ref *ref, int porcelain, int summary_width)
|
||||
static void print_ok_ref_status(struct ref *ref,
|
||||
struct ref_push_report_options *options,
|
||||
int porcelain, int summary_width)
|
||||
{
|
||||
struct object_id *old_oid;
|
||||
struct object_id *new_oid;
|
||||
const char *ref_name;
|
||||
int forced_update;
|
||||
|
||||
if (options && options->old_oid)
|
||||
old_oid = options->old_oid;
|
||||
else
|
||||
old_oid = &ref->old_oid;
|
||||
if (options && options->new_oid)
|
||||
new_oid = options->new_oid;
|
||||
else
|
||||
new_oid = &ref->new_oid;
|
||||
if (options && options->forced_update)
|
||||
forced_update = options->forced_update;
|
||||
else
|
||||
forced_update = ref->forced_update;
|
||||
if (options && options->ref_name)
|
||||
ref_name = options->ref_name;
|
||||
else
|
||||
ref_name = ref->name;
|
||||
|
||||
if (ref->deletion)
|
||||
print_ref_status('-', "[deleted]", ref, NULL, NULL,
|
||||
porcelain, summary_width);
|
||||
else if (is_null_oid(&ref->old_oid))
|
||||
options, porcelain, summary_width);
|
||||
else if (is_null_oid(old_oid))
|
||||
print_ref_status('*',
|
||||
(starts_with(ref->name, "refs/tags/") ? "[new tag]" :
|
||||
"[new branch]"),
|
||||
ref, ref->peer_ref, NULL, porcelain, summary_width);
|
||||
(starts_with(ref_name, "refs/tags/")
|
||||
? "[new tag]"
|
||||
: (starts_with(ref_name, "refs/heads/")
|
||||
? "[new branch]"
|
||||
: "[new reference]")),
|
||||
ref, ref->peer_ref, NULL,
|
||||
options, porcelain, summary_width);
|
||||
else {
|
||||
struct strbuf quickref = STRBUF_INIT;
|
||||
char type;
|
||||
const char *msg;
|
||||
|
||||
strbuf_add_unique_abbrev(&quickref, &ref->old_oid,
|
||||
strbuf_add_unique_abbrev(&quickref, old_oid,
|
||||
DEFAULT_ABBREV);
|
||||
if (ref->forced_update) {
|
||||
if (forced_update) {
|
||||
strbuf_addstr(&quickref, "...");
|
||||
type = '+';
|
||||
msg = "forced update";
|
||||
@ -518,17 +576,18 @@ static void print_ok_ref_status(struct ref *ref, int porcelain, int summary_widt
|
||||
type = ' ';
|
||||
msg = NULL;
|
||||
}
|
||||
strbuf_add_unique_abbrev(&quickref, &ref->new_oid,
|
||||
strbuf_add_unique_abbrev(&quickref, new_oid,
|
||||
DEFAULT_ABBREV);
|
||||
|
||||
print_ref_status(type, quickref.buf, ref, ref->peer_ref, msg,
|
||||
porcelain, summary_width);
|
||||
options, porcelain, summary_width);
|
||||
strbuf_release(&quickref);
|
||||
}
|
||||
}
|
||||
|
||||
static int print_one_push_status(struct ref *ref, const char *dest, int count,
|
||||
int porcelain, int summary_width)
|
||||
static int _print_one_push_status(struct ref *ref, const char *dest, int count,
|
||||
struct ref_push_report_options *options,
|
||||
int porcelain, int summary_width)
|
||||
{
|
||||
if (!count) {
|
||||
char *url = transport_anonymize_url(dest);
|
||||
@ -539,65 +598,89 @@ static int print_one_push_status(struct ref *ref, const char *dest, int count,
|
||||
switch(ref->status) {
|
||||
case REF_STATUS_NONE:
|
||||
print_ref_status('X', "[no match]", ref, NULL, NULL,
|
||||
porcelain, summary_width);
|
||||
options, porcelain, summary_width);
|
||||
break;
|
||||
case REF_STATUS_REJECT_NODELETE:
|
||||
print_ref_status('!', "[rejected]", ref, NULL,
|
||||
"remote does not support deleting refs",
|
||||
porcelain, summary_width);
|
||||
options, porcelain, summary_width);
|
||||
break;
|
||||
case REF_STATUS_UPTODATE:
|
||||
print_ref_status('=', "[up to date]", ref,
|
||||
ref->peer_ref, NULL, porcelain, summary_width);
|
||||
ref->peer_ref, NULL,
|
||||
options, porcelain, summary_width);
|
||||
break;
|
||||
case REF_STATUS_REJECT_NONFASTFORWARD:
|
||||
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
|
||||
"non-fast-forward", porcelain, summary_width);
|
||||
"non-fast-forward",
|
||||
options, porcelain, summary_width);
|
||||
break;
|
||||
case REF_STATUS_REJECT_ALREADY_EXISTS:
|
||||
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
|
||||
"already exists", porcelain, summary_width);
|
||||
"already exists",
|
||||
options, porcelain, summary_width);
|
||||
break;
|
||||
case REF_STATUS_REJECT_FETCH_FIRST:
|
||||
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
|
||||
"fetch first", porcelain, summary_width);
|
||||
"fetch first",
|
||||
options, porcelain, summary_width);
|
||||
break;
|
||||
case REF_STATUS_REJECT_NEEDS_FORCE:
|
||||
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
|
||||
"needs force", porcelain, summary_width);
|
||||
"needs force",
|
||||
options, porcelain, summary_width);
|
||||
break;
|
||||
case REF_STATUS_REJECT_STALE:
|
||||
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
|
||||
"stale info", porcelain, summary_width);
|
||||
"stale info",
|
||||
options, porcelain, summary_width);
|
||||
break;
|
||||
case REF_STATUS_REJECT_SHALLOW:
|
||||
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
|
||||
"new shallow roots not allowed",
|
||||
porcelain, summary_width);
|
||||
options, porcelain, summary_width);
|
||||
break;
|
||||
case REF_STATUS_REMOTE_REJECT:
|
||||
print_ref_status('!', "[remote rejected]", ref,
|
||||
ref->deletion ? NULL : ref->peer_ref,
|
||||
ref->remote_status, porcelain, summary_width);
|
||||
ref->report.error_message,
|
||||
options, porcelain, summary_width);
|
||||
break;
|
||||
case REF_STATUS_EXPECTING_REPORT:
|
||||
print_ref_status('!', "[remote failure]", ref,
|
||||
ref->deletion ? NULL : ref->peer_ref,
|
||||
"remote failed to report status",
|
||||
porcelain, summary_width);
|
||||
options, porcelain, summary_width);
|
||||
break;
|
||||
case REF_STATUS_ATOMIC_PUSH_FAILED:
|
||||
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
|
||||
"atomic push failed", porcelain, summary_width);
|
||||
"atomic push failed",
|
||||
options, porcelain, summary_width);
|
||||
break;
|
||||
case REF_STATUS_OK:
|
||||
print_ok_ref_status(ref, porcelain, summary_width);
|
||||
print_ok_ref_status(ref, options, porcelain, summary_width);
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int print_one_push_status(struct ref *ref, const char *dest, int count,
|
||||
int porcelain, int summary_width)
|
||||
{
|
||||
struct ref_push_report_options *options;
|
||||
int n = 0;
|
||||
|
||||
if (!ref->report.options)
|
||||
return _print_one_push_status(ref, dest, count,
|
||||
NULL, porcelain, summary_width);
|
||||
|
||||
for (options = ref->report.options; options; options = options->next)
|
||||
_print_one_push_status(ref, dest, count + n++,
|
||||
options, porcelain, summary_width);
|
||||
return n;
|
||||
}
|
||||
|
||||
static int measure_abbrev(const struct object_id *oid, int sofar)
|
||||
{
|
||||
char hex[GIT_MAX_HEXSZ + 1];
|
||||
|
Reference in New Issue
Block a user