- if (entry->rename_df_conflict_info)
- return 1; /* Such cases are handled elsewhere. */
-
- entry->processed = 1;
- if (o_sha && (!a_sha || !b_sha)) {
- /* Case A: Deleted in one */
- if ((!a_sha && !b_sha) ||
- (!b_sha && blob_unchanged(o_sha, a_sha, normalize, path)) ||
- (!a_sha && blob_unchanged(o_sha, b_sha, normalize, path))) {
- /* Deleted in both or deleted in one and
- * unchanged in the other */
- if (a_sha)
- output(o, 2, "Removing %s", path);
- /* do not touch working file if it did not exist */
- remove_file(o, 1, path, !a_sha);
- } else if (dir_in_way(path, 0 /*check_wc*/)) {
- entry->processed = 0;
- return 1; /* Assume clean until processed */
- } else {
- /* Deleted in one and changed in the other */
- clean_merge = 0;
- handle_delete_modify(o, path, path,
- a_sha, a_mode, b_sha, b_mode);
- }
-
- } else if ((!o_sha && a_sha && !b_sha) ||
- (!o_sha && !a_sha && b_sha)) {
- /* Case B: Added in one. */
- unsigned mode;
- const unsigned char *sha;
-
- if (a_sha) {
- mode = a_mode;
- sha = a_sha;
- } else {
- mode = b_mode;
- sha = b_sha;
- }
- if (dir_in_way(path, 0 /*check_wc*/)) {
- /* Handle D->F conflicts after all subfiles */
- entry->processed = 0;
- return 1; /* Assume clean until processed */
- } else {
- output(o, 2, "Adding %s", path);
- update_file(o, 1, sha, mode, path);
- }
- } else if (a_sha && b_sha) {
- /* Case C: Added in both (check for same permissions) and */
- /* case D: Modified in both, but differently. */
- clean_merge = merge_content(o, entry->involved_in_rename, path,
- o_sha, o_mode, a_sha, a_mode, b_sha, b_mode,
- NULL);
- } else if (!o_sha && !a_sha && !b_sha) {
- /*
- * this entry was deleted altogether. a_mode == 0 means
- * we had that path and want to actively remove it.
- */
- remove_file(o, 1, path, !a_mode);
- } else
- die("Fatal merge failure, shouldn't happen.");
-
- return clean_merge;
-}
-
-/*
- * Per entry merge function for D/F (and/or rename) conflicts. In the
- * cases we can cleanly resolve D/F conflicts, process_entry() can
- * clean out all the files below the directory for us. All D/F
- * conflict cases must be handled here at the end to make sure any
- * directories that can be cleaned out, are.
- *
- * Some rename conflicts may also be handled here that don't necessarily
- * involve D/F conflicts, since the code to handle them is generic enough
- * to handle those rename conflicts with or without D/F conflicts also
- * being involved.
- */
-static int process_df_entry(struct merge_options *o,
- const char *path, struct stage_data *entry)
-{
- int clean_merge = 1;
- unsigned o_mode = entry->stages[1].mode;
- unsigned a_mode = entry->stages[2].mode;
- unsigned b_mode = entry->stages[3].mode;
- unsigned char *o_sha = stage_sha(entry->stages[1].sha, o_mode);
- unsigned char *a_sha = stage_sha(entry->stages[2].sha, a_mode);
- unsigned char *b_sha = stage_sha(entry->stages[3].sha, b_mode);
-