Rewriting git history to make crlf consistent

I have a git repository that has an excellent variation of the LF and CRLF files.

Before making a possible switch, I want to rewrite the commit where the parent and current commit have different LR / CRLF encodings.

So, I tried the following โ€œsingle lineโ€ (slightly edited), where I try to run todos if the parent version of the file contains CR.

 $ git filter-branch --tree-filter ' echo P=$GIT_COMMIT^; FILES=$(git diff --name-only $P); for a in $FILES; do if ! git cat-file -e $P:$a; then echo "no parent"; continue; fi; if git show $:$a | grep -qUP '\r'; then echo "parent is dos"; todos $a; else echo "parent is unix"; fromdos $a; fi; done' 23498f..HEAD 

This does not work. Can someone detect an error or give a solution to this problem?

+4
source share
2 answers

I answer my question. The error in my original solution is that the FILES set is incorrect, since diff is not executed between the overwritten parent and the current commit, but between the original parent and the current commit.

When passing through a set of such commits, the files that need to be changed are not a set of files affected by the commit, but also a set of files in which some parent latches ruined the end of the line.

This means that I am not getting the correct set of files. There is a map function provided to filter expressions that can convert the โ€œoriginalโ€ revolution to a rewritten rev. When I use this function, it works correctly.

The resulting "single line" is as follows:

 $ git filter-branch -f --tree-filter ' echo "\n $GIT_COMMIT"; P=$(git rev-parse $GIT_COMMIT^); echo $P; P=$(map $P); echo $P; git cat-file commit $GIT_COMMIT; FILES=$(git diff --name-only $GIT_COMMIT $P); echo "FILES:\n$FILES"; for a in $FILES; do git cat-file -e $P:$a > /dev/null 2>&1 || continue; if git show $P:$a | grep -qUP '\r'; then echo "parent is dos $a"; todos $a; else echo "parent is unix $a"; fromdos $a; fi; done; git add $FILES;' a6d9e..HEAD 

Most aI doesn't think they need the last git add $ FILES ', but this is the command I used and I don't want to provide the wrong answer.

Note. You should also define FILES=$(git diff --name-only a6d9e HEAD) and, thus, use a fixed set to bypass commits. This is probably a lot easier, but I did not.

+2
source

Are you sure you want to rewrite the story?

Using the built-in configuration option helps make these things transparent. I did something similar to this, and over the past few years, working with people on Windows, Mac and Linux has not yet been resolved with the end of the line.

See Working with line endings from GitHub.

Here's what they have to say about configuration files:

Here is an example .gitattributes file, you can use it as a template for all your repositories:

 # Set default behaviour, in case users don't have core.autocrlf set. * text=auto # Explicitly declare text files we want to always be normalized and converted # to native line endings on checkout. *.c text *.h text # Declare files that will always have CRLF line endings on checkout. *.sln text eol=crlf # Denote all files that are truly binary and should not be modified. *.png binary *.jpg binary The advantage of this is that your end of line configuration now travels with your repository and you don't need to worry about whether or not collaborators have the proper global settings. 

They continue to talk about what you can do if you have the current repository and you need to apply these settings to it.

Repository normalization

After you set the core.autocrlf and .gitattributes parameter, you may find that git wants to commit files that you have not changed. This is because git wants to normalize the line for you. The best way to do this is to destroy the working tree (all files except the .git directory) and then restore them. Doing Make sure that you have done any work before you do it, or it will be lost.

 git rm --cached -r . # Remove everything from the index. git reset --hard # Write both the index and working directory from git database. git add . # Prepare to make a commit by staging all the files that will get normalized. # This is your chance to inspect which files were never normalized. You should # get lots of messages like: "warning: CRLF will be replaced by LF in file." git commit -m "Normalize line endings" # Commit 
+1
source

Source: https://habr.com/ru/post/1482103/


All Articles