Search code examples
git.htaccesswebpackgzipbrotli

Git force push files which git does not know changed?


I was fiddling with PageSpeed Insights which lead me to compress css and js files in Webpack to .br (compressed with Brotli) and .gz (compressed with gzip) so they can be served to browsers that accept them. .htaccess makes the decision.

Since .htaccess makes the decision, I had to use AddType close. Since .htaccess does not work with multi-extension filenames, I had to make a cutom extension, namely cssbr, cssgz, jsbr and jsgz. In .htaccess they are recognized just fine:

AddEncoding gzip .jsgz .cssgz
AddType application/javascript .jsgz
AddType text/css .cssgz

AddEncoding br .jsbr .cssbr
AddType application/javascript .jsbr
AddType text/css .cssbr

This generally works. There is also a fallback in plain css and js for browsers that cannot use compressed files. When I make changes and use webpack to update the files, everything works. But when I checkout to another branch and merge, git considers my custom files unchanged. .css and .js work as expected, but for the .cssbr files the browser informs me it cannot decode them (ERROR_CONTENT_DECODING_FAILED). What I need to do to fix it is run webpack again and it works locally, but git will not commit the changes as it seems the files as unchanged. I tried deleting them and readding.

TL;DR :

I have custom files that are considered unchanged when switching branches or committing.
I can go for solution from another angle, like change them to different extensions, but how to make .htaccess work with them then?

.htaccess for reference:

<IfModule mod_headers.c>
  # Serve brotli compressed CSS files if they exist and the client accepts br.
  RewriteCond %{HTTP:Accept-encoding} br
  RewriteRule ^(.*)assets/frontend/(.*)\.css $1assets/frontend/$2.cssbr [QSA,L,T=text/css,E=no-gzip:1]

  # Serve gzip compressed CSS files if they exist and the client accepts gzip.
  RewriteCond %{HTTP:Accept-encoding} gzip
  RewriteRule ^(.*)assets/frontend/(.*)\.css $1assets/frontend/$2.cssgz [QSA,L,T=text/css,E=no-gzip:1]

  # Serve brotli compressed JS files if they exist and the client accepts br.
  RewriteCond %{HTTP:Accept-encoding} br
  RewriteRule ^(.*)assets/frontend/(.*)\.js $1assets/frontend/$2.jsbr [QSA,L,T=text/javascript,E=no-gzip:1]

  # Serve gzip compressed JS files if they exist and the client accepts gzip.
  RewriteCond %{HTTP:Accept-encoding} gzip
  RewriteRule ^(.*)assets/frontend/(.*)\.js $1assets/frontend/$2.jsgz [QSA,L,T=text/javascript,E=no-gzip:1]

  # Serve correct content types, and prevent mod_deflate double gzip.
  RewriteRule \.css\.gz$ - [T=text/css,E=no-gzip:1]
  RewriteRule \.js\.gz$ - [T=text/javascript,E=no-gzip:1]
  RewriteRule \.css\.br$ - [T=text/css,E=no-gzip:1]
  RewriteRule \.js\.br$ - [T=text/javascript,E=no-gzip:1]

  <FilesMatch "(\.js\.gz|\.css\.gz)$">
    # Serve correct encoding type.
    Header set Content-Encoding gzip
    # Force proxies to cache gzipped & non-gzipped css/js files separately.
    Header append Vary Accept-Encoding
  </FilesMatch>
  <FilesMatch "(\.js\.br|\.css\.br)$">
    # Serve correct encoding type.
    Header set Content-Encoding br
    # Force proxies to cache gzipped & non-gzipped css/js files separately.
    Header append Vary Accept-Encoding
  </FilesMatch>
</IfModule>

Additional information: I use webpack to compress files, because doing it on the server would add time and defeat purpose for using compression in the first place, according to PageSpeed Insights


Solution

  • I found the solution. The problem was indeed in git, but it was in changing line endings.

    I am on windows, so git changes CRLF to LF which was breaking the files, as they were binary. What I needed to do was to add them as binary to .gitattributes like so:

    *.cssbr binary
    *.cssgz binary
    *.jsbr binary
    *.jsgz binary