From: "Elijah Newren via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Derrick Stolee <stolee@gmail.com>,
Elijah Newren <newren@gmail.com>,
Johannes Schindelin <Johannes.Schindelin@gmx.de>,
Elijah Newren <newren@gmail.com>,
Elijah Newren <newren@gmail.com>
Subject: [PATCH v2 07/11] merge-ort: add implementation of both sides renaming differently
Date: Mon, 14 Dec 2020 16:21:36 +0000 [thread overview]
Message-ID: <d00e26be784d7915b2d476b0c86f37aa366a4274.1607962900.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.812.v2.git.1607962900.gitgitgadget@gmail.com>
From: Elijah Newren <newren@gmail.com>
Implement rename/rename(1to2) handling, i.e. both sides of history
renaming a file and rename it differently. This code replaces the
following from merge-recurisve.c:
* all the 1to2 code in process_renames()
* the RENAME_ONE_FILE_TO_TWO case of process_entry()
* handle_rename_rename_1to2()
Also, there is some shared code from merge-recursive.c for multiple
different rename cases which we will no longer need for this case (or
other rename cases):
* handle_file_collision()
* setup_rename_conflict_info()
The consolidation of five separate codepaths into one is made possible
by a change in design: process_renames() tweaks the conflict_info
entries within opt->priv->paths such that process_entry() can then
handle all the non-rename conflict types (directory/file, modify/delete,
etc.) orthogonally. This means we're much less likely to miss special
implementation of some kind of combination of conflict types (see
commits brought in by 66c62eaec6 ("Merge branch 'en/merge-tests'",
2020-11-18), especially commit ef52778708 ("merge tests: expect improved
directory/file conflict handling in ort", 2020-10-26) for more details).
That, together with letting worktree/index updating be handled
orthogonally in the merge_switch_to_result() function, dramatically
simplifies the code for various special rename cases.
To be fair, there is a _slight_ tweak to process_entry() here to make
sure that the two different paths aren't marked as clean but are left in
a conflicted state. So process_renames() and process_entry() aren't
quite entirely orthogonal, but they are pretty close.
Signed-off-by: Elijah Newren <newren@gmail.com>
---
merge-ort.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 54 insertions(+), 3 deletions(-)
diff --git a/merge-ort.c b/merge-ort.c
index 4034ffcf501..19477cfae60 100644
--- a/merge-ort.c
+++ b/merge-ort.c
@@ -707,7 +707,58 @@ static int process_renames(struct merge_options *opt,
}
/* This is a rename/rename(1to2) */
- die("Not yet implemented");
+ clean_merge = handle_content_merge(opt,
+ pair->one->path,
+ &base->stages[0],
+ &side1->stages[1],
+ &side2->stages[2],
+ pathnames,
+ 1 + 2 * opt->priv->call_depth,
+ &merged);
+ if (!clean_merge &&
+ merged.mode == side1->stages[1].mode &&
+ oideq(&merged.oid, &side1->stages[1].oid))
+ was_binary_blob = 1;
+ memcpy(&side1->stages[1], &merged, sizeof(merged));
+ if (was_binary_blob) {
+ /*
+ * Getting here means we were attempting to
+ * merge a binary blob.
+ *
+ * Since we can't merge binaries,
+ * handle_content_merge() just takes one
+ * side. But we don't want to copy the
+ * contents of one side to both paths. We
+ * used the contents of side1 above for
+ * side1->stages, let's use the contents of
+ * side2 for side2->stages below.
+ */
+ oidcpy(&merged.oid, &side2->stages[2].oid);
+ merged.mode = side2->stages[2].mode;
+ }
+ memcpy(&side2->stages[2], &merged, sizeof(merged));
+
+ side1->path_conflict = 1;
+ side2->path_conflict = 1;
+ /*
+ * TODO: For renames we normally remove the path at the
+ * old name. It would thus seem consistent to do the
+ * same for rename/rename(1to2) cases, but we haven't
+ * done so traditionally and a number of the regression
+ * tests now encode an expectation that the file is
+ * left there at stage 1. If we ever decide to change
+ * this, add the following two lines here:
+ * base->merged.is_null = 1;
+ * base->merged.clean = 1;
+ * and remove the setting of base->path_conflict to 1.
+ */
+ base->path_conflict = 1;
+ path_msg(opt, oldpath, 0,
+ _("CONFLICT (rename/rename): %s renamed to "
+ "%s in %s and to %s in %s."),
+ pathnames[0],
+ pathnames[1], opt->branch1,
+ pathnames[2], opt->branch2);
i++; /* We handled both renames, i.e. i+1 handled */
continue;
@@ -1292,13 +1343,13 @@ static void process_entry(struct merge_options *opt,
int side = (ci->filemask == 4) ? 2 : 1;
ci->merged.result.mode = ci->stages[side].mode;
oidcpy(&ci->merged.result.oid, &ci->stages[side].oid);
- ci->merged.clean = !ci->df_conflict;
+ ci->merged.clean = !ci->df_conflict && !ci->path_conflict;
} else if (ci->filemask == 1) {
/* Deleted on both sides */
ci->merged.is_null = 1;
ci->merged.result.mode = 0;
oidcpy(&ci->merged.result.oid, &null_oid);
- ci->merged.clean = 1;
+ ci->merged.clean = !ci->path_conflict;
}
/*
--
gitgitgadget
next prev parent reply other threads:[~2020-12-14 16:26 UTC|newest]
Thread overview: 65+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-09 19:41 [PATCH 00/11] merge-ort: add basic rename detection Elijah Newren via GitGitGadget
2020-12-09 19:41 ` [PATCH 01/11] merge-ort: add basic data structures for handling renames Elijah Newren via GitGitGadget
2020-12-11 2:03 ` Derrick Stolee
2020-12-11 9:41 ` Elijah Newren
2020-12-09 19:41 ` [PATCH 02/11] merge-ort: add initial outline for basic rename detection Elijah Newren via GitGitGadget
2020-12-11 2:39 ` Derrick Stolee
2020-12-11 9:40 ` Elijah Newren
2020-12-13 7:47 ` Elijah Newren
2020-12-14 14:33 ` Derrick Stolee
2020-12-14 15:42 ` Johannes Schindelin
2020-12-14 16:11 ` Elijah Newren
2020-12-14 16:50 ` Johannes Schindelin
2020-12-14 17:35 ` Elijah Newren
2020-12-09 19:41 ` [PATCH 03/11] merge-ort: implement detect_regular_renames() Elijah Newren via GitGitGadget
2020-12-11 2:54 ` Derrick Stolee
2020-12-11 17:38 ` Elijah Newren
2020-12-09 19:41 ` [PATCH 04/11] merge-ort: implement compare_pairs() and collect_renames() Elijah Newren via GitGitGadget
2020-12-11 3:00 ` Derrick Stolee
2020-12-11 18:43 ` Elijah Newren
2020-12-09 19:41 ` [PATCH 05/11] merge-ort: add basic outline for process_renames() Elijah Newren via GitGitGadget
2020-12-11 3:24 ` Derrick Stolee
2020-12-11 20:03 ` Elijah Newren
2020-12-09 19:41 ` [PATCH 06/11] merge-ort: add implementation of both sides renaming identically Elijah Newren via GitGitGadget
2020-12-11 3:32 ` Derrick Stolee
2020-12-09 19:41 ` [PATCH 07/11] merge-ort: add implementation of both sides renaming differently Elijah Newren via GitGitGadget
2020-12-11 3:39 ` Derrick Stolee
2020-12-11 21:56 ` Elijah Newren
2020-12-09 19:41 ` [PATCH 08/11] merge-ort: add implementation of rename collisions Elijah Newren via GitGitGadget
2020-12-09 19:41 ` [PATCH 09/11] merge-ort: add implementation of rename/delete conflicts Elijah Newren via GitGitGadget
2020-12-09 19:41 ` [PATCH 10/11] merge-ort: add implementation of normal rename handling Elijah Newren via GitGitGadget
2020-12-09 19:41 ` [PATCH 11/11] merge-ort: add implementation of type-changed " Elijah Newren via GitGitGadget
2020-12-14 16:21 ` [PATCH v2 00/11] merge-ort: add basic rename detection Elijah Newren via GitGitGadget
2020-12-14 16:21 ` [PATCH v2 01/11] merge-ort: add basic data structures for handling renames Elijah Newren via GitGitGadget
2020-12-14 16:21 ` [PATCH v2 02/11] merge-ort: add initial outline for basic rename detection Elijah Newren via GitGitGadget
2020-12-14 16:21 ` [PATCH v2 03/11] merge-ort: implement detect_regular_renames() Elijah Newren via GitGitGadget
2020-12-14 16:21 ` [PATCH v2 04/11] merge-ort: implement compare_pairs() and collect_renames() Elijah Newren via GitGitGadget
2020-12-14 16:21 ` [PATCH v2 05/11] merge-ort: add basic outline for process_renames() Elijah Newren via GitGitGadget
2020-12-14 16:21 ` [PATCH v2 06/11] merge-ort: add implementation of both sides renaming identically Elijah Newren via GitGitGadget
2020-12-14 16:21 ` Elijah Newren via GitGitGadget [this message]
2020-12-14 16:21 ` [PATCH v2 08/11] merge-ort: add implementation of rename collisions Elijah Newren via GitGitGadget
2020-12-15 14:09 ` Derrick Stolee
2020-12-15 16:56 ` Elijah Newren
2020-12-14 16:21 ` [PATCH v2 09/11] merge-ort: add implementation of rename/delete conflicts Elijah Newren via GitGitGadget
2020-12-15 14:23 ` Derrick Stolee
2020-12-15 17:07 ` Elijah Newren
2020-12-15 14:27 ` Derrick Stolee
2020-12-14 16:21 ` [PATCH v2 10/11] merge-ort: add implementation of normal rename handling Elijah Newren via GitGitGadget
2020-12-15 14:27 ` Derrick Stolee
2020-12-14 16:21 ` [PATCH v2 11/11] merge-ort: add implementation of type-changed " Elijah Newren via GitGitGadget
2020-12-15 14:31 ` Derrick Stolee
2020-12-15 17:11 ` Elijah Newren
2020-12-15 14:34 ` [PATCH v2 00/11] merge-ort: add basic rename detection Derrick Stolee
2020-12-15 22:09 ` Junio C Hamano
2020-12-15 18:27 ` [PATCH v3 " Elijah Newren via GitGitGadget
2020-12-15 18:27 ` [PATCH v3 01/11] merge-ort: add basic data structures for handling renames Elijah Newren via GitGitGadget
2020-12-15 18:27 ` [PATCH v3 02/11] merge-ort: add initial outline for basic rename detection Elijah Newren via GitGitGadget
2020-12-15 18:27 ` [PATCH v3 03/11] merge-ort: implement detect_regular_renames() Elijah Newren via GitGitGadget
2020-12-15 18:27 ` [PATCH v3 04/11] merge-ort: implement compare_pairs() and collect_renames() Elijah Newren via GitGitGadget
2020-12-15 18:28 ` [PATCH v3 05/11] merge-ort: add basic outline for process_renames() Elijah Newren via GitGitGadget
2020-12-15 18:28 ` [PATCH v3 06/11] merge-ort: add implementation of both sides renaming identically Elijah Newren via GitGitGadget
2020-12-15 18:28 ` [PATCH v3 07/11] merge-ort: add implementation of both sides renaming differently Elijah Newren via GitGitGadget
2020-12-15 18:28 ` [PATCH v3 08/11] merge-ort: add implementation of rename/delete conflicts Elijah Newren via GitGitGadget
2020-12-15 18:28 ` [PATCH v3 09/11] merge-ort: add implementation of rename collisions Elijah Newren via GitGitGadget
2020-12-15 18:28 ` [PATCH v3 10/11] merge-ort: add implementation of normal rename handling Elijah Newren via GitGitGadget
2020-12-15 18:28 ` [PATCH v3 11/11] merge-ort: add implementation of type-changed " Elijah Newren via GitGitGadget
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=d00e26be784d7915b2d476b0c86f37aa366a4274.1607962900.git.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=Johannes.Schindelin@gmx.de \
--cc=git@vger.kernel.org \
--cc=newren@gmail.com \
--cc=stolee@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).