2013-09-10 1 views
1

Обновленные скрипты, прикрепленные ниже, они теперь работают на моем примере документаПочему скрипты ведут себя по-разному вызванными из командной строки vs git attribuites?

Почему следующие сценарии питона работают по-разному, когда вызывается через атрибуты GIT или из командной строки?

У меня есть два сценария, которые я смоделировал на основе функциональности mercurial zipdoc. Все, что я пытаюсь сделать, это распаковать файлы docx на store (filter.clean) и закрепить их при восстановлении (filter.smudge). У меня два сценария работают хорошо, но как только я поместил их в атрибут git, они не работают, и я не понимаю, почему.

Я проверил, выполнив следующие действия

Тестирование сценариев (мерзавец Баш)

$ кошки original.docx | python ~/Documents/pyscripts/unzip.py> uncompress.docx

$ cat uncompress.docx | питон ~/Документы/pyscripts/zip.py> compress.docx

$ md5sum uncompress.docx compress.docx

Я могу открыть как несжатые и сжатые файлы с Microsoft Word без ошибок. Сценарии работают так, как ожидалось.

Тест Git Атрибуты

  1. Я установил как чистый и скраб для кошки, проверил мой файл сохраняет и восстанавливает без проблем.
  2. Я установил чистый python ~/Documents/pyscripts/unzip.py. После фиксации и проверки файл теперь больше (несжатый), но ошибки при открытии в MS-Word. Также md5 не соответствует вышеприведенному тесту «только сценарий». Хотя размер файла идентичен.
  3. Я установил чистый обратно на cat и установил скраб до python ~/Documents/pyscripts/zip.py. После фиксации и проверки файл теперь меньше (сжат), но опять-таки ошибки при открытии в MS-Word. Опять же, md5 отличается от теста «только сценарий», но размер файла соответствует.
  4. Установка как чистых, так и очищаемых сценариев python вызывает ошибку, как и ожидалось.

Я действительно потерялся здесь, я думал, что git Атрибуты просто предоставляют входные данные на stdin и читают его из stdout. Я протестировал оба сценария для работы с каналом из cat и перенаправления с выхода просто отлично. Я знаю, что скрипты запущены b/c, размер файлов изменяется, как ожидалось, однако небольшое изменение вводится где-то в файле.

Дополнительные ссылки

Я использую msgit на Win7, все команды выше, были набраны в окно мерзавец Баш.

Git Attributes Description

Распаковка Script

import fileinput 
import sys 
import zipfile 

# Set stdin and stdout to binary read/write 
if sys.platform == "win32": 
    import os, msvcrt 
    msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) 
    msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY) 

try: 
    from cStringIO import StringIO 
except: 
    from StringIO import StringIO 

# Wrap stdio into a file like object 
inString = StringIO(sys.stdin.read()) 
outString = StringIO() 

# Store each member uncompressed 
try: 
    with zipfile.ZipFile(inString,'r') as inFile: 
     outFile = zipfile.ZipFile(outString,'w',zipfile.ZIP_STORED) 
     for memberInfo in inFile.infolist(): 
      member = inFile.read(memberInfo) 
      memberInfo.compress_type = 0 
      outFile.writestr(memberInfo,member) 
     outFile.close() 
except zipfile.BadZipfile: 
    sys.stdout.write(inString.getvalue()) 

sys.stdout.write(outString.getvalue()) 

Сжать Script

import fileinput 
import sys 
import zipfile 

# Set stdin and stdout to binary read/write 
if sys.platform == "win32": 
    import os, msvcrt 
    msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) 
    msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY) 

try: 
    from cStringIO import StringIO 
except: 
    from StringIO import StringIO 

# Wrap stdio into a file like object 
inString = StringIO(sys.stdin.read()) 
outString = StringIO() 

# Store each member compressed 
try: 
    with zipfile.ZipFile(inString,'r') as inFile: 
     outFile = zipfile.ZipFile(outString,'w',zipfile.ZIP_DEFLATED) 
     for memberInfo in inFile.infolist(): 
      member = inFile.read(memberInfo) 
      memberInfo.compress_type = zipfile.ZIP_DEFLATED 
      outFile.writestr(memberInfo,member) 
     outFile.close() 
except zipfile.BadZipfile: 
    sys.stdout.write(inString.getvalue()) 

sys.stdout.write(outString.getvalue()) 

Edit: Форматирование Edit 2: Сценарии обновлены для записи в память, а не на стандартный вывод при обработке файла ,

+0

Можете ли вы использовать шестнадцатеричный редактор, чтобы увидеть, какая * фактическая * разница между хорошими и плохими несжатыми файлами? Вы говорите, что размер тот же, но MD5 отличается, но это не дает вам никакой реальной информации. –

+0

Несомненно, я упрощу документ и получу шестнадцатеричное сравнение двух файлов. – user1585512

+0

И в процессе этого я думаю, что решил. Используя очень простой тестовый файл, я получил ошибку при вызове функции .read() zipfile. Я изменил zip-файл, чтобы всегда читать и писать из экземпляров StringIO, и теперь тестовый файл отлично работает с git. Конечно, больше испытаний необходимо использовать на свой страх и риск! – user1585512

ответ

1

Я обнаружил, что использование zipfile.ZipFile() с целью, являющейся stdout, вызывало проблему. Открытие zip-файла с целью является StringIO(), а затем в конце записи полного файла StringIO в stdout решила эту проблему.

Я не тестировал это широко, и возможно, что какое-то содержимое .docx не будет обработано, но покажет только время. Мои тестовые файлы теперь открываются с ошибкой, и в качестве бонуса файл .docx в вашем рабочем каталоге меньше из-за использования более высокого сжатия, чем стандартный формат .docx.

Я подтвердил, что после выполнения нескольких изменений и фиксации в файле .docx я могу открыть файл, отредактировать одну строку и совершить с большой дельтой, добавленной к размеру репо. Например, файл 19 Кбайт после трех предыдущих изменений в истории репо, с добавлением новой строки вверху, создал дельта только 1 КБ в репо после выполнения сбора мусора. Выполнение такого же теста (как можно ближе) к Mercurial привело к дельта-фиксации 9.3KB. Я не эксперт Mercurial, я понимаю, что нет никакой команды «gc» для mercurial, поэтому никто не был запущен.

Смежные вопросы