Tại sao git nghĩ rằng tệp .sql của tôi là một tệp nhị phân?


84

Tôi có một số tệp .sql mà lần đầu tiên tôi được đẩy lên github. Tuy nhiên, khi tôi nhìn vào cam kết, nó nói:

BIN  WebRole/Sql/Database.sql View
Binary file not shown

Ai đó có thể cho tôi biết tại sao nó nói "Tệp nhị phân không được hiển thị"


Câu trả lời:


98

Chỉ riêng phần mở rộng là không đủ để GitHub biết liệu nó có phải là một tệp văn bản hay không.
Vì vậy, nó phải nhìn vào nội dung của nó.

Và như đã đề cập trong " Tại sao Git coi tệp văn bản này là tệp nhị phân? ", Nội dung của nó có thể không bao gồm đủ ký tự ascii để đoán nó là tệp văn bản.

Bạn có thể sử dụng tệp .gitattributes để chỉ định rõ ràng a .sqlphải là văn bản, không phải là nhị phân.

*.sql diff

Cập nhật 2018: như tôi đã đề cập trong " Mã hóa Utf-8 không hoạt động trên tài liệu được mã hóa utf-8 ", Git 2.18 .gitattributes có một working-tree-encodingthuộc tính mới .
Vì vậy, như thể hiện trong câu trả lời của Rusi :

*.sql text working-tree-encoding=UTF-16LE eol=CRLF

Như kostix bổ sung trong các nhận xét :

nếu các tệp này được tạo bởi Microsoft SQL Management Studio (hoặc bất cứ thứ gì nó được gọi trong phiên bản công cụ quản lý của MS SQL Server bạn đang sử dụng), thì các tệp mà nó lưu được mã hóa bằng UCS-2 (hoặc UTF-16) - a mã hóa hai byte, thực sự không phải là văn bản trong mắt của Git

Bạn có thể xem một ví dụ trong " Git nói" Binary files a… and b… differ"bật cho *.regtệp "

Như đã đề cập trong " Đặt tệp là không nhị phân trong git ":

"Tại sao Git đánh dấu tệp của tôi là tệp nhị phân?" Câu trả lời là vì nó nhìn thấy một byte NUL (0) ở đâu đó trong 8000 ký tự đầu tiên của tệp.
Thông thường, điều đó xảy ra vì tệp đang được lưu dưới dạng thứ gì đó khác với UTF-8. Vì vậy, nó có thể được lưu dưới dạng UCS-2, UCS-4, UTF-16 hoặc UTF-32. Tất cả chúng đều có ký tự NUL được nhúng khi sử dụng ký tự ASCII


Như Neo đã đề cập trong các nhận xét (và trong Tại sao Git coi tệp văn bản này là tệp nhị phân? ):

Bạn có thể thay đổi mã hóa của tệp đã lưu trong SSMS thành UTF-8 bằng cách chọn mã hóa 'UTF-8 có chữ ký' từ mục menu 'Tùy chọn Lưu Nâng cao' trong menu Tệp.


18
@Alan, nếu các tệp này được tạo bởi Microsoft SQL Management Studio (hoặc bất kỳ tệp nào được gọi trong phiên bản công cụ quản lý của MS SQL Server bạn đang sử dụng), các tệp mà nó lưu được mã hóa bằng UCS-2 (hoặc UTF-16) - một mã hóa hai byte, mà thực sự không phải là văn bản trong mắt của Git.
kostix

16
Bạn có thể thay đổi mã hóa của tệp đã lưu trong SSMS thành UTF-8 bằng cách chọn mã hóa 'UTF-8 có chữ ký' từ mục menu 'Tùy chọn Lưu Nâng cao' trong menu Tệp. Nguồn: stackoverflow.com/a/21170043/197591
Neo

2
@Neo Điểm tốt. Tôi đã bao gồm bình luận của bạn trong câu trả lời để hiển thị nhiều hơn.
VonC

7
Một mẹo nhỏ khác, nếu bạn đang chạy Git Bash trong Windows và không muốn ghi đè lên bất kỳ thay đổi nào bạn đã thực hiện đối với tệp, chỉ cần nhập "dos2unix * .sql". Điều đó sẽ chuyển đổi tất cả các tệp UCS2 thành UTF8, cho phép git nhận dạng văn bản.
Slothario

1
@thebfactor kiểm tra tùy chọn ' iso' của lệnh dos2unix đó để xem điều đó có giúp ích gì không: computerhope.com/unix/dos2unix.htm
VonC

9

Sử dụng câu trả lời được chấp nhận từ câu hỏi được liên kết và một số nhận xét khác, tôi đã đưa ra đây như một giải pháp cho vấn đề, đang hoạt động và chạy trên Win10

$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
Get-ChildItem -Recurse *.sql | foreach {
    $MyPath = $_.FullName;
    $Contents = Get-Content $MyPath
    [System.IO.File]::WriteAllLines($MyPath, $Contents, $Utf8NoBomEncoding)
}

1
Hấp dẫn. Tôi hiểu bằng cách sử dụng Powershell. +1
VonC

Get-Content cần một cờ trong trường hợp của tôi để đối phó với dấu ngoặc vuông trong tên tệp (như [dbo]):$Contents = Get-Content -LiteralPath $MyPath
Jeremy Murray.

7

Câu hỏi cũ có một câu trả lời mới - git gần đây đã phát triển một lựa chọn working-tree-encodingchính xác vì những lý do này. Xem gitattributes tài liệu [Đảm bảo trang người đàn ông của bạn khớp vì trang này khá mới!]

Tìm hiểu mã hóa của tệp sql, ví dụ: với file

Nếu (giả sử) utf-16 của nó không có bom trên máy windows thì hãy thêm vào tệp gitattributes của bạn

*.sql text working-tree-encoding=UTF-16LE eol=CRLF

Nếu utf-16 ít endinan (có bom) làm cho nó

*.sql text working-tree-encoding=UTF-16 eol=CRLF

1
Hấp dẫn. Đã ủng hộ. Tôi đã tham khảo câu trả lời của bạn trong của tôi ( stackoverflow.com/a/28145968/6309 ). Tôi đã ghi lại thuộc tính mới vào tháng 5 năm 2018 cho Git 2.18: stackoverflow.com/a/50435869/6309
VonC

4

Đối với những người đang gặp khó khăn với vấn đề này trong SSMS cho 2008 R2 (vâng, vẫn còn!), Bạn có thể đặt mã hóa mặc định như sau:

  • Định vị thư mục C: \ Program Files (x86) \ Microsoft SQL Server \ 100 \ Tools \ Binn \ VSShell \ Common7 \ IDE \ SqlWorkbenchProjectItems \ Sql

Vị trí có thể khác nhau. Đây là thư mục được sử dụng theo cài đặt mặc định trên Windows 7 64-bit.

  • Tại vị trí này, thêm (hoặc chỉnh sửa) tệp SQL trống SQLFile.sql.

Điều này được sử dụng làm mẫu cho các tệp .SQL mới. Lưu nó bằng cách sử dụng mã hóa bạn yêu cầu (trong trường hợp của tôi là Windows-1252 với phần cuối dòng Windows). Mũi tên ở bên phải của nút 'Lưu' cho bạn lựa chọn mã hóa.

Bạn cần phối hợp mã hóa với nhóm phát triển của mình để tránh rắc rối giữa git và SSMS.


2
Tôi tìm thấy tệp này cho SSMS 2012 lúcC:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\SqlWorkbenchProjectItems\Sql
Aaron D

1
Và SSMS2016:C:\Program Files (x86)\Microsoft SQL Server\130\Tools\Binn\ManagementStudio\SqlWorkbenchProjectItems\Sql
Coxy

4

Đây là một cách giải quyết nhanh phù hợp với tôi, sử dụng SSMS 2012. Trong công cụ => tùy chọn => môi trường => cài đặt quốc tế, nếu bạn thay đổi ngôn ngữ từ "Tiếng Anh" thành "Giống như Microsoft Windows" (nó có thể nhắc bạn khởi động lại SSMS để các thay đổi có hiệu lực), nó sẽ không sử dụng UTF-16 làm mã hóa mặc định cho các tệp mới nữa- tất cả các tệp mới mà tôi tạo đều có Codepage 1252 (tệp => tùy chọn lưu nâng cao) bây giờ, là lược đồ mã hóa 8 bit và dường như không có vấn đề gì vớiGit Diff


1

Cách giải quyết vấn đề này là buộc tệp sử dụng mã hóa 8 bit. Bạn có thể chạy tập lệnh PowerShell này để thay đổi mã hóa của tất cả các tệp .SQL trong thư mục hiện tại và các thư mục con của nó.

Get-ChildItem -Recurse *.sql | foreach {
  $FileName = $_.FullName;
  [System.Io.File]::ReadAllText($FileName) | Out-File -FilePath $FileName -Encoding UTF8;
}

2
Tuy nhiên, một chiến lược vững chắc đã không loại bỏ điểm đánh dấu BOM đối với tôi, đó là thứ mà git coi là nhị phân. Thay vào đó, tôi đã sử dụng câu trả lời cho Sử dụng PowerShell để viết một tập tin trong UTF-8 mà không BOM trong đó sử dụng[System.IO.File]::WriteAllLines($MyPath, $MyFile, $Utf8NoBomEncoding)
KyleMit
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.