summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: c8dd277)
raw | patch | inline | side by side (parent: c8dd277)
author | Shawn O. Pearce <spearce@spearce.org> | |
Wed, 7 Mar 2007 21:51:59 +0000 (16:51 -0500) | ||
committer | Junio C Hamano <junkio@cox.net> | |
Wed, 7 Mar 2007 22:47:09 +0000 (14:47 -0800) |
I discovered we did not send an ng line in the report-status feedback
if the ref was not updated because the repository has the config
option receive.denyNonFastForwards enabled. I think the reason this
happened is that it is simply too easy to forget to set error_string
when returning back a failure from update()
We now return an ng line for a non-fastforward update, which in
turn will cause send-pack to exit with a non-zero exit status.
Hence the modified test.
This refactoring changes update to return a const char* describing
the error, which execute_commands always loads into error_string.
The result is what I think is cleaner code, and allows us to
initialize the error_string member to NULL when we read_head_info.
I want error_string to be NULL in all commands before we call
execute_commands, so that we can reuse the run_hook function to
execute a new pre-receive hook.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
if the ref was not updated because the repository has the config
option receive.denyNonFastForwards enabled. I think the reason this
happened is that it is simply too easy to forget to set error_string
when returning back a failure from update()
We now return an ng line for a non-fastforward update, which in
turn will cause send-pack to exit with a non-zero exit status.
Hence the modified test.
This refactoring changes update to return a const char* describing
the error, which execute_commands always loads into error_string.
The result is what I think is cleaner code, and allows us to
initialize the error_string member to NULL when we read_head_info.
I want error_string to be NULL in all commands before we call
execute_commands, so that we can reuse the run_hook function to
execute a new pre-receive hook.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
receive-pack.c | patch | blob | history | |
t/t5400-send-pack.sh | patch | blob | history |
diff --git a/receive-pack.c b/receive-pack.c
index c55d905d5c9511c073824c8ae759704cf2da897c..ff746e7d565e6711d5afe72ec92cdbb464c53d5c 100644 (file)
--- a/receive-pack.c
+++ b/receive-pack.c
}
}
-static int update(struct command *cmd)
+static const char *update(struct command *cmd)
{
const char *name = cmd->ref_name;
unsigned char *old_sha1 = cmd->old_sha1;
unsigned char *new_sha1 = cmd->new_sha1;
struct ref_lock *lock;
- cmd->error_string = NULL;
if (!prefixcmp(name, "refs/") && check_ref_format(name + 5)) {
- cmd->error_string = "funny refname";
- return error("refusing to create funny ref '%s' locally",
- name);
+ error("refusing to create funny ref '%s' locally", name);
+ return "funny refname";
}
if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
- cmd->error_string = "bad pack";
- return error("unpack should have generated %s, "
- "but I can't find it!", sha1_to_hex(new_sha1));
+ error("unpack should have generated %s, "
+ "but I can't find it!", sha1_to_hex(new_sha1));
+ return "bad pack";
}
if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
!is_null_sha1(old_sha1) &&
if (!hashcmp(old_sha1, ent->item->object.sha1))
break;
free_commit_list(bases);
- if (!ent)
- return error("denying non-fast forward;"
- " you should pull first");
+ if (!ent) {
+ error("denying non-fast forward %s"
+ " (you should pull first)", name);
+ return "non-fast forward";
+ }
}
if (run_hook(update_hook, cmd, 1)) {
- cmd->error_string = "hook declined";
- return error("hook declined to update %s", name);
+ error("hook declined to update %s", name);
+ return "hook declined";
}
if (is_null_sha1(new_sha1)) {
if (delete_ref(name, old_sha1)) {
- cmd->error_string = "failed to delete";
- return error("failed to delete %s", name);
+ error("failed to delete %s", name);
+ return "failed to delete";
}
fprintf(stderr, "%s: %s -> deleted\n", name,
sha1_to_hex(old_sha1));
+ return NULL; /* good */
}
else {
lock = lock_any_ref_for_update(name, old_sha1);
if (!lock) {
- cmd->error_string = "failed to lock";
- return error("failed to lock %s", name);
+ error("failed to lock %s", name);
+ return "failed to lock";
}
if (write_ref_sha1(lock, new_sha1, "push")) {
- cmd->error_string = "failed to write";
- return -1; /* error() already called */
+ return "failed to write"; /* error() already called */
}
fprintf(stderr, "%s: %s -> %s\n", name,
sha1_to_hex(old_sha1), sha1_to_hex(new_sha1));
+ return NULL; /* good */
}
- return 0;
}
static char update_post_hook[] = "hooks/post-update";
| RUN_COMMAND_STDOUT_TO_STDERR);
}
-/*
- * This gets called after(if) we've successfully
- * unpacked the data payload.
- */
-static void execute_commands(void)
+static void execute_commands(const char *unpacker_error)
{
struct command *cmd = commands;
+
+ if (unpacker_error) {
+ while (cmd) {
+ cmd->error_string = "n/a (unpacker error)";
+ cmd = cmd->next;
+ }
+ return;
+ }
+
while (cmd) {
- update(cmd);
+ cmd->error_string = update(cmd);
cmd = cmd->next;
}
}
hashcpy(cmd->old_sha1, old_sha1);
hashcpy(cmd->new_sha1, new_sha1);
memcpy(cmd->ref_name, line + 82, len - 81);
- cmd->error_string = "n/a (unpacker error)";
+ cmd->error_string = NULL;
cmd->next = NULL;
*p = cmd;
p = &cmd->next;
if (!delete_only(commands))
unpack_status = unpack();
- if (!unpack_status)
- execute_commands();
+ execute_commands(unpack_status);
if (pack_lockfile)
unlink(pack_lockfile);
if (report_status)
diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh
index 7d93d0d7c90de94b0972d8fa5cd6d747c3fd2f56..b1c97b0dfb1748a7ba80c18d2d4b84bdee192c95 100755 (executable)
--- a/t/t5400-send-pack.sh
+++ b/t/t5400-send-pack.sh
cd victim &&
git-config receive.denyNonFastforwards true &&
cd .. &&
- git-update-ref refs/heads/master master^ &&
- git-send-pack --force ./victim/.git/ master &&
- ! diff -u .git/refs/heads/master victim/.git/refs/heads/master
+ git-update-ref refs/heads/master master^ || return 1
+ git-send-pack --force ./victim/.git/ master && return 1
+ ! diff .git/refs/heads/master victim/.git/refs/heads/master
'
test_done