From 21b138d0f64d99b55e901f90d4211e036b881e64 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 1 Dec 2014 13:57:28 -0800 Subject: [PATCH] receive-pack: refactor updateInstead codepath Keep the "there is nothing to update in a bare repository", "when the check and update process runs, here are the GIT_DIR and GIT_WORK_TREE" logic, which will be common regardless of how the decision to update and the actual update are done, in the original update_worktree() function, and split out the "working tree and the index must match the original HEAD exactly" and "use two-way read-tree to update the working tree" into a new push_to_deploy() helper function. This will allow customizing the logic more cleanly and easily. Signed-off-by: Junio C Hamano --- builtin/receive-pack.c | 107 +++++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 52 deletions(-) diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index c04741878d..11800cda2e 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -733,7 +733,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 @@ -748,67 +750,68 @@ static const char *update_worktree(unsigned char *sha1) const char *read_tree[] = { "read-tree", "-u", "-m", NULL, NULL }; + struct child_process child = CHILD_PROCESS_INIT; + + child.argv = update_refresh; + 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)) + 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.dir = work_tree; + child.no_stdin = 1; + child.stdout_to_stderr = 1; + child.git_cmd = 1; + if (run_command(&child)) + return "Working directory has unstaged changes"; + + child_process_init(&child); + child.argv = diff_index; + 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)) + 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.dir = work_tree; + child.no_stdin = 1; + child.no_stdout = 1; + child.stdout_to_stderr = 0; + child.git_cmd = 1; + if (run_command(&child)) + return "Could not update working tree to new HEAD"; + + 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; - 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.dir = work_tree; - child.no_stdin = 1; - child.stdout_to_stderr = 1; - child.git_cmd = 1; - if (run_command(&child)) { - argv_array_clear(&env); - 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.dir = work_tree; - child.no_stdin = 1; - child.stdout_to_stderr = 1; - child.git_cmd = 1; - if (run_command(&child)) { - argv_array_clear(&env); - return "Working directory has unstaged changes"; - } - - child_process_init(&child); - child.argv = diff_index; - 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); - 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.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); - return "Could not update working tree to new HEAD"; - } + retval = push_to_deploy(sha1, &env, work_tree); argv_array_clear(&env); - return NULL; + return retval; } static const char *update(struct command *cmd, struct shallow_info *si)