2010-09-16 10 views
7

Duplicar posible:
Why does Mercurial think my SQL files are binary?archivos con extensión .sql identificado como binario en Mercurial

que genera un conjunto completo de secuencias de comandos para los procedimientos almacenados en una base de datos. Cuando creé un repositorio de Mercurial y agregué estos archivos, todos fueron agregados como binarios. Obviamente, sigo teniendo los beneficios del control de versiones, pero pierdo mucha eficiencia, "difamación", etc. de archivos de texto. Verifiqué que estos archivos son solo texto.

¿Por qué está haciendo esto?

¿Qué puedo hacer para evitarlo?

¿Hay alguna manera de hacer que Hg cambie de opinión acerca de estos archivos?

Aquí hay un fragmento del registro de cambios:

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 

Gracias de antemano por su ayuda Jim

+2

Hg decide que un archivo es binario si contiene un byte NUL, ¿es este el caso? – tonfa

+1

¿Qué juego de caracteres usa estos archivos .sql? Algunos conjuntos de caracteres (como utf16 y utf32) se reconocen como binarios. – Rudi

Respuesta

8

En conexión con Mercurial views on binary files, en realidad no realizar un seguimiento de los tipos de archivos, lo que significa que hay no hay forma de que un usuario marque un archivo como binario o no binario.

Como mencionaron Tonfa y Rudi, Mercurial determina si un archivo es binario o no al ver si hay un byte NUL en alguna parte del archivo. En el caso de los archivos UTF- [16 | 32], un byte NUL está prácticamente garantizado.

Para "corregir" esto, debe asegurarse de que los archivos estén codificados con UTF-8 en lugar de UTF-16. Idealmente, su base de datos tendría una configuración para la codificación Unicode al hacer la exportación. Si ese no es el caso, otra opción sería escribir un enlace precommitting para hacerlo (ver How to convert a file to UTF-8 in Python para empezar), pero tendría que tener mucho cuidado con los archivos que estaba convirtiendo.

+1

tghw tiene la respuesta correcta, vale la pena señalar explícitamente que los archivos "binarios" y "de texto" se manejan de forma idéntica por mercurial internamente. Solo difieren en las herramientas de combinación que lanzarán (que se configura fácilmente) y lo que se muestra a los usuarios en diff/entrante/saliente. El almacenamiento y la fusión real es el mismo. –

+1

El problema era de hecho la codificación Unicode. La exportación de db solo permite configurar Unicode o ANSI. No dio más opciones explícitas para Unicode. Cambié la salida a ANSI y obtuve el comportamiento que quería. –

+0

Gracias a todos por su ayuda. –

7

Sé que es un poco tarde, pero estaba evaluando el horno y me encontré con este problema. Después de discutir con los chicos de Fogbugz que no podían darme una respuesta que no fuera "Archivo/Guardar como" de SSMS por cada archivo * .sql (muy tedioso), decidí echar un vistazo a escribir un guión rápido para convertir el * .sql archivos.

Afortunadamente puede usar una tecnología de Microsoft (Powershell) para (más o menos) solucionar un problema con otra tecnología de Microsoft (SSMS) - usando Powershell, cambiar al directorio que contiene sus archivos * .sql y luego copiar y pegar siguiente en la cáscara Powershell (o guardar como un script .ps1 y ejecutarlo desde Powershell - asegúrese de ejecutar el comando "Set-ExecutionPolicy RemoteSigned" antes de intentar ejecutar un script .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" 
    } 
} 

La función Get-FileEncoding es cortesía de http://poshcode.org/3227 aunque tuve que modificarlo ligeramente para abastecer los archivos little endian de la UC2 que SSMS parece haber guardado como estos. Yo recomendaría hacer una copia de seguridad de sus archivos primero, ya que sobrescribe el original; por supuesto, podría modificar el script para que guarde una versión UTF-8 del archivo, por ejemplo,cambiar la última línea de código que decir:

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

El guión debe ser fácil de modificar para atravesar los subdirectorios también.

Ahora solo necesita recordar ejecutar esto si hay nuevos archivos * .sql, antes de comprometerse e impulsar sus cambios. Cualquier archivo ya convertido y posteriormente abierto en SSMS permanecerá como UTF-8 cuando se guarde.

Cuestiones relacionadas