簡體   English   中英

為什么腳本的行為不同於命令行屬性和git屬性?

[英]Why do scripts behave differently called from commandline vs git attribuites?

下面附有更新的腳本,這些腳本現在可以在我的示例文檔中使用

當通過git屬性或從命令行調用以下python腳本時,為什么表現不同?

我有兩個腳本是基於Mercurial zipdoc功能建模的。 我要做的只是在存儲(filter.clean)上解壓縮docx文件,然后在還原(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屬性

  1. 我將clean和scrub都設置為cat ,驗證了我的文件可以保存和恢復無問題。
  2. 我將clean設置為python〜/ Documents / pyscripts / unzip.py 提交和簽出后,文件現在更大(未壓縮),但是在MS-Word中打開時出錯。 md5也與上面的“僅腳本”測試不匹配。 盡管文件大小相同。
  3. 我將clean設置為cat並將scrub設置為python〜/ Documents / pyscripts / zip.py。 提交和簽出后,文件現在變小(壓縮),但是在MS-Word中打開時再次出錯。 md5再次不同於“僅腳本”測試,但文件大小匹配。
  4. 如預期的那樣,將clean和scrub設置為python腳本會產生錯誤。

我在這里真的迷路了,我認為git Attributes只是在stdin上提供輸入,並從stdout讀取它。 我已經測試了兩個腳本,它們都可以與cat的管道和輸出的重定向一起使用。 我知道腳本正在運行b / c,文件會按預期更改大小,但是文件中的某個地方引入了一個小的更改。

其他參考

我在Win7上使用msgit,上面的所有命令都輸入到git bash窗口中。

Git屬性說明

解壓縮腳本

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的情況下使用zipfile.ZipFile()會引起問題。 打開目標為StringIO()的zip文件,然后最后將完整的StringIO文件寫入stdout已解決了該問題。

我尚未對此進行廣泛的測試,有可能某些.docx內容無法很好地處理,但只有時間才能證明。 我的測試文件現在打開時沒有錯誤,並且,由於使用了比標准.docx格式更高的壓縮率,因此,工作目錄中的.docx文件更小了。

我已經確認,在對.docx文件進行幾次編輯和提交之后,我可以打開該文件,編輯一行,然后在不增加回購文件大小的情況下提交。 例如,一個19KB的文件在回購歷史記錄中進行了3次先前的編輯之后,在頂部添加了新行,從而在執行垃圾回收后在回購中僅產生了1KB的增量。 使用Mercurial運行相同的測試(盡我所能)導致9.3KB增量提交。 我不是水銀專家,我的理解是沒有用於水銀的“ gc”命令,因此沒有運行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM