web-dev-qa-db-fra.com

Puis-je faire git reconnaître un fichier UTF-16 comme du texte?

Je suis en train de suivre un fichier de machine virtuelle Virtual PC (* .vmc) dans git, et après avoir effectué une modification, git a identifié le fichier comme binaire et ne le différerait pas pour moi. J'ai découvert que le fichier était encodé en UTF-16.

Peut-on apprendre à git à reconnaître que ce fichier est du texte et à le gérer correctement?

J'utilise git sous Cygwin, avec core.autocrlf défini sur false. Je pourrais utiliser mSysGit ou git sous UNIX, si nécessaire.

130
skiphoppy

Je lutte avec ce problème depuis un certain temps et je viens de découvrir (pour moi) une solution parfaite:

$ git config --global diff.tool vimdiff      # or merge.tool to get merging too!
$ git difftool commit1 commit2

git difftool prend les mêmes arguments que git diff le ferait, mais exécute un programme de diff de votre choix au lieu du programme intégré GNU diff. Choisissez donc un diff compatible multi-octets (dans mon cas, vim en mode diff) et utilisez simplement git difftool au lieu de git diff.

Vous trouvez "difftool" trop long pour taper? Aucun problème:

$ git config --global alias.dt difftool
$ git dt commit1 commit2

Git rocks.

77
Sam Stokes

Il existe une solution très simple qui fonctionne par défaut sur Unices.

Par exemple, avec les fichiers .strings D'Apple:

  1. Créez un fichier .gitattributes À la racine de votre référentiel avec:

    *.strings diff=localizablestrings
    
  2. Ajoutez ce qui suit à votre fichier ~/.gitconfig:

    [diff "localizablestrings"]
    textconv = "iconv -f utf-16 -t utf-8"
    

Source: fichiers Diff .strings dans Git (et ancien article de 2010).

60
IlDan

Avez-vous essayé de définir votre .gitattributes pour le traiter comme un fichier texte?

par exemple.:

*.vmc diff

Plus de détails sur http://www.git-scm.com/docs/gitattributes.html .

37
Chealion

Par défaut, il semble que git ne fonctionne pas bien avec UTF-16; pour un tel fichier, vous devez vous assurer qu'aucun traitement CRLF n'est effectué dessus, mais vous voulez que diff et merge fonctionnent comme un fichier texte normal (ceci ignore si votre terminal/éditeur peut gérer UTF-16).

Mais en regardant le .gitattributes manpage , voici l'attribut personnalisé qui est binary:

[attr]binary -diff -crlf

Il me semble donc que vous pourriez définir un attribut personnalisé dans votre niveau supérieur .gitattributes pour utf16 (notez que j'ajoute fusion ici pour être sûr qu'il est traité comme du texte):

[attr]utf16 diff merge -crlf

De là, vous seriez en mesure de spécifier dans n'importe quel .gitattributes fichier quelque chose comme:

*.vmc utf16

Notez également que vous devriez toujours pouvoir diff un fichier, même si git pense que c'est binaire avec:

git diff --text

Modifier

Cette réponse dit essentiellement que GNU diff wth UTF-16 ou même UTF-8 ne fonctionne pas très bien. Si vous voulez avoir git utilisez un autre outil pour voir les différences (via --ext-diff), cette réponse suggère Guiffy .

Mais ce dont vous avez probablement besoin est simplement de diff un fichier UTF-16 qui ne contient que ASCII caractères. Une façon de faire fonctionner cela est d'utiliser --ext-diff et le script Shell suivant:

#!/bin/bash
diff <(iconv -f utf-16 -t utf-8 "$1") <(iconv -f utf-16 -t utf-8 "$2")

Notez que la conversion en UTF-8 peut également fonctionner pour la fusion, il vous suffit de vous assurer que cela se fait dans les deux sens.

Quant à la sortie vers le terminal en regardant un diff d'un fichier UTF-16:

Essayer de faire une différence comme cela entraîne des ordures binaires crachées à l'écran. Si git utilise GNU diff, il semblerait que GNU diff ne soit pas compatible Unicode).

GNU diff ne se soucie pas vraiment de l'unicode, donc lorsque vous utilisez diff --text, il diffère juste et produit le texte. Le problème est que le terminal que vous utilisez ne peut pas gérer l'UTF-16 qui est émis (combiné avec les marques de diff ASCII caractères).

29
Jared Oberhaus

La solution consiste à filtrer à travers cmd.exe /c "type %1". La commande intégrée type de cmd effectuera la conversion, et vous pouvez donc l'utiliser avec la capacité textconv de git diff pour activer la différence de texte des fichiers UTF-16 (devrait également fonctionner avec UTF-8, bien que non testé).

Citant la page de manuel de gitattributes:


Exécution de différences de texte de fichiers binaires

Parfois, il est souhaitable de voir la différence d'une version convertie en texte de certains fichiers binaires. Par exemple, un document de traitement de texte peut être converti en une représentation textuelle ASCII et le diff du texte affiché. Même si cette conversion perd certaines informations, le diff résultant est utile pour la visualisation humaine ( mais ne peut pas être appliqué directement).

L'option de configuration textconv est utilisée pour définir un programme pour effectuer une telle conversion. Le programme doit prendre un seul argument, le nom d'un fichier à convertir, et produire le texte résultant sur stdout.

Par exemple, pour afficher la différence des informations exif d'un fichier au lieu des informations binaires (en supposant que l'outil exif est installé), ajoutez la section suivante à votre $GIT_DIR/config fichier (ou $HOME/.gitconfig fichier):

[diff "jpg"]
        textconv = exif

Une solution pour mingw32, les fans de cygwin devront peut-être modifier l'approche. Le problème est de passer le nom de fichier à convertir en cmd.exe - il utilisera des barres obliques et cmd suppose des séparateurs de répertoires de barre oblique inverse.

Étape 1:

Créez le script à argument unique qui effectuera la conversion en stdout. c:\chemin\vers\certains\script.sh:

#!/bin/bash
SED='s/\//\\\\\\\\/g'
FILE=\`echo $1 | sed -e "$SED"\`
cmd.exe /c "type $FILE"

Étape 2:

Configurez git pour pouvoir utiliser le fichier de script. Dans votre configuration git (~/.gitconfig ou .git/config ou voir man git-config), mettez ceci:

[diff "cmdtype"]
textconv = c:/path/to/some/script.sh

Étape 3:

Indiquez les fichiers auxquels appliquer cette solution de contournement en utilisant des fichiers .gitattributes (voir man gitattributes (5)):

*vmc diff=cmdtype

puis utilisez git diff sur vos fichiers.

8
Tony Kuneck

J'ai écrit un petit pilote git-diff, to-utf8, ce qui devrait faciliter la différenciation de tous les fichiers encodés non ASCII/UTF-8. Vous pouvez l'installer en utilisant les instructions ici: https://github.com/chaitanyagupta/gitutils#to-utf8 (le to-utf8 le script est disponible dans le même dépôt).

Notez que ce script requiert que les commandes file et iconv soient disponibles sur le système.

4
Chaitanya Gupta

git a récemment commencé à comprendre des encodages tels que utf16. Voir gitattributes docs, recherchez working-tree-encoding

[Assurez-vous que votre page de manuel correspond, car c'est assez nouveau!]

Si (par exemple) le fichier est utf-16 sans bom sur la machine Windows, ajoutez-le à votre fichier gitattributes

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

Si utf-16 (avec bom) sur * nix, faites-le

*.vmc text working-tree-encoding=UTF-16 eol=LF
2
Rusi

J'ai rencontré récemment ce problème sous Windows et le dos2unixet unix2dos les bacs livrés avec git pour windows ont fait l'affaire. Par défaut, ils sont situés dans C:\Program Files\Git\usr\bin\. Notez que cela ne fonctionnera que si votre fichier n'a pas besoin d'être UTF-16. Par exemple, quelqu'un a accidentellement encodé un python au format UTF-16 alors qu'il n'était pas nécessaire de le faire (dans mon cas).

PS C:\Users\xxx> dos2unix my_file.py
dos2unix: converting UTF-16LE file my_file.py to ANSI_X3.4-1968 Unix format...

et

PS C:\Users\xxx> unix2dos my_file.py
unix2dos: converting UTF-16LE file my_file.py to ANSI_X3.4-1968 DOS format...
1
Matt Messersmith