2012-03-28 23 views
31

我很滿意Git如何通過core.autocrlf,core.eol + gitattributes(Tim's post is excellent)處理行結束符。git-svn如何處理行尾?

我有一個Windows Git回購,它有autocrlf設置爲true。因此,所有文本文件都以LF的形式存儲在回購站中,並且以工作目錄CRLF居住。這個回購是從一個SVN repo中克隆出來的,我們仍然使用它來推/拉(SVN回購是我們中心的,用於觸發CI的中心回購)。

但我不知道git-svn在推/拉操作過程中如何處理行結束符。

任何人都可以解釋什麼git-svn在這種情況下呢?

回答

15

我也對此感興趣。假設你有一個被通過的git的svn克隆創造了一個回購協議,我想你可以把它分成三個不同的問題:

  1. 是否有任何混帳換行符規範化/變更發生在混帳SVN提取時間,從SVN移動提交到git回購?
  2. 是否有任何git換行標準化/改變發生在git commit time [即在一個正常的本地git提交與svn遙控回購]?合併/重新啓動時間如何?
  3. 在git svn dcommit時間發生任何git換行標準化/變更,推送/重播/ git提交svn的任何內容嗎?

我喜歡聽到什麼理論上應該對這些問題是真實的,但現在我做了一個小實驗,這似乎表明,在情況#1至少不換行正常化:

rem We'll make a svn repo with CRLF newlines, clone it into git with 
rem autocrlf enabled, and try to see if that results in LF-only newlines 
rem getting stored in the git repo 

cd c:\code 

rem Step 1. Prepare SVN repo with CRLF type newlines. 
rem The pre-1.4 flag is to prevent an error during git clone. 

svnadmin create --pre-1.4-compatible svnrepo 
svn checkout file:///C:/code/svnrepo svnworking 
cd svnworking 
echo "First line" > file.txt 
echo "Second line" >> file.txt 
echo "Third line" >> file.txt 
rem NOTE: At this point file.txt has CRLF newlines 
svn add file.txt 
svn commit -m "Add file.txt" 
rem NOTE: At this point file.txt still has CRLF newlines 
cd .. 

rem Step 2. Clone the svn repo into git and inspect work copy newline type 
git svn clone file:///C:/code/svnrepo gitrepo 
rem The following outputs true on my machine 
git config --get core.autocrlf 
cd gitrepo 
rem The following also outputs true on my machine 
git config --get core.autocrlf 
git svn fetch 
rem NOTE: At this point file.txt (git working dir copy) has CRLF newlines 

rem Step 3. Disable autocrlf to inspect repo's inner newline type 
rem Use the following and my editor to set core.autocrlf to false: 
git config --edit --local 
rem This now prints false: 
git config --get core.autocrlf 
git checkout . 
rem NOTE: At this point file.txt (git working dir copy) still has CRLF newlines 
del file.txt 
git checkout . 
rem NOTE: Even after explicitly deleting the old one and checking out again, 
rem file.txt still has CRLF newlines 

如果git newline轉換髮生在我的git svn pull中,相反,那麼我希望file.txt在所有這些結尾處都有僅帶LF的換行符。

這裏有一個全面的檢查上面步驟3實際實現的回購是否有LF-只有換行符有效的測試:

rem We'll a git repo with core.autocrlf on, then switch it off to 
rem pull out a file 

rem The following outputs true 
git config --get core.autocrlf 
git init gitcrtest 
cd gitcrtest 
rem The following still outputs true 
git config --get core.autocrlf 
echo "First line" > file.txt 
echo "Second line" >> file.txt 
echo "Third line" >> file.txt 
git add file.txt 
git commit -m "Add file.txt" 
rem NOTE: At this point file.txt (git working dir copy) has CRLF newlines 
rem Use the following to set core.autocrlf to false 
git config --edit --local 
git checkout . 
rem NOTE: Now file.txt (git working dir copy) has LF-only newlines 

總結:基於上述,看來,當混帳SVN拉從svn開始,即使啓用了autocrlf,svn提交也會被添加到git commit圖中,而不會進行任何crlf轉換。也就是說,無論您的文件在svn repo中有哪些類型的換行符,它們也會在您的git克隆中擁有。 (但你的git 工作副本可能有不同的換行符類型。)

請注意,這與「git幫助屬性」中關於行結束標準化的討論非常一致。那裏的規範化是作爲一些事情發生的,這些命令通過將回調內容從工作目錄(例如結賬或合併)或者將工作目錄移動到索引/回購(例如添加或提交)的命令進行。 「Git svn fetch」似乎沒有做這兩件事情,所以當時沒有結束標準化會發生是有道理的。我對dcommit的做法模糊不清,所以我不確定當時是否需要結束行規範化。

請注意,如果SVN的svn:eol-style屬性設置在您的回購/機器上,則會出現額外的皺摺。我認爲 SVN的默認值是而不是在它的最後做了換行轉換,但我不是100%確定的。

更新:對於換行符上的真實svn-> git遷移透視圖,另請參閱Tim Abell's description。通過git-svn,CRLF換行符不會轉換爲僅LF的換行符,如果git的自動換行符標準化處於開啓狀態,那麼結果不理想。解決方案是在git中標準化行結尾或禁用行結束標準化。

+1

「我認爲SVN默認不會在其末尾執行換行轉換」根據http://svnbook.red-bean.com/en/1.7/svn.advanced.props的說法,這是正確的。 file-portability.html「,默認情況下,Subversion不會關注文件中使用的行尾標記(EOL)標記的類型。」 – 2018-01-24 11:23:48