下面附有更新的脚本,这些脚本现在正在处理我的示例文档
为什么以下python脚本在通过git属性或命令行调用时执行的方式不同?
我所拥有的是两个基于mercurial zipdoc功能建模的脚本。我试图做的就是在商店(filter.clean)上解压缩docx文件并在恢复(filter.smudge)上压缩它们。我有两个脚本运行良好,但一旦我将它们放入git属性,它们就无法工作,我不明白为什么。
我已经通过以下方式进行了测试
测试脚本(git bash)
$ cat original.docx | python~ / Documents / pyscripts / unzip.py> uncompress.docx
$ cat uncompress.docx |蟒蛇 〜/ Documents / pyscripts / zip.py> compress.docx
$ md5sum uncompress.docx compress.docx
我可以使用Microsoft Word打开未压缩和压缩的文件,没有错误。脚本按预期工作。
测试Git属性
我真的迷失在这里,我认为git属性只是在stdin上提供输入并从stdout读取它。我已经测试了两个脚本来处理来自cat的管道和来自输出的重定向就好了。我知道脚本正在运行b / c文件按预期更改大小,但是在文件中的某处引入了一个小的更改。
其他参考资料
我在Win7上使用msgit,上面的所有命令都输入到git bash窗口。
解压缩脚本
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())
压缩脚本
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())
编辑:格式化 编辑2:更新脚本以在文件处理期间写入内存而不是stdout。
答案 0 :(得分:1)
我发现使用目标为stdout的zipfile.ZipFile()导致了问题。打开zipfile,目标是StringIO(),最后将完整的StringIO文件写入stdout,解决了这个问题。
我没有对此进行过广泛的测试,但有些.docx内容可能无法很好地处理,但只有时间会证明。我的测试文件现在打开时没有出错,作为奖励,由于使用比标准.docx格式更高的压缩,工作目录中的.docx文件更小。
我已经确认在对.docx文件执行多次编辑和提交后,我可以打开文件,编辑一行,并提交一个添加到repo大小的大增量。例如,在repo历史记录中的3个先前编辑之后,在顶部添加了新行后,19KB文件在执行垃圾收集后在repo 中创建了仅1KB的增量。使用Mercurial运行相同的测试(尽可能接近)导致9.3KB增量提交。我不是Mercurial专家,我的理解是mercurial没有“gc”命令所以没有运行。