2010-09-16 100 views
7

可能重複鑑定爲二進制.sql擴展名:
Why does Mercurial think my SQL files are binary?文件與水銀

我產生了一整套用於在數據庫中的存儲過程的腳本。當我創建Mercurial存儲庫並添加這些文件時,它們都被添加爲二進制文件。很明顯,我仍然可以從版本控制中獲益,但是會損失很多文本文件的效率,差異等等。我證實這些文件確實都只是文本。

它爲什麼這樣做?

我該怎麼做才能避免它?

有沒有辦法讓Hg改變它對這些文件的思想?

這裏是變更日誌的一個片段:

496.1 Binary file SQL/SfiData/Stored Procedures/dbo.pFindCustomerByMatchCode.StoredProcedure.sql has changed 
    497.1 Binary file SQL/SfiData/Stored Procedures/dbo.pFindUnreconcilableChecks.StoredProcedure.sql has changed 
    498.1 Binary file SQL/SfiData/Stored Procedures/dbo.pFixBadLabelSelected.StoredProcedure.sql has changed 
    499.1 Binary file SQL/SfiData/Stored Procedures/dbo.pFixCCOPL.StoredProcedure.sql has changed 
    500.1 Binary file SQL/SfiData/Stored Procedures/dbo.pFixCCOrderMoneyError.StoredProcedure.sql has changed 

在此先感謝您的幫助 吉姆

+2

如果文件包含一個NUL字節,汞決定一個文件是二進制文件,這是這種情況嗎? – tonfa 2010-09-16 11:16:27

+1

哪個字符集使用這些.sql文件?一些字符集(如utf16和utf32)被識別爲二​​進制文件。 – Rudi 2010-09-16 11:47:52

回答

8

與Mercurial的views on binary files配件,它實際上並沒有跟蹤的文件類型,這意味着有沒有辦法讓用戶將文件標記爲二進制文件或不是二進制文件。

正如Tonfa和Rudi提到的,​​Mercurial通過查看文件中是否有NUL字節來確定文件是否爲二進制文件。在UTF- [16 | 32]文件的情況下,NUL字節幾乎得到保證。爲了「解決」這個問題,你必須確保文件是用UTF-8而不是UTF-16編碼的。理想情況下,您的數據庫在進行導出時應具有Unicode編碼設置。如果情況並非如此,另一種選擇是編寫一個預提交鉤子來執行它(請參閱How to convert a file to UTF-8 in Python的一開始),但您必須非常小心要轉換哪些文件。

+1

tghw有正確的答案,值得指出的是,「二進制」和「文本」文件在內部由mercurial處理相同。它們僅在合併工具(它們很容易配置)以及差異/傳入/傳出的用戶顯示內容上有所不同。實際的存儲和合並是相同的。 – 2010-09-16 14:06:40

+1

問題確實是Unicode編碼。數據庫導出只允許設置Unicode或ANSI。它沒有爲Unicode提供更明確的選擇。我將輸出更改爲ANSI,並獲得了我想要的行爲。 – 2010-09-16 14:18:45

+0

謝謝大家的幫助。 – 2010-09-16 14:20:58

7

我知道這有點晚了,但我正在評估窯並發現了這個問題。在與Fogbugz的人討論後,他們無法爲每個* .sql文件(非常單調乏味)向SSMS提供「File/Save As」以外的答案,於是我決定編寫一個快速腳本來轉換* .sql文件。

幸運的是,您可以使用一種Microsoft技術(Powershell)解決另一個Microsoft技術(SSMS)的問題 - 使用Powershell,更改到包含* .sql文件的目錄,然後複製並粘貼以下爲PowerShell的外殼(或保存爲名爲.ps1腳本和PowerShell中運行它 - 確保運行命令「set-ExecutionPolicy RemoteSigned就是」試圖運行一個腳本名爲.psl前):


function Get-FileEncoding 
{ 
    [CmdletBinding()] Param (
    [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)] [string]$Path 
) 

    [byte[]]$byte = get-content -Encoding byte -ReadCount 4 -TotalCount 4 -Path $Path 

    if ($byte[0] -eq 0xef -and $byte[1] -eq 0xbb -and $byte[2] -eq 0xbf) 
    { Write-Output 'UTF8' } 
    elseif ($byte[0] -eq 0xfe -and $byte[1] -eq 0xff) 
    { Write-Output 'Unicode' } 
    elseif ($byte[0] -eq 0xff -and $byte[1] -eq 0xfe) 
    { Write-Output 'Unicode' } 
    elseif ($byte[0] -eq 0 -and $byte[1] -eq 0 -and $byte[2] -eq 0xfe -and $byte[3] -eq 0xff) 
    { Write-Output 'UTF32' } 
    elseif ($byte[0] -eq 0x2b -and $byte[1] -eq 0x2f -and $byte[2] -eq 0x76) 
    { Write-Output 'UTF7'} 
    else 
    { Write-Output 'ASCII' } 
} 


$files = get-ChildItem "*.sql" 
foreach ($file in $files) 
{ 
$encoding = Get-FileEncoding $file 
If ($encoding -eq 'Unicode') 
    { 
    (Get-Content "$file" -Encoding Unicode) | Set-Content -Encoding UTF8 "$file" 
    } 
} 

函數Get-FileEncoding是由0123提供的雖然我不得不稍微修改它以迎合SSMS似乎將這些保存爲UC2的小端文件。我建議首先備份文件,因爲它會覆蓋原始文件 - 當然,您可以修改腳本,以便保存該文件的UTF-8版本,例如更改代碼的最後一行說:

(Get-Content "$file" -Encoding Unicode) | Set-Content -Encoding UTF8 "$file.new" 

腳本應該很容易修改,以橫過子目錄爲好。

現在只需要記住在提交併推送更改之前運行此操作,如果有任何新的* .sql文件。任何已經轉換並隨後在SSMS中打開的文件保存爲UTF-8。