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 07/48] t6039: Ensure rename/rename conflicts leave index and workdir in sane state
Date: Mon, 18 Jul 2011 16:40:28 -0700	[thread overview]
Message-ID: <7vaacbb1jn.fsf@alter.siamese.dyndns.org> (raw)
In-Reply-To: 1307518278-23814-8-git-send-email-newren@gmail.com

Elijah Newren <newren@gmail.com> writes:

> +test_expect_success 'setup simple rename/rename (1to2) conflict' '
> +	git rm -rf . &&
> +	git clean -fdqx &&
> +	rm -rf .git &&
> +	git init &&
> +
> +	echo stuff >a &&
> +	git add a &&
> +	test_tick &&
> +	git commit -m A &&
> +	git tag A &&
> +
> +	git checkout -b B A &&
> +	git mv a b &&
> +	test_tick &&
> +	git commit -m B &&
> +
> +	git checkout -b C A &&
> +	git mv a c &&
> +	test_tick &&
> +	git commit -m C
> +'

This looks like a simpler variant of the last test in 06/48; shouldn't it
come before the more complex one?

> +
> +test_expect_success 'merge has correct working tree contents' '
> +	git checkout C^0 &&
> +
> +	test_must_fail git merge -s recursive B^0 &&
> +
> +	test 3 -eq $(git ls-files -s | wc -l) &&
> +	test 3 -eq $(git ls-files -u | wc -l) &&
> +	test 0 -eq $(git ls-files -o | wc -l) &&
> +
> +	test -f b &&
> +	test -f c
> +'

This test is being a bit too lazy, compared to the better ones in 06/48,
no? What do we want to see here? Perhaps

 - "a" at stage #1 with "stuff", not in the working tree;
 - "b" at stage #3 with "stuff", same in the working tree; and
 - "c" at stage #2 with "stuff", same in the working tree

> +# Test for all kinds of things that can go wrong with rename/rename (2to1):
> +#   Commit A: new files: a & b
> +#   Commit B: rename a->c, modify b
> +#   Commit C: rename b->c, modify a
> +#
> +# Merging of B & C should NOT be clean.  Questions:
> +#   * Both a & b should be removed by the merge; are they?
> +#   * The two c's should contain modifications to a & b; do they?
> +#   * The index should contain two files, both for c; does it?
> +#   * The working copy should have two files, both of form c~<unique>; does it?
> +#   * Nothing else should be present.  Is anything?

What is the most useful thing to leave in the index and in the working
tree for the person who needs to resolve such a merge using the working
tree, starting from B and merging C? The above "Questions" lists what the
current code might try to do but I am not sure if it is really useful. For
example, in the index, you would have to stuff two stage #1 entries ("a"
from A and "b" from A) for path "c", with stage #2 ("c" from B) and stage
#3 ("c" from C) entries, and represent what B tried to do to "a" (in the
above you said "rename a->c" but it does not have to be a rename without
content change) and what C tried to do to "b" in the half-conflicted
result that is in a single file "c". Because the result are totally
unrelated files (one side wants a variant of original "a" there, the other
side wants a variant of "b"), such a half-merge result is totally useless
to help the person to come up with anything.

Also renaming "c" to "c~<unique>", if they do not have corresponding
entries in the index to let you check with "git diff", would make the
result _harder_ to use, not easier. So if you are going to rename "c" to
"c-B" and "c-C", at least it would make much more sense to have in the
index:

 - "c-B", with stage #1 ("a" from A), stage #2 ("c" from B) and stage #3
   ("a" from C);
 - "c-C", with stage #1 ("b" from A), stage #2 ("b" from B) and stage #3
   ("c" from C); and
 - No "a" nor "b" in the index nor in the working tree.

no?

That way, you could run "git diff" to get what happened to the two
variants of "a" and "b" at the content level, and decide to clean things
up with:

    $ git diff ;# view content level merge
    $ edit c-B c-C; git add c-B c-C
    $ git mv c-B c-some-saner-name
    $ git mv c-C c-another-saner-name
    $ edit other files that refer to c like Makefile
    $ git commit

To take it one step further to the extreme, it might give us a more
reasonable and useful conflicted state if we deliberately dropped some
information instead in a case like this, e.g.:

 - We may want to have "a" at stage #1 (from A) in the index;
 - No "a" remains in the working tree;
 - "b" at stage #1 (from A), stage #2 (from B) and stage #3 ("c" from C);
 - "b" in the working tree a conflicted-merge of the above three;
 - "c" at stage #1 ("a" from A), stage #2 (from B), and stage #3 ("a" from
   C); and
 - "c" in the working tree a conflicted-merge of the above three.

Note that unlike the current merge-recursive that tries to come up with a
temporary pathname to store both versions of C, this would ignore "mv b c"
on the A->C branch, and make the conflicted tentative merge asymmetric
(merging B into C and merging C into B would give different conflicts),
but I suspect that the asymmetry may not hurt us.

Whether the merger wants to keep "c" that was derived from "a" (in line
with the HEAD) or "c" that was derived from "b" (in line with MERGE_HEAD),
if the result were to keep both files in some shape, the content level
edit, renaming of at least one side, and adjusting other files that refer
to it, are all required anyway, e.g.

    $ git diff ;# view content level merge
    $ edit b c; git add b c
    $ edit other files that refer to c line Makefile (the content C's
      change wants is now in "b").
    $ git commit

would be a way to pick "c" as "c-some-saner-name" and "b" as
"c-another-saner-name" in the previous workflow, but needs much less
typing. The complexity of the workflow would be the same if the final
resolution is to take what one side did and dropping the other's work,
I think.

  reply	other threads:[~2011-07-18 23:40 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 [this message]
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 ` [PATCH 00/48] Handling more corner cases in merge-recursive.c Junio C Hamano
     [not found]   ` <BANLkTimd0O70e7KhT-G5quxQhF_Nwc30Hg@mail.gmail.com>
2011-06-12  6:18     ` 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=7vaacbb1jn.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).