apply: fall back on three-way merge

Grab the preimage blob the patch claims to be based on out of the object store, apply the patch, and then call three-way-merge function. This step still does not plug the actual three-way merge logic yet, but we are getting there. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Jun 8, 2012 at 09:54 UTC 519d1a5b4e044459bd7323cfa6a7cb98cec5c884
1 file changed +45 -1
builtin/apply.c
+45 -1
@@ -3140,10 +3140,54 @@ static int load_preimage(struct image *image,
3140 return 0;
3141 }
3142
3143 +static int three_way_merge(struct image *image,
3144 + char *path,
3145 + const unsigned char *base,
3146 + const unsigned char *ours,
3147 + const unsigned char *theirs)
3148 +{
3149 + return -1; /* for now */
3150 +}
3151 +
3152 static int try_threeway(struct image *image, struct patch *patch,
3153 struct stat *st, struct cache_entry *ce)
3154 {
3146 - return -1; /* for now */
3155 + unsigned char pre_sha1[20], post_sha1[20], our_sha1[20];
3156 + struct strbuf buf = STRBUF_INIT;
3157 + size_t len;
3158 + char *img;
3159 + struct image tmp_image;
3160 +
3161 + /* No point falling back to 3-way merge in these cases */
3162 + if (patch->is_new || patch->is_delete ||
3163 + S_ISGITLINK(patch->old_mode) || S_ISGITLINK(patch->new_mode))
3164 + return -1;
3165 +
3166 + /* Preimage the patch was prepared for */
3167 + if (get_sha1(patch->old_sha1_prefix, pre_sha1) ||
3168 + read_blob_object(&buf, pre_sha1, patch->old_mode))
3169 + return error("repository lacks the necessary blob to fall back on 3-way merge.");
3170 + img = strbuf_detach(&buf, &len);
3171 + prepare_image(&tmp_image, img, len, 1);
3172 + /* Apply the patch to get the post image */
3173 + if (apply_fragments(&tmp_image, patch) < 0) {
3174 + clear_image(&tmp_image);
3175 + return -1;
3176 + }
3177 + /* post_sha1[] is theirs */
3178 + write_sha1_file(tmp_image.buf, tmp_image.len, blob_type, post_sha1);
3179 + clear_image(&tmp_image);
3180 +
3181 + /* our_sha1[] is ours */
3182 + if (load_preimage(&tmp_image, patch, st, ce))
3183 + return error("cannot read the current contents of '%s'",
3184 + patch->old_name);
3185 + write_sha1_file(tmp_image.buf, tmp_image.len, blob_type, our_sha1);
3186 + clear_image(&tmp_image);
3187 +
3188 + /* in-core three-way merge between post and our using pre as base */
3189 + return three_way_merge(image,
3190 + patch->new_name, pre_sha1, our_sha1, post_sha1);
3191 }
3192
3193 static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *ce)