Windows: a test_cmp that is agnostic to random LF <> CRLF conversions
In a number of tests, output that was produced by a shell script is compared to expected output using test_cmp. Unfortunately, the MSYS bash-- when invoked via git, such as in hooks--converts LF to CRLF on output (as produced by echo and printf), which leads to many false positives. Implements a diff tool that undoes the converted CRLF. To avoid that sub-processes are spawned (which is very slow on Windows), the tool is implemented as a shell function. Diff is invoked as usual only when a difference is detected by the shell code. Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Johannes Sixt committed
Oct 26, 2013 at 21:17 UTC
4d715ac05cf5b800a98ce75bbc0cb3ea2dfe70ab
2 files changed
+67
t/test-lib-functions.sh
+66
@@ -710,3 +710,69 @@ test_ln_s_add () {
710
git update-index --add --cacheinfo 120000 $ln_s_obj "$2"
711
fi
712
}
713
+
714
+# The following mingw_* functions obey POSIX shell syntax, but are actually
715
+# bash scripts, and are meant to be used only with bash on Windows.
716
+
717
+# A test_cmp function that treats LF and CRLF equal and avoids to fork
718
+# diff when possible.
719
+mingw_test_cmp () {
720
+ # Read text into shell variables and compare them. If the results
721
+ # are different, use regular diff to report the difference.
722
+ local test_cmp_a= test_cmp_b=
723
+
724
+ # When text came from stdin (one argument is '-') we must feed it
725
+ # to diff.
726
+ local stdin_for_diff=
727
+
728
+ # Since it is difficult to detect the difference between an
729
+ # empty input file and a failure to read the files, we go straight
730
+ # to diff if one of the inputs is empty.
731
+ if test -s "$1" && test -s "$2"
732
+ then
733
+ # regular case: both files non-empty
734
+ mingw_read_file_strip_cr_ test_cmp_a <"$1"
735
+ mingw_read_file_strip_cr_ test_cmp_b <"$2"
736
+ elif test -s "$1" && test "$2" = -
737
+ then
738
+ # read 2nd file from stdin
739
+ mingw_read_file_strip_cr_ test_cmp_a <"$1"
740
+ mingw_read_file_strip_cr_ test_cmp_b
741
+ stdin_for_diff='<<<"$test_cmp_b"'
742
+ elif test "$1" = - && test -s "$2"
743
+ then
744
+ # read 1st file from stdin
745
+ mingw_read_file_strip_cr_ test_cmp_a
746
+ mingw_read_file_strip_cr_ test_cmp_b <"$2"
747
+ stdin_for_diff='<<<"$test_cmp_a"'
748
+ fi
749
+ test -n "$test_cmp_a" &&
750
+ test -n "$test_cmp_b" &&
751
+ test "$test_cmp_a" = "$test_cmp_b" ||
752
+ eval "diff -u \"\$@\" $stdin_for_diff"
753
+}
754
+
755
+# $1 is the name of the shell variable to fill in
756
+mingw_read_file_strip_cr_ () {
757
+ # Read line-wise using LF as the line separator
758
+ # and use IFS to strip CR.
759
+ local line
760
+ while :
761
+ do
762
+ if IFS=$'\r' read -r -d $'\n' line
763
+ then
764
+ # good
765
+ line=$line$'\n'
766
+ else
767
+ # we get here at EOF, but also if the last line
768
+ # was not terminated by LF; in the latter case,
769
+ # some text was read
770
+ if test -z "$line"
771
+ then
772
+ # EOF, really
773
+ break
774
+ fi
775
+ fi
776
+ eval "$1=\$$1\$line"
777
+ done
778
+}
t/test-lib.sh
+1
@@ -817,6 +817,7 @@ case $(uname -s) in
817
test_set_prereq NOT_CYGWIN
818
test_set_prereq SED_STRIPS_CR
819
test_set_prereq GREP_STRIPS_CR
820
+ GIT_TEST_CMP=mingw_test_cmp
821
;;
822
*CYGWIN*)
823
test_set_prereq POSIXPERM