2012-02-24 88 views
16

我查找過重複項目,雖然其中一些具有類似的標題,但我還沒有找到任何與我具有相同問題的人,所以在這裏去。如何在git pre-commit鉤子中添加文件到索引

我寫了一個腳本,運行在pre-commit上,並使用git status --porcelain的輸出來編譯我項目中已更改的任何LESS文件。這部分工作正常。但是我希望將.css文件包含在當前提交中。所以除了運行編譯器之外,我的腳本還運行了git add <filename>。而這裏的事情變得棘手。

文件被添加到索引,但它不是當前提交的索引。因此,如果我修改style.less並運行git commit -a(或手動git add style.less),編譯器應生成style.cssstyle.min.css並將它們添加到當前提交中。但是我注意到的行爲只有style.less已提交,儘管兩個.css文件被添加到索引以用於下一次提交。

所以我的問題是:有沒有辦法將文件添加到預提交鉤子中的提交,以便它們對該提交生效?請注意,在執行預提交掛鉤之前,這兩個.css文件未被修改,所以我不能只在這之前添加它們。我也知道我可以退出非零狀態的鉤子,所以提交被取消,但文件被添加,但我希望避免這種情況。任何更好的想法?

回答

-3

爲什麼你想這樣做呢?您正試圖將生成的文件包含到版本控制中,無論如何這通常都不是一個好主意。如果你需要在結賬時使用style.min.css,爲什麼你不能在構建步驟結帳後生成它?

+0

由於CSS文件不是二進制文件,它們只是靜態文本文件。生成的文件不會放在版本控制中,因爲它們通常會導致合併衝突,而您沒有真正有效的方法來解決它們(二進制文件),但對於CSS文件,您很少遇到這種問題。我不想在我們的Web服務器上安裝一個LESS編譯器來進行合併/更新。然而,所有這一切說,它確實證明是一種更簡單的方法來完成我正在嘗試做的事情,儘管它並不理想。 – 2012-03-03 22:22:41

+1

爲什麼這是被接受的答案?這根本不能解決問題。 – frhd 2014-10-01 16:00:47

+1

我猜他接受了我的「你做錯了」的非答案,因爲在這種情況下,它解決了他的問題(可以說沒有回答他的問題)。如果他沒有首先檢查LESS文件,那麼「我如何將它們融入提交」問題就會消失。 – plaugg 2014-10-15 19:00:03

0

在我看來,你可以讓git屬性'clean'成爲更新生成文件的腳本。通常情況下,鉤子可以運行一個腳本來整理你的源代碼,但我認爲它可以用來「清理」你生成的輸出。 當您執行'git add'時會觸發此屬性,並且您可以讓腳本在生成的文件上執行另一個'git add'。

+0

你能詳細說明一下嗎?我做了一些Google搜索,發現了一些有關Git屬性的信息,但沒有提供如何將腳本附加到它們以及如何佈置'add'屬性的信息。 – 2012-02-27 19:54:19

0

您可能會利用修改上次提交的優勢。只是一個想法。

+0

我確實考慮過這個選項,但我希望避免它。它涉及到運行提交,運行掛鉤,然後讓原始提交完成,然後運行第二次提交(除非我遺漏了某些內容),這看起來很麻煩,而且手動操作似乎很複雜,而且自動使用鉤子很荒謬。 – 2012-02-27 19:56:12

+0

雖然當被鉤子自動運行時,它會完美地完成工作。 – Xobb 2012-02-28 13:06:51

10

我無法重現您的問題。我最初的猜測是GIT_INDEX_FILE環境變量正在被你的pre-commit掛鉤取消。但是,當我嘗試從pre-commit未設置GIT_INDEX_FILE,我得到了一個不同的問題(Git抱怨.git/index被鎖定)。

下面是一個示例腳本,顯示Git的功能如您所期望的那樣,並且其他內容必須是錯誤的。該腳本初始化一個新的測試版本庫,創建一個pre-commit鉤模仿你的鉤子做什麼,並提出了一些測試承諾:

#!/bin/sh 

# initialize the test repository 
rm -rf testrepo 
git init testrepo 
cd testrepo 

# create the pre-commit hook 
cat <<\EOF >.git/hooks/pre-commit 
#!/bin/sh 
git status --porcelain | while IFS= read -r line; do 
    # todo: handle renames and deletions of a *.less file 
    f=${line#???} 
    case ${f} in 
     *.less) 
      fb=${f%.less} 
      echo bar >>"${fb}".css 
      echo baz >>"${fb}".min.css 
      git add "${fb}".css "${fb}".min.css 
      ;; 
    esac 
done 
EOF 
chmod +x .git/hooks/pre-commit 

# create foo.less, commit it 
echo foo >foo.less 
git add foo.less 
git commit -m "add foo.less" 

# modify foo.less, commit it 
echo foo2 >>foo.less 
git commit -a -m "modify foo.less" 

如果您在測試中運行的倉庫git log -p和查看最終的承諾,你」當foo.less被修改時,將看到foo.cssfoo.min.css被修改。

這也是爲什麼我覺得你的問題是通過改變/取消設置GIT_INDEX_FILE環境變量引起的:

git commit -a運行,Git會使得臨時索引文件,並使用,而不是默認.git/index創建提交。爲了使像git add這樣的操作能夠在pre-commit鉤子內工作,Git將GIT_INDEX_FILE環境變量設置爲在運行pre-commit之前創建的臨時索引的名稱。如果您的掛鉤取消設置GIT_INDEX_FILE,或將其設置爲.git/index,則鉤子中的所有Git操作都會嘗試修改原始索引,而不是用於生成提交的臨時索引。

但是,臨時索引文件也充當原始索引文件的鎖定。如果掛鉤試圖修改原始索引,並且臨時索引存在,那麼Git將會中止並出現錯誤。

+0

我運行了你的腳本,它和預期一樣工作,這與我的真實存儲庫的實際行爲相反。我會稍後再研究一下,如果我找出一些東西,就會回到你身邊。謝謝! – 2012-02-28 20:10:13

+0

因爲努力,給了你賞金,儘管我仍然無法弄清楚發生了什麼。再次感謝! – 2012-03-03 22:23:38

相關問題