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 <gitster@pobox.com>

Junio C Hamano committed Dec 1, 2014 at 13:57 UTC 21b138d0f64d99b55e901f90d4211e036b881e64
1 file changed +28 -25
builtin/receive-pack.c
+28 -25
@@ -733,7 +733,9 @@ static int update_shallow_ref(struct command *cmd, struct shallow_info *si)
733 return 0;
734 }
735
736 -static const char *update_worktree(unsigned char *sha1)
736 +static const char *push_to_deploy(unsigned char *sha1,
737 + struct argv_array *env,
738 + const char *work_tree)
739 {
740 const char *update_refresh[] = {
741 "update-index", "-q", "--ignore-submodules", "--refresh", NULL
@@ -748,69 +750,70 @@ static const char *update_worktree(unsigned char *sha1)
750 const char *read_tree[] = {
751 "read-tree", "-u", "-m", NULL, NULL
752 };
751 - const char *work_tree = git_work_tree_cfg ? git_work_tree_cfg : "..";
752 - struct argv_array env = ARGV_ARRAY_INIT;
753 struct child_process child = CHILD_PROCESS_INIT;
754
755 - if (is_bare_repository())
756 - return "denyCurrentBranch = updateInstead needs a worktree";
757 -
758 - argv_array_pushf(&env, "GIT_DIR=%s", absolute_path(get_git_dir()));
759 -
755 child.argv = update_refresh;
761 - child.env = env.argv;
756 + child.env = env->argv;
757 child.dir = work_tree;
758 child.no_stdin = 1;
759 child.stdout_to_stderr = 1;
760 child.git_cmd = 1;
766 - if (run_command(&child)) {
767 - argv_array_clear(&env);
761 + if (run_command(&child))
762 return "Up-to-date check failed";
769 - }
763
764 /* run_command() does not clean up completely; reinitialize */
765 child_process_init(&child);
766 child.argv = diff_files;
774 - child.env = env.argv;
767 + child.env = env->argv;
768 child.dir = work_tree;
769 child.no_stdin = 1;
770 child.stdout_to_stderr = 1;
771 child.git_cmd = 1;
779 - if (run_command(&child)) {
780 - argv_array_clear(&env);
772 + if (run_command(&child))
773 return "Working directory has unstaged changes";
782 - }
774
775 child_process_init(&child);
776 child.argv = diff_index;
786 - child.env = env.argv;
777 + child.env = env->argv;
778 child.no_stdin = 1;
779 child.no_stdout = 1;
780 child.stdout_to_stderr = 0;
781 child.git_cmd = 1;
791 - if (run_command(&child)) {
792 - argv_array_clear(&env);
782 + if (run_command(&child))
783 return "Working directory has staged changes";
794 - }
784
785 read_tree[3] = sha1_to_hex(sha1);
786 child_process_init(&child);
787 child.argv = read_tree;
799 - child.env = env.argv;
788 + child.env = env->argv;
789 child.dir = work_tree;
790 child.no_stdin = 1;
791 child.no_stdout = 1;
792 child.stdout_to_stderr = 0;
793 child.git_cmd = 1;
805 - if (run_command(&child)) {
806 - argv_array_clear(&env);
794 + if (run_command(&child))
795 return "Could not update working tree to new HEAD";
808 - }
796
810 - argv_array_clear(&env);
797 return NULL;
798 }
799
800 +static const char *update_worktree(unsigned char *sha1)
801 +{
802 + const char *retval;
803 + const char *work_tree = git_work_tree_cfg ? git_work_tree_cfg : "..";
804 + struct argv_array env = ARGV_ARRAY_INIT;
805 +
806 + if (is_bare_repository())
807 + return "denyCurrentBranch = updateInstead needs a worktree";
808 +
809 + argv_array_pushf(&env, "GIT_DIR=%s", absolute_path(get_git_dir()));
810 +
811 + retval = push_to_deploy(sha1, &env, work_tree);
812 +
813 + argv_array_clear(&env);
814 + return retval;
815 +}
816 +
817 static const char *update(struct command *cmd, struct shallow_info *si)
818 {
819 const char *name = cmd->ref_name;