Merge branch 'tb/check-crlf-for-safe-crlf'
authorJunio C Hamano <gitster@pobox.com>
Wed, 27 Dec 2017 19:16:21 +0000 (11:16 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 27 Dec 2017 19:16:21 +0000 (11:16 -0800)
The "safe crlf" check incorrectly triggered for contents that does
not use CRLF as line endings, which has been corrected.

* tb/check-crlf-for-safe-crlf:
t0027: Adapt the new MIX tests to Windows
convert: tighten the safe autocrlf handling

1  2 
convert.c
t/t0027-auto-crlf.sh
diff --combined convert.c
index 20d7ab67bdf889feb255e01a9b18cf4efa6107a3,d3b39dd61d0a741265b4e80ff355e2c17f80cd40..1a41a48e15efd7a6c3030e7a0d1097cbc08099c1
+++ b/convert.c
@@@ -220,18 -220,27 +220,27 @@@ static void check_safe_crlf(const char 
        }
  }
  
- static int has_cr_in_index(const struct index_state *istate, const char *path)
+ static int has_crlf_in_index(const struct index_state *istate, const char *path)
  {
        unsigned long sz;
        void *data;
-       int has_cr;
+       const char *crp;
+       int has_crlf = 0;
  
        data = read_blob_data_from_index(istate, path, &sz);
        if (!data)
                return 0;
-       has_cr = memchr(data, '\r', sz) != NULL;
+       crp = memchr(data, '\r', sz);
+       if (crp) {
+               unsigned int ret_stats;
+               ret_stats = gather_convert_stats(data, sz);
+               if (!(ret_stats & CONVERT_STAT_BITS_BIN) &&
+                   (ret_stats & CONVERT_STAT_BITS_TXT_CRLF))
+                       has_crlf = 1;
+       }
        free(data);
-       return has_cr;
+       return has_crlf;
  }
  
  static int will_convert_lf_to_crlf(size_t len, struct text_stat *stats,
@@@ -290,7 -299,7 +299,7 @@@ static int crlf_to_git(const struct ind
                 * cherry-pick.
                 */
                if ((checksafe != SAFE_CRLF_RENORMALIZE) &&
-                   has_cr_in_index(istate, path))
+                   has_crlf_in_index(istate, path))
                        convert_crlf_into_lf = 0;
        }
        if ((checksafe == SAFE_CRLF_WARN ||
@@@ -423,10 -432,8 +432,10 @@@ static int filter_buffer_or_fd(int in, 
        child_process.in = -1;
        child_process.out = out;
  
 -      if (start_command(&child_process))
 +      if (start_command(&child_process)) {
 +              strbuf_release(&cmd);
                return error("cannot fork to run external filter '%s'", params->cmd);
 +      }
  
        sigchain_push(SIGPIPE, SIG_IGN);
  
@@@ -566,7 -573,8 +575,7 @@@ static int apply_multi_file_filter(cons
  
        if (!subprocess_map_initialized) {
                subprocess_map_initialized = 1;
 -              hashmap_init(&subprocess_map, (hashmap_cmp_fn) cmd2process_cmp,
 -                           NULL, 0);
 +              hashmap_init(&subprocess_map, cmd2process_cmp, NULL, 0);
                entry = NULL;
        } else {
                entry = (struct cmd2process *)subprocess_find_entry(&subprocess_map, cmd);
@@@ -1545,9 -1553,8 +1554,9 @@@ static int ident_filter_fn(struct strea
                switch (ident->state) {
                default:
                        strbuf_add(&ident->left, head, ident->state);
 +                      /* fallthrough */
                case IDENT_SKIPPING:
 -                      /* fallthru */
 +                      /* fallthrough */
                case IDENT_DRAINING:
                        ident_drain(ident, &output, osize_p);
                }
diff --combined t/t0027-auto-crlf.sh
index 68108d956a3f65c868b08ecb81bae87e9c1f5e67,71298960011dfbab828e1b27b4b37fe79e6fce5a..beb5927f77f7f21456eef2835ee67402e487a899
@@@ -43,19 -43,31 +43,31 @@@ create_gitattributes () 
        } >.gitattributes
  }
  
- create_NNO_files () {
+ # Create 2 sets of files:
+ # The NNO files are "Not NOrmalized in the repo. We use CRLF_mix_LF and store
+ #   it under different names for the different test cases, see ${pfx}
+ #   Depending on .gitattributes they are normalized at the next commit (or not)
+ # The MIX files have different contents in the repo.
+ #   Depending on its contents, the "new safer autocrlf" may kick in.
+ create_NNO_MIX_files () {
        for crlf in false true input
        do
                for attr in "" auto text -text
                do
                        for aeol in "" lf crlf
                        do
-                               pfx=NNO_attr_${attr}_aeol_${aeol}_${crlf}
+                               pfx=NNO_attr_${attr}_aeol_${aeol}_${crlf} &&
                                cp CRLF_mix_LF ${pfx}_LF.txt &&
                                cp CRLF_mix_LF ${pfx}_CRLF.txt &&
                                cp CRLF_mix_LF ${pfx}_CRLF_mix_LF.txt &&
                                cp CRLF_mix_LF ${pfx}_LF_mix_CR.txt &&
-                               cp CRLF_mix_LF ${pfx}_CRLF_nul.txt
+                               cp CRLF_mix_LF ${pfx}_CRLF_nul.txt &&
+                               pfx=MIX_attr_${attr}_aeol_${aeol}_${crlf} &&
+                               cp LF          ${pfx}_LF.txt &&
+                               cp CRLF        ${pfx}_CRLF.txt &&
+                               cp CRLF_mix_LF ${pfx}_CRLF_mix_LF.txt &&
+                               cp LF_mix_CR   ${pfx}_LF_mix_CR.txt &&
+                               cp CRLF_nul    ${pfx}_CRLF_nul.txt
                        done
                done
        done
@@@ -136,6 -148,49 +148,49 @@@ commit_chk_wrnNNO () 
        '
  }
  
+ # Commit a file with mixed line endings on top of different files
+ # in the index. Check for warnings
+ commit_MIX_chkwrn () {
+       attr=$1 ; shift
+       aeol=$1 ; shift
+       crlf=$1 ; shift
+       lfwarn=$1 ; shift
+       crlfwarn=$1 ; shift
+       lfmixcrlf=$1 ; shift
+       lfmixcr=$1 ; shift
+       crlfnul=$1 ; shift
+       pfx=MIX_attr_${attr}_aeol_${aeol}_${crlf}
+       #Commit file with CLRF_mix_LF on top of existing file
+       create_gitattributes "$attr" $aeol &&
+       for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
+       do
+               fname=${pfx}_$f.txt &&
+               cp CRLF_mix_LF $fname &&
+               printf Z >>"$fname" &&
+               git -c core.autocrlf=$crlf add $fname 2>"${pfx}_$f.err"
+       done
+       test_expect_success "commit file with mixed EOL onto LF crlf=$crlf attr=$attr" '
+               check_warning "$lfwarn" ${pfx}_LF.err
+       '
+       test_expect_success "commit file with mixed EOL onto CLRF attr=$attr aeol=$aeol crlf=$crlf" '
+               check_warning "$crlfwarn" ${pfx}_CRLF.err
+       '
+       test_expect_success "commit file with mixed EOL onto CRLF_mix_LF attr=$attr aeol=$aeol crlf=$crlf" '
+               check_warning "$lfmixcrlf" ${pfx}_CRLF_mix_LF.err
+       '
+       test_expect_success "commit file with mixed EOL onto LF_mix_cr attr=$attr aeol=$aeol crlf=$crlf " '
+               check_warning "$lfmixcr" ${pfx}_LF_mix_CR.err
+       '
+       test_expect_success "commit file with mixed EOL onto CRLF_nul attr=$attr aeol=$aeol crlf=$crlf" '
+               check_warning "$crlfnul" ${pfx}_CRLF_nul.err
+       '
+ }
  stats_ascii () {
        case "$1" in
        LF)
@@@ -315,7 -370,7 +370,7 @@@ test_expect_success 'setup master' 
        echo >.gitattributes &&
        git checkout -b master &&
        git add .gitattributes &&
 -      git commit -m "add .gitattributes" "" &&
 +      git commit -m "add .gitattributes" . &&
        printf "\$Id: 0000000000000000000000000000000000000000 \$\nLINEONE\nLINETWO\nLINETHREE"     >LF &&
        printf "\$Id: 0000000000000000000000000000000000000000 \$\r\nLINEONE\r\nLINETWO\r\nLINETHREE" >CRLF &&
        printf "\$Id: 0000000000000000000000000000000000000000 \$\nLINEONE\r\nLINETWO\nLINETHREE"   >CRLF_mix_LF &&
        printf "\$Id: 0000000000000000000000000000000000000000 \$\r\nLINEONE\r\nLINETWO\rLINETHREE"   >CRLF_mix_CR &&
        printf "\$Id: 0000000000000000000000000000000000000000 \$\r\nLINEONEQ\r\nLINETWO\r\nLINETHREE" | q_to_nul >CRLF_nul &&
        printf "\$Id: 0000000000000000000000000000000000000000 \$\nLINEONEQ\nLINETWO\nLINETHREE" | q_to_nul >LF_nul &&
-       create_NNO_files CRLF_mix_LF CRLF_mix_LF CRLF_mix_LF CRLF_mix_LF CRLF_mix_LF &&
-       git -c core.autocrlf=false add NNO_*.txt &&
+       create_NNO_MIX_files &&
+       git -c core.autocrlf=false add NNO_*.txt MIX_*.txt &&
        git commit -m "mixed line endings" &&
        test_tick
  '
@@@ -385,6 -440,18 +440,18 @@@ test_expect_success 'commit files attr=
        commit_check_warn input "crlf" "LF_CRLF" ""        "LF_CRLF" "LF_CRLF" ""
  '
  
+ # Commit "CRLFmixLF" on top of these files already in the repo:
+ #                                         mixed     mixed     mixed       mixed       mixed
+ #                                         onto      onto      onto        onto        onto
+ #                 attr                    LF        CRLF      CRLFmixLF   LF_mix_CR   CRLFNUL
+ commit_MIX_chkwrn ""      ""      false   ""        ""        ""          ""          ""
+ commit_MIX_chkwrn ""      ""      true    "LF_CRLF" ""        ""          "LF_CRLF"   "LF_CRLF"
+ commit_MIX_chkwrn ""      ""      input   "CRLF_LF" ""        ""          "CRLF_LF"   "CRLF_LF"
+ commit_MIX_chkwrn "auto"  ""      false   "$WAMIX"  ""        ""          "$WAMIX"    "$WAMIX"
+ commit_MIX_chkwrn "auto"  ""      true    "LF_CRLF" ""        ""          "LF_CRLF"   "LF_CRLF"
+ commit_MIX_chkwrn "auto"  ""      input   "CRLF_LF" ""        ""          "CRLF_LF"   "CRLF_LF"
  #                 attr                    LF        CRLF      CRLFmixLF   LF_mix_CR   CRLFNUL
  commit_chk_wrnNNO ""      ""      false   ""        ""        ""          ""          ""
  commit_chk_wrnNNO ""      ""      true    LF_CRLF   ""        ""          ""          ""