更新的脚本附在下面,这些现在正在处理我的示例文档
为什么以下 python 脚本在通过 git 属性或命令行调用时执行不同?
我有两个基于 mercurial zipdoc 功能建模的脚本。我要做的就是解压缩存储中的 docx 文件(filter.clean)并在恢复时压缩它们(filter.smudge)。我有两个脚本运行良好,但是一旦我将它们放入 git 属性,它们就不起作用,我不明白为什么。
我已经通过执行以下操作进行了测试
测试脚本(git bash)
$ cat original.docx | python ~/Documents/pyscripts/unzip.py > uncompress.docx
$ cat uncompress.docx | python ~/Documents/pyscripts/zip.py > compress.docx
$ md5sum uncompress.docx compress.docx
我可以用 Microsoft Word 打开未压缩和压缩文件,没有错误。脚本按预期工作。
测试 Git 属性
- 我将 clean 和 scrub 都设置为cat,验证了我的文件保存和恢复没有问题。
- 我将 clean 设置为python ~/Documents/pyscripts/unzip.py。提交和签出后,文件现在更大(未压缩),但在 MS-Word 中打开时出错。此外,md5 与上面的“仅脚本”测试不匹配。虽然文件大小相同。
- 我将 clean 设置回cat并将 Scrub 设置为python ~/Documents/pyscripts/zip.py。提交和签出后,文件现在更小(压缩),但在 MS-Word 中打开时再次出错。同样,md5 与“仅脚本”测试不同,但文件大小匹配。
- 正如预期的那样,将清理和清理都设置为 python 脚本会产生错误。
我真的迷路了,我认为 git Attributes 只是在标准输入上提供输入并从标准输出中读取它。我已经测试了这两个脚本以使用来自 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:脚本更新为在文件处理期间写入内存而不是标准输出。