Subject: [PATCH v2 0/4] Attr fixes

From: "Elijah Newren via GitGitGadget" <[email-masked]>
Date: Mon, 03 Aug 2020 18:41:16 +0000

This fixes a few issues surrounding .gitattributes files and usage of the
merge machinery outside of "git merge". All were issues I found and fixed
while working on merge-ort.

Changes since v1:

 * Made the fixes suggested by Eric and Junio
 * Just ripped out the test in patch 2 that was testing undefined behavior
   (especially since it was a test_expect_failure, and clearly was testing
   multiple things wrong), as suggested by Junio.

Elijah Newren (4):
  t6038: make tests fail for the right reason
  t6038: remove problematic test
  merge: make merge.renormalize work for all uses of merge machinery
  checkout: support renormalization with checkout -m <paths>

 builtin/checkout.c         | 18 ++++++------------
 builtin/merge.c            |  4 ----
 merge-recursive.c          |  3 +++
 t/t6038-merge-text-auto.sh | 26 ++++++--------------------
 4 files changed, 15 insertions(+), 36 deletions(-)

base-commit: 47ae905ffb98cc4d4fd90083da6bc8dab55d9ecc
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-825%2Fnewren%2Fattr-fixes-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-825/newren/attr-fixes-v2
Pull-Request: https://github.com/git/git/pull/825

Range-diff vs v1:

 1:  3619118175 ! 1:  21033c4c14 t6038: make tests fail for the right reason
     @@ Commit message
          t6038 had a pair of tests that were expected to fail, but weren't
          failing for the expected reason.  Both were meant to do a merge that
          could be done cleanly after renormalization, but were supposed to fail
     -    for lack of renormalization.  Unfortunately, both tests has staged
     +    for lack of renormalization.  Unfortunately, both tests had staged
          changes, and checkout -m would abort due to the presence of those staged
          changes before even attempting a merge.
      
 2:  83a50f7e0b ! 2:  305fe534c5 t6038: fix test with obviously incorrect expectations
     @@ Metadata
      Author: Elijah Newren <[email-masked]>
      
       ## Commit message ##
     -    t6038: fix test with obviously incorrect expectations
     +    t6038: remove problematic test
      
     -    t6038.11, 'cherry-pick patch from after text=auto' was set up so that on
     -    a branch with no .gitattributes file, you cherry-picked a patch from a
     -    branch that had a .gitattributes file (containing '* text=auto').
     -    Further, the two branches had a file which differed only in line
     -    endings.  In this situation, correct behavior is not well defined:
     -    should the .gitattributes file affect the merge or not?
     +    t6038.11, 'cherry-pick patch from after text=auto' was a test of
     +    undefined behavior.  To make matters worse, while there are a couple
     +    possible correct answers, this test was coded to only check for an
     +    obviously incorrect answer.  And the final cherry on top is that the
     +    test is marked test_expect_failure, meaning it can't provide much value,
     +    other than possibly confusing future folks who come along and try to
     +    work on attributes and look at existing tests.  Because of all these
     +    problems, just remove the test.
     +
     +    But for any future code spelunkers, here's my understanding of the two
     +    possible correct answers:
     +
     +    This test was set up so that on a branch with no .gitattributes file,
     +    you cherry-picked a patch from a branch that had a .gitattributes file
     +    (containing '* text=auto').  Further, the two branches had a file which
     +    differed only in line endings.  In this situation, correct behavior is
     +    not well defined: should the .gitattributes file affect the merge or
     +    not?
      
          If the .gitattributes file on the other branch should not affect the
          merge, then we would have a content conflict with all three stages
          different (the merge base didn't match either side).
      
          If the .gitattributes file from the other branch should affect the
     -    merge, then we would expect the line endings to be normalized to LF so
     -    that the versions from both sides match, and then the cherry-pick has no
     -    conflicts and can succeed.  After the cherry-pick, the line endings in
     -    the file will change from CRLF to LF.
     -
     -    This test had an expectation that the line endings would remain CRLF.
     -    Further, it expected an error message that was built assuming
     -    cherry-pick was the old scripted version, because cherry-pick no longer
     -    uses the error message that was encoded in this test.  So, although I
     -    don't know what correct behavior for this test is, I know that this test
     -    was not testing for it.
     -
     -    Since I have no idea which of the two cases above provides correct
     -    behavior, let's just assume for now it's the case where we assume that
     -    .gitattributes affects the merge and update it accordingly.
     +    merge, then we would expect the line endings to be normalized to LF for
     +    the version to be recorded in the repository.  This would mean that when
     +    doing a three-way content merge on the file that differed in line
     +    endings, that the three-way content merge would see that the versions on
     +    both sides matched and so the cherry-pick has no conflicts and can
     +    succeed.  The line endings in the file as recorded in the repository
     +    will change from CRLF to LF.  The version checked out in the working
     +    copy will depend on the platform (since there's no eol attribute defined
     +    for the file).
     +
     +    Also, as a final side note, this test expected an error message that was
     +    built assuming cherry-pick was the old scripted version, because
     +    cherry-pick no longer uses the error message that was encoded in this
     +    test.  So it was wrong for yet another reason.
     +
     +    Given that the handling of .gitattributes is not well defined and this
     +    test was obviously broken and could do nothing but confuse future
     +    readers, just remove it.
      
          Signed-off-by: Elijah Newren <[email-masked]>
      
       ## t/t6038-merge-text-auto.sh ##
      @@ t/t6038-merge-text-auto.sh: test_expect_failure 'checkout -m addition of text=auto' '
     + 	git diff --no-index --ignore-cr-at-eol expected file
       '
       
     - test_expect_failure 'cherry-pick patch from after text=auto was added' '
     +-test_expect_failure 'cherry-pick patch from after text=auto was added' '
      -	append_cr <<-\EOF >expected &&
     -+	cat <<-\EOF >expected &&
     - 	first line
     - 	same line
     - 	EOF
     -@@ t/t6038-merge-text-auto.sh: test_expect_failure 'cherry-pick patch from after text=auto was added' '
     - 	git config merge.renormalize true &&
     - 	git rm -fr . &&
     - 	git reset --hard b &&
     +-	first line
     +-	same line
     +-	EOF
     +-
     +-	git config merge.renormalize true &&
     +-	git rm -fr . &&
     +-	git reset --hard b &&
      -	test_must_fail git cherry-pick a >err 2>&1 &&
      -	grep "[Nn]othing added" err &&
      -	compare_files expected file
     -+	git cherry-pick a &&
     -+	git cat-file -p HEAD:file >actual &&
     -+	compare_files expected actual
     - '
     - 
     +-'
     +-
       test_expect_success 'Test delete/normalize conflict' '
     + 	git checkout -f side &&
     + 	git rm -fr . &&
 3:  08c8080b31 ! 3:  379a87ea82 merge: make merge.renormalize work for all uses of merge machinery
     @@ builtin/merge.c: static const char **xopts;
       static const char *branch;
       static char *branch_mergeoptions;
      -static int option_renormalize;
     -+static int option_renormalize = -1;
       static int verbosity;
       static int allow_rerere_auto;
       static int abort_current_merge;
     @@ builtin/merge.c: static int try_merge_strategy(const char *strategy, struct comm
       			o.subtree_shift = "";
       
      -		o.renormalize = option_renormalize;
     -+		if (option_renormalize != -1)
     -+			o.renormalize = option_renormalize;
       		o.show_rename_progress =
       			show_progress == -1 ? isatty(2) : show_progress;
       
 4:  fcc7ea3add = 4:  36e08a75a3 checkout: support renormalization with checkout -m <paths>

-- 
gitgitgadget