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 toLF
when reading from the filesystem, and convert in reverse when writing to the filesystem. The variable can be set toinput
, in which case the conversion happens only while reading from the filesystem but files are written out withLF
at the end of lines. A file is considered "text" (i.e. be subjected to theautocrlf
mechanism) based on the file'scrlf
attribute, or ifcrlf
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.