convert: add 'working-tree-encoding' attribute
[git] / t / t0028-working-tree-encoding.sh
1 #!/bin/sh
2
3 test_description='working-tree-encoding conversion via gitattributes'
4
5 . ./test-lib.sh
6
7 test_expect_success 'setup test files' '
8         git config core.eol lf &&
9
10         text="hallo there!\ncan you read me?" &&
11         echo "*.utf16 text working-tree-encoding=utf-16" >.gitattributes &&
12         printf "$text" >test.utf8.raw &&
13         printf "$text" | iconv -f UTF-8 -t UTF-16 >test.utf16.raw &&
14         printf "$text" | iconv -f UTF-8 -t UTF-32 >test.utf32.raw &&
15
16         # Line ending tests
17         printf "one\ntwo\nthree\n" >lf.utf8.raw &&
18         printf "one\r\ntwo\r\nthree\r\n" >crlf.utf8.raw &&
19
20         # BOM tests
21         printf "\0a\0b\0c"                         >nobom.utf16be.raw &&
22         printf "a\0b\0c\0"                         >nobom.utf16le.raw &&
23         printf "\376\777\0a\0b\0c"                 >bebom.utf16be.raw &&
24         printf "\777\376a\0b\0c\0"                 >lebom.utf16le.raw &&
25         printf "\0\0\0a\0\0\0b\0\0\0c"             >nobom.utf32be.raw &&
26         printf "a\0\0\0b\0\0\0c\0\0\0"             >nobom.utf32le.raw &&
27         printf "\0\0\376\777\0\0\0a\0\0\0b\0\0\0c" >bebom.utf32be.raw &&
28         printf "\777\376\0\0a\0\0\0b\0\0\0c\0\0\0" >lebom.utf32le.raw &&
29
30         # Add only UTF-16 file, we will add the UTF-32 file later
31         cp test.utf16.raw test.utf16 &&
32         cp test.utf32.raw test.utf32 &&
33         git add .gitattributes test.utf16 &&
34         git commit -m initial
35 '
36
37 test_expect_success 'ensure UTF-8 is stored in Git' '
38         test_when_finished "rm -f test.utf16.git" &&
39
40         git cat-file -p :test.utf16 >test.utf16.git &&
41         test_cmp_bin test.utf8.raw test.utf16.git
42 '
43
44 test_expect_success 're-encode to UTF-16 on checkout' '
45         test_when_finished "rm -f test.utf16.raw" &&
46
47         rm test.utf16 &&
48         git checkout test.utf16 &&
49         test_cmp_bin test.utf16.raw test.utf16
50 '
51
52 test_expect_success 'check $GIT_DIR/info/attributes support' '
53         test_when_finished "rm -f test.utf32.git" &&
54         test_when_finished "git reset --hard HEAD" &&
55
56         echo "*.utf32 text working-tree-encoding=utf-32" >.git/info/attributes &&
57         git add test.utf32 &&
58
59         git cat-file -p :test.utf32 >test.utf32.git &&
60         test_cmp_bin test.utf8.raw test.utf32.git
61 '
62
63 for i in 16 32
64 do
65         test_expect_success "eol conversion for UTF-${i} encoded files on checkout" '
66                 test_when_finished "rm -f crlf.utf${i}.raw lf.utf${i}.raw" &&
67                 test_when_finished "git reset --hard HEAD^" &&
68
69                 cat lf.utf8.raw | iconv -f UTF-8 -t UTF-${i} >lf.utf${i}.raw &&
70                 cat crlf.utf8.raw | iconv -f UTF-8 -t UTF-${i} >crlf.utf${i}.raw &&
71                 cp crlf.utf${i}.raw eol.utf${i} &&
72
73                 cat >expectIndexLF <<-EOF &&
74                         i/lf    w/-text attr/text               eol.utf${i}
75                 EOF
76
77                 git add eol.utf${i} &&
78                 git commit -m eol &&
79
80                 # UTF-${i} with CRLF (Windows line endings)
81                 rm eol.utf${i} &&
82                 git -c core.eol=crlf checkout eol.utf${i} &&
83                 test_cmp_bin crlf.utf${i}.raw eol.utf${i} &&
84
85                 # Although the file has CRLF in the working tree,
86                 # ensure LF in the index
87                 git ls-files --eol eol.utf${i} >actual &&
88                 test_cmp expectIndexLF actual &&
89
90                 # UTF-${i} with LF (Unix line endings)
91                 rm eol.utf${i} &&
92                 git -c core.eol=lf checkout eol.utf${i} &&
93                 test_cmp_bin lf.utf${i}.raw eol.utf${i} &&
94
95                 # The file LF in the working tree, ensure LF in the index
96                 git ls-files --eol eol.utf${i} >actual &&
97                 test_cmp expectIndexLF actual
98         '
99 done
100
101 test_expect_success 'check unsupported encodings' '
102         test_when_finished "git reset --hard HEAD" &&
103
104         echo "*.set text working-tree-encoding" >.gitattributes &&
105         printf "set" >t.set &&
106         test_must_fail git add t.set 2>err.out &&
107         test_i18ngrep "true/false are no valid working-tree-encodings" err.out &&
108
109         echo "*.unset text -working-tree-encoding" >.gitattributes &&
110         printf "unset" >t.unset &&
111         git add t.unset &&
112
113         echo "*.empty text working-tree-encoding=" >.gitattributes &&
114         printf "empty" >t.empty &&
115         git add t.empty &&
116
117         echo "*.garbage text working-tree-encoding=garbage" >.gitattributes &&
118         printf "garbage" >t.garbage &&
119         test_must_fail git add t.garbage 2>err.out &&
120         test_i18ngrep "failed to encode" err.out
121 '
122
123 test_expect_success 'error if encoding round trip is not the same during refresh' '
124         BEFORE_STATE=$(git rev-parse HEAD) &&
125         test_when_finished "git reset --hard $BEFORE_STATE" &&
126
127         # Add and commit a UTF-16 file but skip the "working-tree-encoding"
128         # filter. Consequently, the in-repo representation is UTF-16 and not
129         # UTF-8. This simulates a Git version that has no working tree encoding
130         # support.
131         echo "*.utf16le text working-tree-encoding=utf-16le" >.gitattributes &&
132         echo "hallo" >nonsense.utf16le &&
133         TEST_HASH=$(git hash-object --no-filters -w nonsense.utf16le) &&
134         git update-index --add --cacheinfo 100644 $TEST_HASH nonsense.utf16le &&
135         COMMIT=$(git commit-tree -p $(git rev-parse HEAD) -m "plain commit" $(git write-tree)) &&
136         git update-ref refs/heads/master $COMMIT &&
137
138         test_must_fail git checkout HEAD^ 2>err.out &&
139         test_i18ngrep "error: .* overwritten by checkout:" err.out
140 '
141
142 test_done