2010-09-16 33 views
7

thể trùng lặp:
Why does Mercurial think my SQL files are binary?tập tin với phần mở rộng sql xác định là nhị phân trong Mercurial

tôi tạo ra một bộ hoàn chỉnh các kịch bản cho các thủ tục lưu trữ trong một cơ sở dữ liệu. Khi tôi tạo một kho lưu trữ Mercurial và thêm các tệp này, tất cả chúng đều được thêm dưới dạng nhị phân. Rõ ràng, tôi vẫn nhận được những lợi ích của phiên bản, nhưng mất rất nhiều hiệu quả, 'diff'ing, vv ... của các tập tin văn bản. Tôi đã xác minh rằng những tệp này thực sự chỉ là văn bản.

Tại sao lại thực hiện việc này?

Tôi có thể làm gì để tránh nó?

Có cách nào để Hg thay đổi ý định về những tệp này không?

Dưới đây là một đoạn ghi changeset:

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 

Cảm ơn trước sự giúp đỡ của bạn Jim

+2

Hg quyết định tệp là nhị phân nếu tệp chứa byte NUL, đây có phải là trường hợp không? – tonfa

+1

Bộ ký tự nào sử dụng các tệp .sql này? Một số bộ ký tự (như utf16 và utf32) được nhận dạng dưới dạng nhị phân. – Rudi

Trả lời

8

Trong phù hợp với Mercurial views on binary files, nó không thực sự theo dõi các loại tập tin, điều đó có nghĩa rằng có không có cách nào để người dùng đánh dấu một tệp là nhị phân hay không nhị phân.

Như tonfa và Rudi đã đề cập, Mercurial xác định xem tệp có nhị phân hay không bằng cách xem liệu có byte NUL ở bất kỳ đâu trong tệp hay không. Trong trường hợp tệp UTF- [16 | 32], một byte NUL được đảm bảo khá nhiều.

Để "khắc phục" điều này, bạn phải đảm bảo rằng các tệp được mã hóa bằng UTF-8 thay vì UTF-16. Lý tưởng nhất, cơ sở dữ liệu của bạn sẽ có một thiết lập cho mã hóa Unicode khi thực hiện xuất khẩu. Nếu đó không phải là trường hợp, một lựa chọn khác sẽ là viết một móc precommit để làm điều đó (xem How to convert a file to UTF-8 in Python để bắt đầu), nhưng bạn sẽ phải rất cẩn thận về những tập tin bạn đã chuyển đổi.

+1

tghw có câu trả lời đúng, nó đáng để chỉ ra một cách rõ ràng rằng các tệp "nhị phân" và "văn bản" được xử lý giống hệt nhau bằng cách mercurial nội bộ. Chúng chỉ khác nhau về những công cụ hợp nhất mà chúng sẽ khởi chạy (dễ dàng được cấu hình) và những gì hiển thị cho người dùng trên diff/incoming/outgoing. Việc lưu trữ và hợp nhất thực tế là như nhau. –

+1

Vấn đề thực sự là mã hóa Unicode. Xuất db chỉ cho phép cài đặt Unicode hoặc ANSI. Nó không đưa ra bất kỳ lựa chọn rõ ràng nào hơn cho Unicode. Tôi đã thay đổi đầu ra thành ANSI và nhận được hành vi mà tôi muốn. –

+0

Cảm ơn tất cả các bạn đã hỗ trợ. –

7

Tôi biết đã muộn một chút, nhưng tôi đã đánh giá Kiln và đã gặp phải vấn đề này. Sau khi thảo luận với những người ở Fogbugz, người không thể trả lời cho tôi ngoài "File/Save As" từ SSMS cho mọi tệp * .sql (rất tẻ nhạt), tôi quyết định xem một kịch bản nhanh để chuyển đổi * .sql tệp. May mắn thay, bạn có thể sử dụng một công nghệ của Microsoft (Powershell) để loại bỏ vấn đề với một công nghệ Microsoft khác (SSMS) - sử dụng Powershell, thay đổi thư mục chứa tệp * .sql của bạn và sau đó sao chép và dán sau vào vỏ Powershell (hoặc save as một kịch bản .ps1 và chạy nó từ Powershell - hãy chắc chắn để chạy lệnh "Set-ExecutionPolicy RemoteSigned" trước khi cố gắng để chạy một kịch bản .ps1):


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" 
    } 
} 

Chức năng Get-FileEncoding là lịch sự của http://poshcode.org/3227 mặc dù tôi đã phải sửa đổi nó một chút để phục vụ cho UC2 ​​ít tập tin cuối cùng mà SSMS dường như đã lưu chúng như. Tôi khuyên bạn nên sao lưu các tệp của mình trước tiên vì nó ghi đè lên tệp gốc - bạn có thể, tất nhiên, sửa đổi tập lệnh để nó lưu phiên bản UTF-8 của tệp thay vì, ví dụ:thay đổi dòng mã cuối cùng để nói:

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

Kịch bản cũng cần dễ dàng sửa đổi để duyệt qua các thư mục con.

Bây giờ bạn chỉ cần nhớ để chạy điều này nếu có bất kỳ tệp * .sql mới nào, trước khi bạn cam kết và đẩy các thay đổi của bạn. Bất kỳ tệp nào đã được chuyển đổi và sau đó được mở trong SSMS sẽ vẫn là UTF-8 khi được lưu.

Các vấn đề liên quan