git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Elijah Newren <newren@gmail.com>
Cc: git@vger.kernel.org, jgfouca@sandia.gov
Subject: Re: [PATCH 00/48] Handling more corner cases in merge-recursive.c
Date: Sat, 11 Jun 2011 11:12:03 -0700	[thread overview]
Message-ID: <7vipsctez0.fsf@alter.siamese.dyndns.org> (raw)
In-Reply-To: <1307518278-23814-1-git-send-email-newren@gmail.com> (Elijah Newren's message of "Wed, 8 Jun 2011 01:30:30 -0600")

Elijah Newren <newren@gmail.com> writes:

> You can note that I did not fix all the testcases I added.  I consider
> some cases either unfixable or not worth fixing.

Thanks for working on these.  A quick comment (after reading a handful of
tests in the early part of the series) I have on rename cases is that the
test might be aiming too high to be too strict in "undetected rename"
cases. Consider:

 - We start from commit A that has path file1 where commit B and C fork
   from;
 - One side, commit B, renames file1 to file2 and edits file2;
 - The other side, commit C, modifies file1.

When merging B and C, we will ideally want to see file1 removed and
content level merge done between C's edit to file1 and B's edit to file2
left in file2. The content level merge may or may not conflict, and if
it cleanly merges, then that is Ok.

But if B's edit is too extensive, we may see what B did as "delete file1,
add file2", and we may report conflict at file1 (delete/modify) while
resolving file2 cleanly (one side added). When notifying the user with
delete/modify conflict at file1, we should make him aware that among the
paths added by the merge (i.e. file2) there might be a corresponding
rewrite of it on the other side, so that such a case can be manually
merged. As long as that is done, a test of such a case should consider
both clean merge (rename noticed) and a conflict at the tree structure
level (delete/modify with new) valid expected result, I think.

To put it another way, merge-recursive should expect that one side of
history may rewrite a path it renames beyond recognition, and when
punting, loudly ask the user for help, with enough information to help the
user to help it (e.g. perhaps say "file1 has delete/modify conflict; the
deleted side has added file2---you the user might want to inspect it and
see if it is a rename with extensive rewrite and resolve it accordingly if
that is the case").  We might want to dig deeper at that point by checking
the similarity again between the two blobs ourselves at that stage before
punting.

If we change what C did to "removes file1", instead of "modifies file1",
the story changes.

When merging B and C, that would be rename/delete conflict (B renamed, C
deleted). However, if we see that B's history as "delete file1 and add
file2", it would merge cleanly with C that deletes file1. The end result
would be an addition of file2. This tastes bad, as it will end up with a
clean merge that the user may not even notice.

Ideally we would want the merge to somehow warn the user to see if the
added "file2" still is wanted, and the worst part of this problem is that
this cannot be mechanically inferred. We could warn against every merge
that has a history that adds new paths and removes some other paths, but
then the warning becomes meaningless.

The changes done by B to the other parts of the tree (that wasn't involved
in the conflict) still want the updated content in file2 to work
correctly, and the changes done by C will not want the original content in
file1 (now in file2). The latter may or may not care about the presense of
what was added to "file2" by B. If C's work was to remove file1 that was
nothing but dead code (and other parts of C's work removed all the
callsite of code in original "file1" to make them dead), while B's work
was to add a code with purpose similar to the original code "file1" had
(and other parts of B's work calls that new code), then the right merge
result of "file2" might be to keep the line removal of dead code made by C
while keeping the code added by B there. So (I am thinking aloud here
without thinking things through) a possible approach to this issue might
involve considering a removal of a path and modifying the contents of a
path to make it empty similarly.

> However, there is one large class of problems that I think is fixable,
> I'm just not sure whether it is worth fixing.  git's rename detection
> optimization of only considering files that exist on one side of the
> diff but not the other causes issues with merges (undetected conflicts,
> spurious conflicts, or merged cleanly but wrongly due to deleting files
> that should be present).  To fix these cases, we would need some way of
> including rewritten files as potential rename candidates,...

This may be part of the larger "when punting, loudly ask the user for
help, or we may want to go deeper". If we can come up with a way to avoid
"undetected conflicts" ("merged cleanly but wrongly" is saying the same
thing as "undetected conflicts"), maybe we can attempt a cheap way first,
and then only when we know there is something complicated going on, we can
redo the diff with -B/-M options on. Spurious conflicts can be handled the
same way, as we should be able to come up with a clean merge once we dig
deeper (that's the definition of "spurious", right?).

  parent reply	other threads:[~2011-06-11 18:12 UTC|newest]

Thread overview: 97+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-06-08  7:30 [PATCH 00/48] Handling more corner cases in merge-recursive.c Elijah Newren
2011-06-08  7:30 ` [PATCH 01/48] t6039: Add a testcase where git deletes an untracked file Elijah Newren
2011-06-08  7:30 ` [PATCH 02/48] t6039: Add failing testcase for rename/modify/add-source conflict Elijah Newren
2011-06-08  7:30 ` [PATCH 03/48] t6039: Add a pair of cases where undetected renames cause issues Elijah Newren
2011-06-08  7:30 ` [PATCH 04/48] t6039: Add a testcase where undetected rename causes silent file deletion Elijah Newren
2011-06-08  7:30 ` [PATCH 05/48] t6039: Add tests for content issues with modify/rename/directory conflicts Elijah Newren
2011-07-18 23:37   ` Junio C Hamano
2011-08-08 15:49     ` Elijah Newren
2011-06-08  7:30 ` [PATCH 06/48] t6039: Add failing testcases for rename/rename/add-{source,dest} conflicts Elijah Newren
2011-07-18 23:38   ` Junio C Hamano
2011-06-08  7:30 ` [PATCH 07/48] t6039: Ensure rename/rename conflicts leave index and workdir in sane state Elijah Newren
2011-07-18 23:40   ` Junio C Hamano
2011-08-08 17:59     ` Elijah Newren
2011-06-08  7:30 ` [PATCH 08/48] t6036: Add differently resolved modify/delete conflict in criss-cross test Elijah Newren
2011-07-18 23:38   ` Junio C Hamano
2011-06-08  7:30 ` [PATCH 09/48] t6036: criss-cross with weird content can fool git into clean merge Elijah Newren
2011-07-18 23:38   ` Junio C Hamano
2011-08-08 18:02     ` Elijah Newren
2011-06-08  7:30 ` [PATCH 10/48] t6036: tests for criss-cross merges with various directory/file conflicts Elijah Newren
2011-07-18 23:40   ` Junio C Hamano
2011-08-08 19:07     ` Elijah Newren
2011-06-08  7:30 ` [PATCH 11/48] t6036: criss-cross w/ rename/rename(1to2)/modify+rename/rename(2to1)/modify Elijah Newren
2011-07-18 23:38   ` Junio C Hamano
2011-06-08  7:30 ` [PATCH 12/48] t6036: criss-cross + rename/rename(1to2)/add-source + modify/modify Elijah Newren
2011-07-18 23:38   ` Junio C Hamano
2011-07-20 23:15     ` Phil Hord
2011-06-08  7:30 ` [PATCH 13/48] t6022: Remove unnecessary untracked files to make test cleaner Elijah Newren
2011-06-08  7:30 ` [PATCH 14/48] t6022: New tests checking for unnecessary updates of files Elijah Newren
2011-06-08  7:30 ` [PATCH 15/48] t6022: Add testcase for merging a renamed file with a simple change Elijah Newren
2011-06-08  7:30 ` [PATCH 16/48] merge-recursive: Make BUG message more legible by adding a newline Elijah Newren
2011-06-08  7:30 ` [PATCH 17/48] merge-recursive: Correct a comment Elijah Newren
2011-06-08  7:30 ` [PATCH 18/48] merge-recursive: Mark some diff_filespec struct arguments const Elijah Newren
2011-07-18 23:40   ` Junio C Hamano
2011-06-08  7:30 ` [PATCH 19/48] merge-recursive: Remember to free generated unique path names Elijah Newren
2011-07-18 23:39   ` Junio C Hamano
2011-06-08  7:30 ` [PATCH 20/48] merge-recursive: Avoid working directory changes during recursive case Elijah Newren
2011-06-08  7:30 ` [PATCH 21/48] merge-recursive: Fix recursive case with D/F conflict via add/add conflict Elijah Newren
2011-07-18 23:40   ` Junio C Hamano
2011-06-08  7:30 ` [PATCH 22/48] merge-recursive: Fix sorting order and directory change assumptions Elijah Newren
2011-07-11  7:04   ` Johannes Sixt
2011-07-12  7:27     ` Johannes Sixt
2011-07-13  7:24       ` Johannes Sixt
2011-07-13 20:34         ` Junio C Hamano
2011-07-18 23:39   ` Junio C Hamano
2011-08-08 19:21     ` Elijah Newren
2011-06-08  7:30 ` [PATCH 23/48] merge-recursive: Fix code checking for D/F conflicts still being present Elijah Newren
2011-06-08  7:30 ` [PATCH 24/48] merge-recursive: Save D/F conflict filenames instead of unlinking them Elijah Newren
2011-06-08  7:30 ` [PATCH 25/48] merge-recursive: Split was_tracked() out of would_lose_untracked() Elijah Newren
2011-06-08  7:30 ` [PATCH 26/48] merge-recursive: Allow make_room_for_path() to remove D/F entries Elijah Newren
2011-07-11  7:14   ` Johannes Sixt
2011-07-13  7:17   ` Johannes Sixt
2011-08-08 20:56     ` Elijah Newren
2011-08-09  7:01       ` Johannes Sixt
2011-07-18 23:39   ` Junio C Hamano
2011-06-08  7:30 ` [PATCH 27/48] merge-recursive: Consolidate different update_stages functions Elijah Newren
2011-07-18 23:39   ` Junio C Hamano
2011-06-08  7:30 ` [PATCH 28/48] merge-recursive: Split update_stages_and_entry; only update stages at end Elijah Newren
2011-07-18 23:39   ` Junio C Hamano
2011-06-08  7:30 ` [PATCH 29/48] merge-recursive: When we detect we can skip an update, actually skip it Elijah Newren
2011-07-18 23:39   ` Junio C Hamano
2011-06-08  7:31 ` [PATCH 30/48] merge-recursive: Fix deletion of untracked file in rename/delete conflicts Elijah Newren
2011-07-21 18:43   ` Junio C Hamano
2011-06-08  7:31 ` [PATCH 31/48] merge-recursive: Make dead code for rename/rename(2to1) conflicts undead Elijah Newren
2011-06-08  7:31 ` [PATCH 32/48] merge-recursive: Add comments about handling rename/add-source cases Elijah Newren
2011-06-08  7:31 ` [PATCH 33/48] merge-recursive: Improve handling of rename target vs. directory addition Elijah Newren
2011-06-08  7:31 ` [PATCH 34/48] merge-recursive: Consolidate process_entry() and process_df_entry() Elijah Newren
2011-07-21 18:43   ` Junio C Hamano
2011-06-08  7:31 ` [PATCH 35/48] merge-recursive: Cleanup and consolidation of rename_conflict_info Elijah Newren
2011-06-08  7:31 ` [PATCH 36/48] merge-recursive: Provide more info in conflict markers with file renames Elijah Newren
2011-07-21 18:43   ` Junio C Hamano
2011-06-08  7:31 ` [PATCH 37/48] merge-recursive: Fix modify/delete resolution in the recursive case Elijah Newren
2011-07-21 18:43   ` Junio C Hamano
2011-08-08 22:09     ` Elijah Newren
2011-06-08  7:31 ` [PATCH 38/48] merge-recursive: Introduce a merge_file convenience function Elijah Newren
2011-06-08  7:31 ` [PATCH 39/48] merge-recursive: Fix rename/rename(1to2) resolution for virtual merge base Elijah Newren
2011-07-25 20:55   ` Junio C Hamano
2011-08-08 22:58     ` Elijah Newren
2011-06-08  7:31 ` [PATCH 40/48] merge-recursive: Small cleanups for conflict_rename_rename_1to2 Elijah Newren
2011-06-08  7:31 ` [PATCH 41/48] merge-recursive: Defer rename/rename(2to1) handling until process_entry Elijah Newren
2011-06-08  7:31 ` [PATCH 42/48] merge-recursive: Record more data needed for merging with dual renames Elijah Newren
2011-06-08  7:31 ` [PATCH 43/48] merge-recursive: Create function for merging with branchname:file markers Elijah Newren
2011-06-08  7:31 ` [PATCH 44/48] merge-recursive: Consider modifications in rename/rename(2to1) conflicts Elijah Newren
2011-06-08  7:31 ` [PATCH 45/48] merge-recursive: Make modify/delete handling code reusable Elijah Newren
2011-06-08  7:31 ` [PATCH 46/48] merge-recursive: Have conflict_rename_delete reuse modify/delete code Elijah Newren
2011-06-08  7:31 ` [PATCH 47/48] merge-recursive: add handling for rename/rename/add-dest/add-dest Elijah Newren
2011-06-08  7:31 ` [PATCH 48/48] merge-recursive: Fix working copy handling for rename/rename/add/add Elijah Newren
2011-06-11 18:12 ` Junio C Hamano [this message]
     [not found]   ` <BANLkTimd0O70e7KhT-G5quxQhF_Nwc30Hg@mail.gmail.com>
2011-06-12  6:18     ` [PATCH 00/48] Handling more corner cases in merge-recursive.c Junio C Hamano
2011-06-12  6:28       ` Junio C Hamano
2011-08-04  0:20 ` Junio C Hamano
2011-08-04  1:48   ` Junio C Hamano
2011-08-04  2:12     ` Elijah Newren
2011-08-04 17:26   ` Elijah Newren
2011-08-04 19:03     ` Junio C Hamano
2011-08-04 19:16       ` Elijah Newren
2011-08-06  5:22         ` Junio C Hamano
2011-08-06 20:31           ` Elijah Newren

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

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7vipsctez0.fsf@alter.siamese.dyndns.org \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    --cc=jgfouca@sandia.gov \
    --cc=newren@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.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).