$ git diff diff --git a/chapter1.doc b/chapter1.doc index 88839c4..4afcb7c 100644 Binary files a/chapter1.doc and b/chapter1.doc differ
У вас не получится сравнить две версии между собой, только если вы не выгрузите их обе и просмотрите их вручную, так? Оказывается, можно сделать это достаточно успешно, используя атрибуты Git. Поместите следующую строку в свой файл .gitattributes:
*.doc diff=word
Она говорит Git'у, что все файлы, соответствующие указанному шаблону (.doc) должны использовать фильтр "word" при попытке посмотреть дельту с изменениями. Что такое фильтр "word"? Нам нужно его изготовить. Сейчас мы настроим Git на использование программы strings для конвертирования документов Word в читаемые текстовые файлы, которые Git затем правильно сравнит:
$ git config diff.word.textconv strings
Этой командой в свой .git/config вы добавите следующую секцию:
[diff "word"] textconv = strings
Замечание: Существуют разные виды .doc файлов. Некоторые из них могут использовать кодировку UTF-16 или могут быть написаны не в латинице, в таких файлах strings не найдёт ничего хорошего. Полезность strings может сильно варьироваться.
Теперь Git знает, что если ему надо найти дельту между двумя снимками состояния, и какие-то их файлы заканчиваются на .doc, он должен прогнать эти файлы через фильтр "word", который определён как программа strings. Так вы фактически сделаете текстовые версии своих Word-файлов перед тем, как получить для них дельту.
Рассмотрим пример. Я поместил Главу 1 настоящей книги в Git, добавил немного текста в один параграф и сохранил документ. Затем я выполнил git diff, чтобы увидеть, что изменилось:
$ git diff diff --git a/chapter1.doc b/chapter1.doc index c1c8a0a..b93c9e4 100644 --- a/chapter1.doc +++ b/chapter1.doc @@ -8,7 +8,8 @@ re going to cover Version Control Systems (VCS) and Git basics re going to cover how to get it and set it up for the first time if you don t already have it on your system. In Chapter Two we will go over basic Git usage - how to use Git for the 80% -s going on, modify stuff and contribute changes. If the book spontaneously +s going on, modify stuff and contribute changes. If the book spontaneously +Let's see if this works.
Git коротко и ясно дал мне знать, что я добавил строку "Let’s see if this works", так оно и есть. Работает не идеально, так как добавляет немного лишнего в конце, но определённо работает. Если вы сможете найти или написать хорошо работающую программу для конвертации документов Word в обычный текст, то такое решение скорее всего будет невероятно эффективно. Тем не менее, strings доступен на большинстве Mac и Linux-систем, так что он может быть хорошим первым вариантом для того, чтобы сделать подобное со многими бинарными форматами.
Текстовые файлы в формате OpenDocument
Тот же подход, который мы использовали для файлов MS Word (*.doc), может быть использован и для текстовых файлов в формате OpenDocument, созданных в OpenOffice.org.
Добавим следующую строку в файл .gitattributes:
*.odt diff=odt
Теперь настроим фильтр odt в .git/config:
[diff "odt"] binary = true textconv = /usr/local/bin/odt-to-txt
Файлы в формате OpenDocument на самом деле являются запакованными zip'ом каталогами с множеством файлов (содержимое в XML-формате, таблицы стилей, изображения и т.д.). Мы напишем сценарий для извлечения содержимого и вывода его в виде обычного текста. Создайте файл /usr/local/bin/odt-to-txt (можете создать его в любом другом каталоге) со следующим содержимым:
#! /usr/bin/env perl # Сценарий для конвертации OpenDocument Text (.odt) в обычный текст. # Автор: Philipp Kempgen if (! defined($ARGV[0])) { print STDERR "Не задано имя файла!\n"; print STDERR "Использование: $0 имя файла\n"; exit 1; } my $content = ''; open my $fh, '-|', 'unzip', '-qq', '-p', $ARGV[0], 'content.xml' or die $!; { local $/ = undef; # считываем файл целиком $content = <$fh>; } close $fh; $_ = $content; s/<text:span\b[^>]*>//g; # удаляем span'ы s/<text:h\b[^>]*>/\n\n***** /g; # заголовки s/<text:list-item\b[^>]*>\s*<text:p\b[^>]*>/\n -- /g; # элементы списков s/<text:list\b[^>]*>/\n\n/g; # списки s/<text:p\b[^>]*>/\n /g; # параграфы s/<[^>]+>//g; # удаляем все XML-теги s/\n{2,}/\n\n/g; # удаляем подряд идущие пустые строки s/\A\n+//; # удаляем пустые строки в начале print "\n", $_, "\n\n";
Сделайте его исполняемым
chmod +x /usr/local/bin/odt-to-txt
Теперь git diff сможет сказать вам, что изменилось в .odt файлах.
Изображения
Ещё одна интересная проблема, которую можно решить таким способом, это сравнение файлов изображений. Один из способов сделать это — прогнать PNG-файлы через фильтр, извлекающий их EXIF-информацию — метаданные, которые дописываются в большинство форматов изображений. Если скачаете и установите программу exiftool, то сможете воспользоваться ею, чтобы извлечь из изображений текстовую информацию о метаданных, так чтобы diff хоть как-то показал вам текстовое представление произошедших изменений: