2017-08-16 44 views
-1

在試圖回答this question我做了一個乾淨的過濾器,設置.sh文件的可執行位,並被其結果困惑。爲什麼這個乾淨的過濾器在第一次運行時被忽略?

首先,我跑了git config filter.executable.clean 'chmod +x %f'。這增加了下面的內容,我的測試存儲庫的.git/config文件:

[filter "executable"] 
     clean = chmod +x %f 

接下來,我創建了一個.gitattributes文件:

*.sh filter=executable 

讓我們來看看如何行爲。當然,新創建的.sh文件不是可執行文件:

$ touch foo.sh 
$ ls -l foo.sh 
-rw-r--r-- foo.sh 

如果我們add是我們的清潔過濾器應該運行。但是這會導致我們的工作目錄中有一個可執行文件,我們的臨時區域中有一個不可執行的文件,以及髒的工作副本!

$ git add foo.sh 
$ ls -l foo.sh 
-rwxr-xr-x foo.sh 
$ git ls-files -s foo.sh 
100644 foo.sh 
$ git status 
Changes to be committed: 
    new file: foo.sh 

Changes not staged for commit: 
    modified: foo.sh 

運行git add再次導致在臨時區域的可執行文件和一個乾淨的工作拷貝:

$ git add foo.sh 
$ git ls-files -s foo.sh 
10755 foo.sh 
$ git status 
Changes to be committed: 
    new file: foo.sh 

這是怎麼回事?

回答

0

GIT中的過濾器必須take their input from STDIN and send their output to STDOUT

在結帳時,指定了smudge命令時,該命令被送到從它的標準輸入團塊對象,並且它的標準輸出被用來更新worktree文件。同樣,clean命令用於在簽入時轉換工作文件的內容。

上面顯示的過濾器不會這樣。它忽略STDIN並且它不向STDOUT發送任何輸出,所以它的效果不會被第一個git add命令捕獲。暫存文件不可執行。

但是,過濾器確實運行。這有副作用,即在工作副本中的文件上添加執行位。 git status發現文件的權限已更改。

第二個git add捕獲可執行的位,但不是直接因爲我們的過濾器。它只是簡單地對它在工作副本中看到的權限更改進行分段。

我不知道有任何方式通過STDIN和STDOUT修改文件的權限。在乾淨和污跡過濾器中修改文件權限可能非常困難。

相關問題