static int transfer_unpack_limit = -1;
static int unpack_limit = 100;
static int report_status;
+static int prefer_ofs_delta = 1;
static const char *head_name;
-
-static char capabilities[] = " report-status delete-refs ";
-static int capabilities_sent;
+static char *capabilities_to_send;
static enum deny_action parse_deny_action(const char *var, const char *value)
{
return 0;
}
+ if (strcmp(var, "repack.usedeltabaseoffset") == 0) {
+ prefer_ofs_delta = git_config_bool(var, value);
+ return 0;
+ }
+
return git_default_config(var, value, cb);
}
static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
{
- if (capabilities_sent)
+ if (!capabilities_to_send)
packet_write(1, "%s %s\n", sha1_to_hex(sha1), path);
else
packet_write(1, "%s %s%c%s\n",
- sha1_to_hex(sha1), path, 0, capabilities);
- capabilities_sent = 1;
+ sha1_to_hex(sha1), path, 0, capabilities_to_send);
+ capabilities_to_send = NULL;
return 0;
}
static void write_head_info(void)
{
for_each_ref(show_ref, NULL);
- if (!capabilities_sent)
+ if (capabilities_to_send)
show_ref("capabilities^{}", null_sha1, 0, NULL);
}
static const char pre_receive_hook[] = "hooks/pre-receive";
static const char post_receive_hook[] = "hooks/post-receive";
-static int hook_status(int code, const char *hook_name)
-{
- switch (code) {
- case 0:
- return 0;
- case -ERR_RUN_COMMAND_FORK:
- return error("hook fork failed");
- case -ERR_RUN_COMMAND_EXEC:
- return error("hook execute failed");
- case -ERR_RUN_COMMAND_PIPE:
- return error("hook pipe failed");
- case -ERR_RUN_COMMAND_WAITPID:
- return error("waitpid failed");
- case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
- return error("waitpid is confused");
- case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
- return error("%s died of signal", hook_name);
- case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
- return error("%s died strangely", hook_name);
- default:
- error("%s exited with error code %d", hook_name, -code);
- return -code;
- }
-}
-
static int run_receive_hook(const char *hook_name)
{
static char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4];
code = start_command(&proc);
if (code)
- return hook_status(code, hook_name);
+ return code;
for (cmd = commands; cmd; cmd = cmd->next) {
if (!cmd->error_string) {
size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
}
}
close(proc.in);
- return hook_status(finish_command(&proc), hook_name);
+ return finish_command(&proc);
}
static int run_update_hook(struct command *cmd)
{
static const char update_hook[] = "hooks/update";
- struct child_process proc;
const char *argv[5];
if (access(update_hook, X_OK) < 0)
argv[3] = sha1_to_hex(cmd->new_sha1);
argv[4] = NULL;
- memset(&proc, 0, sizeof(proc));
- proc.argv = argv;
- proc.no_stdin = 1;
- proc.stdout_to_stderr = 1;
-
- return hook_status(run_command(&proc), update_hook);
+ return run_command_v_opt(argv, RUN_COMMAND_NO_STDIN |
+ RUN_COMMAND_STDOUT_TO_STDERR);
}
static int is_ref_checked_out(const char *ref)
static void run_update_post_hook(struct command *cmd)
{
struct command *cmd_p;
- int argc;
+ int argc, status;
const char **argv;
for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
argc++;
}
argv[argc] = NULL;
- run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
- | RUN_COMMAND_STDOUT_TO_STDERR);
+ status = run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
+ | RUN_COMMAND_STDOUT_TO_STDERR);
}
static void execute_commands(const char *unpacker_error)
unpacker[i++] = hdr_arg;
unpacker[i++] = NULL;
code = run_command_v_opt(unpacker, RUN_GIT_CMD);
- switch (code) {
- case 0:
+ if (!code)
return NULL;
- case -ERR_RUN_COMMAND_FORK:
- return "unpack fork failed";
- case -ERR_RUN_COMMAND_EXEC:
- return "unpack execute failed";
- case -ERR_RUN_COMMAND_WAITPID:
- return "waitpid failed";
- case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
- return "waitpid is confused";
- case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
- return "unpacker died of signal";
- case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
- return "unpacker died strangely";
- default:
- return "unpacker exited with error code";
- }
+ return "unpack-objects abnormal exit";
} else {
const char *keeper[7];
int s, status, i = 0;
ip.argv = keeper;
ip.out = -1;
ip.git_cmd = 1;
- if (start_command(&ip))
+ status = start_command(&ip);
+ if (status) {
return "index-pack fork failed";
+ }
pack_lockfile = index_pack_lockfile(ip.out);
close(ip.out);
status = finish_command(&ip);
setup_path();
if (!enter_repo(dir, 0))
- die("'%s': unable to chdir or not a git archive", dir);
+ die("'%s' does not appear to be a git repository", dir);
if (is_repository_shallow())
die("attempt to push into a shallow repository");
else if (0 <= receive_unpack_limit)
unpack_limit = receive_unpack_limit;
+ capabilities_to_send = (prefer_ofs_delta) ?
+ " report-status delete-refs ofs-delta " :
+ " report-status delete-refs ";
+
add_alternate_refs();
write_head_info();
clear_extra_refs();
unpack_status = unpack();
execute_commands(unpack_status);
if (pack_lockfile)
- unlink(pack_lockfile);
+ unlink_or_warn(pack_lockfile);
if (report_status)
report(unpack_status);
run_receive_hook(post_receive_hook);