apply: register conflicted stages to the index
[gitweb.git] / builtin / apply.c
index 24efb3f438ef16a9a42a869dcebfcfa66a6669cd..dc52c9475e5f250912b01c80a261185d0b9034b9 100644 (file)
@@ -3288,7 +3288,10 @@ static int try_threeway(struct image *image, struct patch *patch,
 
        if (status) {
                patch->conflicted_threeway = 1;
-               hashcpy(patch->threeway_stage[0], pre_sha1);
+               if (patch->is_new)
+                       hashclr(patch->threeway_stage[0]);
+               else
+                       hashcpy(patch->threeway_stage[0], pre_sha1);
                hashcpy(patch->threeway_stage[1], our_sha1);
                hashcpy(patch->threeway_stage[2], post_sha1);
                fprintf(stderr, "Applied patch to '%s' with conflicts.\n", patch->new_name);
@@ -3852,6 +3855,32 @@ static void create_one_file(char *path, unsigned mode, const char *buf, unsigned
        die_errno(_("unable to write file '%s' mode %o"), path, mode);
 }
 
+static void add_conflicted_stages_file(struct patch *patch)
+{
+       int stage, namelen;
+       unsigned ce_size, mode;
+       struct cache_entry *ce;
+
+       if (!update_index)
+               return;
+       namelen = strlen(patch->new_name);
+       ce_size = cache_entry_size(namelen);
+       mode = patch->new_mode ? patch->new_mode : (S_IFREG | 0644);
+
+       remove_file_from_cache(patch->new_name);
+       for (stage = 1; stage < 4; stage++) {
+               if (is_null_sha1(patch->threeway_stage[stage - 1]))
+                       continue;
+               ce = xcalloc(1, ce_size);
+               memcpy(ce->name, patch->new_name, namelen);
+               ce->ce_mode = create_ce_mode(mode);
+               ce->ce_flags = create_ce_flags(namelen, stage);
+               hashcpy(ce->sha1, patch->threeway_stage[stage - 1]);
+               if (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD) < 0)
+                       die(_("unable to add cache entry for %s"), patch->new_name);
+       }
+}
+
 static void create_file(struct patch *patch)
 {
        char *path = patch->new_name;
@@ -3862,7 +3891,11 @@ static void create_file(struct patch *patch)
        if (!mode)
                mode = S_IFREG | 0644;
        create_one_file(path, mode, buf, size);
-       add_index_file(path, mode, buf, size);
+
+       if (patch->conflicted_threeway)
+               add_conflicted_stages_file(patch);
+       else
+               add_index_file(path, mode, buf, size);
 }
 
 /* phase zero is to remove, phase one is to create */
@@ -3964,6 +3997,7 @@ static int write_out_results(struct patch *list)
        int phase;
        int errs = 0;
        struct patch *l;
+       struct string_list cpath = STRING_LIST_INIT_DUP;
 
        for (phase = 0; phase < 2; phase++) {
                l = list;
@@ -3972,12 +4006,28 @@ static int write_out_results(struct patch *list)
                                errs = 1;
                        else {
                                write_out_one_result(l, phase);
-                               if (phase == 1 && write_out_one_reject(l))
-                                       errs = 1;
+                               if (phase == 1) {
+                                       if (write_out_one_reject(l))
+                                               errs = 1;
+                                       if (l->conflicted_threeway) {
+                                               string_list_append(&cpath, l->new_name);
+                                               errs = 1;
+                                       }
+                               }
                        }
                        l = l->next;
                }
        }
+
+       if (cpath.nr) {
+               struct string_list_item *item;
+
+               sort_string_list(&cpath);
+               for_each_string_list_item(item, &cpath)
+                       fprintf(stderr, "U %s\n", item->string);
+               string_list_clear(&cpath, 0);
+       }
+
        return errs;
 }
 
@@ -4100,8 +4150,12 @@ static int apply_patch(int fd, const char *filename, int options)
            !apply_with_reject)
                exit(1);
 
-       if (apply && write_out_results(list))
-               exit(1);
+       if (apply && write_out_results(list)) {
+               if (apply_with_reject)
+                       exit(1);
+               /* with --3way, we still need to write the index out */
+               return 1;
+       }
 
        if (fake_ancestor)
                build_fake_ancestor(list, fake_ancestor);