Estou rastreando um arquivo de máquina virtual do Virtual PC (* .vmc) no git e, depois de fazer uma alteração, o git identificou o arquivo como binário e não o difere para mim. Descobri que o arquivo estava codificado em UTF-16.
O git pode ser ensinado a reconhecer que esse arquivo é texto e manipulá-lo adequadamente?
Estou usando o git no Cygwin, com core.autocrlf definido como false. Eu poderia usar mSysGit ou git no UNIX, se necessário.
Existe uma solução muito simples que funciona imediatamente no Unices.
Por exemplo, com os
.strings
arquivos da Apple apenas:Crie um
.gitattributes
arquivo na raiz do seu repositório com:Adicione o seguinte ao seu
~/.gitconfig
arquivo:Fonte: arquivos Diff .strings no Git (e post anterior de 2010).
fonte
iconv
é "outra ferramenta" da mesma maneira que o Vim ou Beyond Compare (não faz parte do pacote git).vimdiff
eiconv
são ambos já presente no MacOS, assim você não precisa se preocupar perguntando onde consegui-los, e eles fazem o trabalhoVocê já tentou definir o seu
.gitattributes
tratamento como um arquivo de texto?por exemplo:
Mais detalhes em http://www.git-scm.com/docs/gitattributes.html .
fonte
set
ediff
...*.vmc diff
,*.sql diff
etc .. é necessário para definir o atributo 'diff' para o caminho especificado. (Não consigo editar a resposta). No entanto, existem duas ressalvas: as diferenças são mostradas com um espaço entre cada caractere e não é possível "encenar o pedaço" ou "descartar o pedaço" para esses arquivos problemáticos.Por padrão, parece que
git
não funcionará bem com UTF-16; para esse arquivo, você precisa garantir que nenhumCRLF
processamento seja feito, mas desejadiff
emerge
funcione como um arquivo de texto normal (isso é ignorar se o seu terminal / editor pode ou não lidar com UTF-16).Mas, olhando para a página de
.gitattributes
manual , aqui está o atributo personalizado que ébinary
:Portanto, parece-me que você pode definir um atributo personalizado em seu nível superior
.gitattributes
parautf16
(observe que eu adiciono mesclagem aqui para garantir que seja tratado como texto):A partir daí, você poderá especificar em qualquer
.gitattributes
arquivo algo como:Observe também que você ainda pode conseguir
diff
um arquivo, mesmo quegit
pense que ele é binário com:Editar
Essa resposta basicamente diz que o GNU diff com UTF-16 ou mesmo UTF-8 não funciona muito bem. Se você quiser
git
usar uma ferramenta diferente para ver as diferenças (via--ext-diff
), essa resposta sugere Guiffy .Mas o que você provavelmente precisa é apenas para
diff
um arquivo UTF-16 que contenha apenas caracteres ASCII. Uma maneira de fazer isso funcionar é usar--ext-diff
o seguinte script de shell:Observe que a conversão para UTF-8 também pode funcionar para mesclagem, você só precisa garantir que isso seja feito nas duas direções.
Quanto à saída para o terminal ao examinar um diff de um arquivo UTF-16:
O diff do GNU realmente não se importa com o unicode, portanto, quando você usa o diff --text, ele apenas difere e gera o texto. O problema é que o terminal que você está usando não suporta o UTF-16 emitido (combinado com as marcas diff que são caracteres ASCII).
fonte
A solução é filtrar
cmd.exe /c "type %1"
. Otype
builtin do cmd fará a conversão e, portanto, você pode usá-lo com a capacidade de conversão de texto do git diff para ativar a difusão de texto dos arquivos UTF-16 (deve funcionar com o UTF-8 também, embora não tenha sido testado).Citando a página de manual gitattributes:
Executando diferenças de texto de arquivos binários
Às vezes, é desejável ver o diff de uma versão convertida em texto de alguns arquivos binários. Por exemplo, um documento do processador de texto pode ser convertido em uma representação de texto ASCII e no diff do texto mostrado. Mesmo que essa conversão perca algumas informações, o diff resultante é útil para visualização humana (mas não pode ser aplicado diretamente).
A opção de configuração textconv é usada para definir um programa para realizar essa conversão. O programa deve usar um único argumento, o nome de um arquivo a ser convertido e produzir o texto resultante no stdout.
Por exemplo, para mostrar o diff das informações exif de um arquivo em vez das informações binárias (supondo que você tenha a ferramenta exif instalada), adicione a seguinte seção ao seu
$GIT_DIR/config
arquivo (ou$HOME/.gitconfig
arquivo):Uma solução para os fãs do mingw32 , cygwin, pode ter que alterar a abordagem. O problema é passar o nome do arquivo para converter em cmd.exe - ele estará usando barras invertidas e o cmd assume separadores de diretório de barra invertida.
Passo 1:
Crie o script de argumento único que fará a conversão em stdout. c: \ caminho \ para \ algum \ script.sh:
Passo 2:
Configure o git para poder usar o arquivo de script. Dentro de sua git config (
~/.gitconfig
ou.git/config
ou verman git-config
), coloque isso:Etapa 3:
Aponte os arquivos aos quais aplicar esta solução alternativa utilizando arquivos .gitattributes (consulte man gitattributes (5)):
depois use
git diff
em seus arquivos.fonte
cmd //c type "${1//\//\\}"
.textconv = powershell -NoProfile -Command \"& {Get-Content \\$args[0]}\"
O git começou recentemente a entender codificações como utf16. Consulte os documentos gitattributes , pesquise por
working-tree-encoding
[Verifique se a sua página de manual corresponde, pois é uma novidade!]
Se (digamos) o arquivo for UTF-16 sem BOM na máquina Windows, adicione-o ao
.gitattributes
arquivoSe UTF-16 (com bom) em * nix, faça-o:
(Substitua
*.vmc
com*.whatever
parawhatever
arquivos do tipo que você precisa para lidar com)Consulte: Suporte à codificação de árvore de trabalho "UTF-16LE-BOM" .
Adicionado mais tarde
Seguindo @Hackslash, pode-se achar que isso é insuficiente
Para obter boas diferenças de texto, você precisa
Colocando ambos os trabalhos também
Mas é sem dúvida
eol=...
implicatext
O problema
Git tem um atributo macro, o
binary
que significa-text -diff
. O oposto+text +diff
não está disponível, mas o git fornece as ferramentas (eu acho!) Para sintetizá-loA solução
O Git permite definir novos atributos de macro.
Eu proporia que o topo do
.gitattributes
arquivo que você temEntão, para todos os caminhos que precisam ser texto e diff
Observe que, na maioria dos casos, queremos a codificação padrão (utf-8) e o eol padrão (nativo), podendo ser descartados.
A maioria das linhas deve parecer
Por que não usar apenas diff?
Prático: Na maioria dos casos, queremos eol nativo. O que significa que não
eol=...
. Portantotext
, não será implícito e precisa ser explicitamente explicado.Conceitual: Texto versus binário é a distinção fundamental. eol, codificação, diff etc são apenas alguns aspectos.
aviso Legal
Devido aos tempos bizarros em que vivemos, não tenho uma máquina com um git atual. No momento, não consigo verificar a última adição. Se alguém encontrar algo errado, eu o emendarei / removerei.
fonte
*.vmc diff working-tree-encoding=UTF-16LE-BOM eol=CRLF
text
sozinho, você não obteve boas diferenças de texto? Você pode verificar isso com ambostext
ediff
tudo funciona bem? Nesse caso, farei uma recomendação diferentetext
sozinho , resulta em comparação binária. Eu posso fazerdiff
outext diff
e funciona. Eu precisava adicionar-BOM
simplesmente porque meu arquivo tinha uma BOM, YMMV.Eu escrevi um pequeno driver git-diff
to-utf8
, que deve facilitar a difusão de arquivos codificados que não sejam ASCII / UTF-8. Você pode instalá-lo usando as instruções aqui: https://github.com/chaitanyagupta/gitutils#to-utf8 (oto-utf8
script está disponível no mesmo repositório).Note que esse script exige tanto
file
eiconv
comandos para estar disponível no sistema.fonte
Recentemente, tive esse problema no Windows e as caixas
dos2unix
eunix2dos
fornecidas com o git for windows fizeram o truque. Por padrão, eles estão localizadosC:\Program Files\Git\usr\bin\
. Observe que isso só funcionará se seu arquivo não precisar ser UTF-16. Por exemplo, alguém acidentalmente codificou um arquivo python como UTF-16 quando não precisava (no meu caso).e
fonte