Merge branch 'jc/plug-fmt-merge-msg-leak'
[gitweb.git] / builtin / receive-pack.c
index e0ce78e5a069670b00da6f3d67b991525c6dd29c..d2ec52bca983d9dfe1094cffe6049c902049e4d6 100644 (file)
@@ -743,6 +743,22 @@ static int update_shallow_ref(struct command *cmd, struct shallow_info *si)
        return 0;
 }
 
+/*
+ * NEEDSWORK: we should consolidate various implementions of "are we
+ * on an unborn branch?" test into one, and make the unified one more
+ * robust. !get_sha1() based check used here and elsewhere would not
+ * allow us to tell an unborn branch from corrupt ref, for example.
+ * For the purpose of fixing "deploy-to-update does not work when
+ * pushing into an empty repository" issue, this should suffice for
+ * now.
+ */
+static int head_has_history(void)
+{
+       unsigned char sha1[20];
+
+       return !get_sha1("HEAD", sha1);
+}
+
 static const char *push_to_deploy(unsigned char *sha1,
                                  struct argv_array *env,
                                  const char *work_tree)
@@ -755,7 +771,7 @@ static const char *push_to_deploy(unsigned char *sha1,
        };
        const char *diff_index[] = {
                "diff-index", "--quiet", "--cached", "--ignore-submodules",
-               "HEAD", "--", NULL
+               NULL, "--", NULL
        };
        const char *read_tree[] = {
                "read-tree", "-u", "-m", NULL, NULL
@@ -782,6 +798,9 @@ static const char *push_to_deploy(unsigned char *sha1,
        if (run_command(&child))
                return "Working directory has unstaged changes";
 
+       /* diff-index with either HEAD or an empty tree */
+       diff_index[4] = head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX;
+
        child_process_init(&child);
        child.argv = diff_index;
        child.env = env->argv;
@@ -953,8 +972,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)
                if (ref_transaction_delete(transaction,
                                           namespaced_name,
                                           old_sha1,
-                                          0, old_sha1 != NULL,
-                                          "push", &err)) {
+                                          0, "push", &err)) {
                        rp_error("%s", err.buf);
                        strbuf_release(&err);
                        return "failed to delete";
@@ -971,7 +989,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)
                if (ref_transaction_update(transaction,
                                           namespaced_name,
                                           new_sha1, old_sha1,
-                                          0, 1, "push",
+                                          0, "push",
                                           &err)) {
                        rp_error("%s", err.buf);
                        strbuf_release(&err);
@@ -990,7 +1008,7 @@ static void run_update_post_hook(struct command *commands)
        int argc;
        const char **argv;
        struct child_process proc = CHILD_PROCESS_INIT;
-       char *hook;
+       const char *hook;
 
        hook = find_hook("post-update");
        for (argc = 0, cmd = commands; cmd; cmd = cmd->next) {