aboutsummaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/receive-pack.c70
1 files changed, 45 insertions, 25 deletions
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 4e85e25d0..e0ce78e5a 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -743,7 +743,9 @@ static int update_shallow_ref(struct command *cmd, struct shallow_info *si)
return 0;
}
-static const char *update_worktree(unsigned char *sha1)
+static const char *push_to_deploy(unsigned char *sha1,
+ struct argv_array *env,
+ const char *work_tree)
{
const char *update_refresh[] = {
"update-index", "-q", "--ignore-submodules", "--refresh", NULL
@@ -758,69 +760,87 @@ static const char *update_worktree(unsigned char *sha1)
const char *read_tree[] = {
"read-tree", "-u", "-m", NULL, NULL
};
- const char *work_tree = git_work_tree_cfg ? git_work_tree_cfg : "..";
- struct argv_array env = ARGV_ARRAY_INIT;
struct child_process child = CHILD_PROCESS_INIT;
- if (is_bare_repository())
- return "denyCurrentBranch = updateInstead needs a worktree";
-
- argv_array_pushf(&env, "GIT_DIR=%s", absolute_path(get_git_dir()));
-
child.argv = update_refresh;
- child.env = env.argv;
+ child.env = env->argv;
child.dir = work_tree;
child.no_stdin = 1;
child.stdout_to_stderr = 1;
child.git_cmd = 1;
- if (run_command(&child)) {
- argv_array_clear(&env);
+ if (run_command(&child))
return "Up-to-date check failed";
- }
/* run_command() does not clean up completely; reinitialize */
child_process_init(&child);
child.argv = diff_files;
- child.env = env.argv;
+ child.env = env->argv;
child.dir = work_tree;
child.no_stdin = 1;
child.stdout_to_stderr = 1;
child.git_cmd = 1;
- if (run_command(&child)) {
- argv_array_clear(&env);
+ if (run_command(&child))
return "Working directory has unstaged changes";
- }
child_process_init(&child);
child.argv = diff_index;
- child.env = env.argv;
+ child.env = env->argv;
child.no_stdin = 1;
child.no_stdout = 1;
child.stdout_to_stderr = 0;
child.git_cmd = 1;
- if (run_command(&child)) {
- argv_array_clear(&env);
+ if (run_command(&child))
return "Working directory has staged changes";
- }
read_tree[3] = sha1_to_hex(sha1);
child_process_init(&child);
child.argv = read_tree;
- child.env = env.argv;
+ child.env = env->argv;
child.dir = work_tree;
child.no_stdin = 1;
child.no_stdout = 1;
child.stdout_to_stderr = 0;
child.git_cmd = 1;
- if (run_command(&child)) {
- argv_array_clear(&env);
+ if (run_command(&child))
return "Could not update working tree to new HEAD";
- }
- argv_array_clear(&env);
return NULL;
}
+static const char *push_to_checkout_hook = "push-to-checkout";
+
+static const char *push_to_checkout(unsigned char *sha1,
+ struct argv_array *env,
+ const char *work_tree)
+{
+ argv_array_pushf(env, "GIT_WORK_TREE=%s", absolute_path(work_tree));
+ if (run_hook_le(env->argv, push_to_checkout_hook,
+ sha1_to_hex(sha1), NULL))
+ return "push-to-checkout hook declined";
+ else
+ return NULL;
+}
+
+static const char *update_worktree(unsigned char *sha1)
+{
+ const char *retval;
+ const char *work_tree = git_work_tree_cfg ? git_work_tree_cfg : "..";
+ struct argv_array env = ARGV_ARRAY_INIT;
+
+ if (is_bare_repository())
+ return "denyCurrentBranch = updateInstead needs a worktree";
+
+ argv_array_pushf(&env, "GIT_DIR=%s", absolute_path(get_git_dir()));
+
+ if (!find_hook(push_to_checkout_hook))
+ retval = push_to_deploy(sha1, &env, work_tree);
+ else
+ retval = push_to_checkout(sha1, &env, work_tree);
+
+ argv_array_clear(&env);
+ return retval;
+}
+
static const char *update(struct command *cmd, struct shallow_info *si)
{
const char *name = cmd->ref_name;