Line endings messed up in Git - how to track changes from another branch after a huge line ending fix? Line endings messed up in Git - how to track changes from another branch after a huge line ending fix? git git

Line endings messed up in Git - how to track changes from another branch after a huge line ending fix?


I finally managed to solve it.

The answer is:

git filter-branch --tree-filter '~/Scripts/fix-line-endings.sh' -- --all

fix-line-endings.sh contains:

#!/bin/shfind . -type f -a \( -name '*.tpl' -o -name '*.php' -o -name '*.js' -o -name '*.css' -o -name '*.sh' -o -name '*.txt' -iname '*.html' \) | xargs fromdos

After all line endings were fixed in all trees in all commits, I did an interactive rebase and removed all commits that were fixing line endings.

Now my repo is clean and fresh, ready to be pushed :)

Note to visitors: do not do this if your repo has been pushed / cloned because it will mess things up badly!


Going forward, avoid this problem with the core.autocrlf setting, documented in git config --help:

core.autocrlf

If true, makes git convert CRLF at the end of lines in text files to LF when reading from the filesystem, and convert in reverse when writing to the filesystem. The variable can be set to input, in which case the conversion happens only while reading from the filesystem but files are written out with LF at the end of lines. A file is considered "text" (i.e. be subjected to the autocrlf mechanism) based on the file's crlf attribute, or if crlf is unspecified, based on the file's contents. See gitattributes.


Did you look at git rebase?

You will need to re-base the history of your repository, as follows:

  • commit the line terminator fixes
  • start the rebase
  • leave the third-party import commit first
  • apply the line terminator fixes
  • apply your other patches

What you do need to understand though is that this will break all downstream repositories - those that are cloned from your parent repo. Ideally you will start from scratch with those.


Update: sample usage:

target=`git rev-list --max-count=3 HEAD | tail -n1`get rebase -i $target

Will start a rebase session for the last 3 commits.