From: Yann Droneaud Date: Fri, 21 Jun 2013 13:51:53 GMT Subject: Re: git rebase fail with CRLF conversion Message-ID: <6ae09e227e559a024d3ffa13570e81a2@meuh.org> In-Reply-To: Hi, Le 21.06.2013 15:41, Yann Droneaud a écrit : > > > I believe "git rebase" should not fail here, but more, it must not > fail in a different fashion randomly. > > Please find in reply to this email: > - a shell script to demonstrate the behavor Please find a shell script to test git rebase with .gitattributes text flag set to enable End-Of-Line (EOL) conversion from CRLF to LF, with core.safecrlf set to warn and to true. Regards. -- Yann Droneaud OPTEYA ----------------------------------8<---------------------------------- #! /bin/sh set -e LC_ALL=C export LC_ALL #GIT_AUTHOR_DATE=`date -R` GIT_AUTHOR_DATE="2001-01-01 00:00:00.+00:00" GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" export GIT_AUTHOR_DATE export GIT_COMMITTER_DATE # global settings set +e global_core_eol=`git config --global core.eol` global_core_safecrlf=`git config --global core.safecrlf` global_core_autocrlf=`git config --global core.autocrlf` set -e # archive if test -d work; then dir=`mktemp -d work.XXXXX` rmdir $dir mv work $dir fi mkdir work echo "****** Testing in work *******" cd work # prepare git init git commit --allow-empty -m "empty root commit" # local settings, might be different from the global settings set +e local_core_eol=`git config core.eol` local_core_safecrlf=`git config core.safecrlf` local_core_autocrlf=`git config core.autocrlf` set -e echo "global core.eol = $global_core_eol" echo "global core.safecrlf = $global_core_safecrlf" echo "global core.autocrlf = $global_core_autocrlf" echo "local core.eol = $local_core_eol" echo "local core.safecrlf = $local_core_safecrlf" echo "local core.autocrlf = $local_core_autocrlf" # set default configuration git config --local core.eol native git config --local core.safecrl warn git config --local core.autocrlf false echo "current core.eol = `git config core.eol`" echo "current core.safecrlf = `git config core.safecrlf`" echo "current core.autocrlf = `git config core.autocrlf`" CRLF="\r\n" CR="\r" LF="\n" # TODO detect line ending on the current environment if true ; then EOL=$LF else EOL=$CRLF fi echo "Create work branches" git branch import-raw master git branch import-eol master echo "Create a branch to be used as new root later" git checkout import-eol git commit --allow-empty -m "an empty commit" file_type= create_raw_file () { # Want to test mixed EOL: # printf "Hello World 1${CRLF}Hello World 2${CRLF}${CR}Hello World 3${CRLF}Hello World 4" > test printf "Hello World 1${CRLF}Hello World 2${CRLF}Hello World 3${CRLF}Hello World 4" > test file_type="`file test`" echo "::: $file_type" } check_file () { local t="`file test`" if test "x$file_type" != "x$t" ; then file_type="$t" echo "::: $file_type" fi } create_git_attributes () { printf "test text${EOL}" > .gitattributes } # # First test: # # import raw, add .gitattributes after, normalize, rebase # echo "===== BEGIN: first test =====" git checkout import-raw git reset --hard master create_raw_file git add test && check_file git commit -m "Commit raw" && check_file create_git_attributes && check_file git add .gitattributes && check_file git commit -m "Added git attributes" && check_file echo "--- First kind of 'normalization'" # # trick from https://help.github.com/articles/dealing-with-line-endings # git rm --cached test git reset --hard && check_file git add test && check_file git commit -m "Normalization" check_file git tag norm1 echo "--- Second kind of 'normalization'" git reset --hard HEAD^ check_file create_raw_file rm test git checkout test && check_file git add test && check_file git commit -m "Normalization" check_file git tag norm2 echo "--- Third kind of 'normalization'" git reset --hard HEAD^ check_file create_raw_file dos2unix test && check_file git add test && check_file git commit -m "Normalization" check_file git tag norm3 echo "--- differences ? ---" git diff norm1 norm2 git diff norm1 norm3 git diff norm2 norm1 git diff norm2 norm3 git diff norm3 norm1 git diff norm3 norm2 echo "--- rebase, should failed ---" git rebase import-eol || { echo "--- Expected failure to rebase on another branch ---" check_file git status git diff -w --stat git diff # just adding the file again and continue ... git add test && check_file git rebase --continue || { echo "### failed to continue rebase" ; exit 1 ; } check_file } echo "--- rebase complete ---" check_file echo "===== END: first test =====" # # again, with safecrlf set # echo "===== BEGIN: second test =====" git config core.safecrlf true git checkout import-raw git reset --hard master create_raw_file git add test && check_file git commit -m "Commit raw" && check_file create_git_attributes && check_file git add .gitattributes && check_file git commit -m "Added git attributes" && check_file echo "--- First kind of 'normalization', git add should failed" git rm --cached test git reset --hard && check_file git add test && { echo "### git add must failed !" ; exit 1 ; } echo "--- Second kind of 'normalization', git add should failed" rm test git checkout test && check_file git add test && { echo "### git add must failed !" ; exit 1 ; } echo "--- Third kind of 'normalization'" dos2unix test && check_file git add test && check_file git commit -m "Normalization" check_file echo "--- rebase, should failed ---" git rebase import-eol || { echo "--- Expected failure to rebase on another branch ---" check_file git status set +e git diff -w --stat || echo "!? git diff return an error !?" git diff || echo "!? git diff return an error !?" set -e git add test && { echo "### git add must failed !" ; exit 1 ; } dos2unix test && check_file git add test && check_file git status git rebase --continue || { echo "### failed to continue rebase" ; exit 1 ; } check_file } echo "--- rebase complete ---" check_file echo "===== END: second test =====" # # the way around: # first .gitattributes, then the file with CRLF (with safecrlf unset) # echo "===== BEGIN: third test =====" git config core.safecrlf false git checkout import-raw git reset --hard master create_git_attributes git add .gitattributes git commit -m "Added git attributes" create_raw_file git add test && check_file git commit -m "Commit raw" && check_file echo "--- First kind of 'normalization', git commit should failed" git rm --cached test git reset --hard && check_file git add test && check_file git commit -m "Normalization" && { echo "### git commit should failed here !" ; exit 1 ; } check_file echo "--- Second kind of 'normalization', git commit should failed" rm test git checkout test && check_file git add test && check_file git commit -m "Normalization" && { echo "### git commit should failed here !" ; exit 1 ; } check_file echo "--- Third kind of 'normalization', git commit should failed" dos2unix test && check_file git add test && check_file git commit -m "Normalization" && { echo "### git commit should failed here !" ; exit 1 ; } check_file echo "--- rebase, should failed ---" git rebase import-eol || { echo "--- Expected failure to rebase on another branch ---" check_file git status git diff -w --stat git diff # just adding the file again and continue ... git add test && check_file git rebase --continue || { echo "### failed to continue rebase" ; exit 1 ; } check_file } echo "--- rebase complete ---" check_file echo "===== END: third test =====" # # the way around # first .gitattributes, then the file with CRLF (with safecrlf set to true) # echo "===== BEGIN: fourth test =====" git config core.safecrlf true git checkout import-raw git reset --hard master create_git_attributes git add .gitattributes git commit -m "Added git attributes" create_raw_file # with safecrlf set to true, it's impossible to add the file with CRLF. git add test && { echo "### git add should failed here !" ; exit 1 ; } dos2unix test && check_file git add test && check_file git commit -m "Commit raw" && check_file echo "--- rebase, should failed ---" git rebase import-eol || { echo "--- Expected failure to rebase on another branch ---" check_file git status git diff -w --stat git diff # just adding the file again and continue ... git add test && check_file git rebase --continue || { echo "### failed to continue rebase" ; exit 1 ; } check_file } echo "--- rebase complete ---" check_file echo "===== END: fourth test =====" exit 0 ----------------------------------8<----------------------------------