匿名
尚未登入
登入
DILA Wiki
搜尋
檢視 Pro Git 7.2 Git 屬性 的原始碼
出自DILA Wiki
命名空間
頁面
討論
更多
更多
頁面操作
閱讀
檢視原始碼
歷史
←
Pro Git 7.2 Git 屬性
由於下列原因,您沒有權限進行編輯此頁面的動作:
您請求的操作只有這個群組的使用者能使用:
使用者
您可以檢視並複製此頁面的原始碼。
一些設置項(settings)也能被運用於特定的路徑中,這樣,Git 只對這個特定的子目錄或某些檔檔應用這些設置值。這些設置項被稱為 Git 屬性,可以在你目錄中的 .gitattributes 檔內進行設置(通常是你專案的根目錄),也可以當你不想讓這些屬性檔和專案檔案一同提交時,在 .git/info/attributes 進行設置。 使用屬性,你可以對個別檔或目錄定義不同的合併策略,讓 Git 知道怎樣比較非文字檔,在你提交或簽出(check out)前讓 Git 過濾內容。你將在這個章節裏瞭解到能在自己的專案中使用的屬性,以及一些實例。 =二進位檔案= 你可以用 Git 屬性讓其知道哪些是二進位檔案(以防 Git 沒有識別出來),以及指示怎樣處理這些檔,這點很酷。例如,一些文字檔是由機器產生的,而且無法比較,而一些二進位檔案可以比較 — 你將會瞭解到怎樣讓 Git 識別這些檔。 ==識別二進位檔案== 一些檔看起來像是文字檔,但其實是作為二進位資料被對待。例如,在 Mac 上的 Xcode 專案含有一個以 .pbxproj 結尾的檔,它是由記錄設置項的 IDE 寫到磁片的 JSON 資料集(純文字 javascript 資料類型)。雖然技術上看它是由 ASCII 字元組成的文字檔,但你並不認為如此,因為它確實是一個羽量級資料庫 — 如果有兩個人改變了它,你通常無法合併和比較內容,只有機器才能進行識別和操作,於是,你想把它當成二進位檔案。 讓 Git 把所有 pbxproj 檔當成二進位檔案,在 .gitattributes 文件中設置如下: <syntaxhighlight lang="XML"> *.pbxproj -crlf -diff </syntaxhighlight> 現在,Git 不會嘗試轉換和修正 CRLF(回車換行)問題;也不會當你在專案中運行 git show 或 git diff 時,比較不同的內容。在 Git 1.6 及之後的版本中,可以用一個巨集代替 -crlf -diff: <syntaxhighlight lang="XML"> *.pbxproj binary </syntaxhighlight> ==比較二進位檔案== 在 Git 1.6 及以上版本中,你能利用 Git 屬性來有效地比較二進位檔案。可以設置 Git 把二進位資料轉換成文本格式,用通常的 diff 來比較。 這個特性很酷,而且鮮為人知,因此我會結合實例來講解。首先,要解決的是最令人頭疼的問題:對 Word 文檔進行版本控制。很多人對 Word 文檔又恨又愛,如果想對其進行版本控制,你可以把檔案加入到 Git 倉庫中,每次修改後提交即可。但這樣做沒有一點實際意義,因為運行 git diff 命令後,你只能得到如下的結果: <syntaxhighlight lang="XML"> $ git diff diff --git a/chapter1.doc b/chapter1.doc index 88839c4..4afcb7c 100644 Binary files a/chapter1.doc and b/chapter1.doc differ </syntaxhighlight> 你不能直接比較兩個不同版本的 Word 檔,除非人工細看,不是嗎?Git 屬性能很好地解決此問題,把下面的行加到 .gitattributes 文件: <syntaxhighlight lang="XML"> *.doc diff=word </syntaxhighlight> 當你要看比較結果時,如果檔副檔名是 ”doc”,Git 會使用 ”word” 篩檢程式。什麼是 ”word” 篩檢程式呢?其實就是 Git 使用 strings 程式,把 Word 文檔轉換成可讀的文字檔,之後再進行比較: <syntaxhighlight lang="XML"> $ git config diff.word.textconv strings </syntaxhighlight> 現在如果在兩個快照之間比較以 .doc 結尾的檔,Git 對這些檔運用 ”word” 篩檢程式,在比較前把 Word 檔轉換成文字檔。 下面展示了一個實例,我把此書的第一章納入 Git 管理,在一個段落中加入了一些文本後保存,之後運行 git diff 命令,得到結果如下: <syntaxhighlight lang="XML"> $ git diff diff --git a/chapter1.doc b/chapter1.doc index c1c8a0a..b93c9e4 100644 --- a/chapter1.doc +++ b/chapter1.doc @@ -8,7 +8,8 @@ re going to cover Version Control Systems (VCS) and Git basics re going to cover how to get it and set it up for the first time if you don t already have it on your system. In Chapter Two we will go over basic Git usage - how to use Git for the 80% -s going on, modify stuff and contribute changes. If the book spontaneously +s going on, modify stuff and contribute changes. If the book spontaneously +Let's see if this works. </syntaxhighlight> Git 成功且簡潔地顯示出我增加的文本 ”Let’s see if this works”。雖然有些瑕疵,在末尾顯示了一些隨機的內容,但確實可以比較了。如果你能找到或自己寫個 Word 到純文字的轉換器的話,效果可能會更好。strings 可以在大部分 Mac 和 Linux 系統上運行,所以它是處理二進位格式的第一選擇。 你還能用這個方法比較影像檔。當比較時,對 JPEG 檔運用一個篩檢程式,它能提煉出 EXIF 資訊 — 大部分圖像格式使用的中繼資料。如果你下載並安裝了 exiftool 程式,可以用它參照中繼資料把圖像轉換成文本。比較的不同結果將會用文本向你展示: <syntaxhighlight lang="XML"> $ echo '*.png diff=exif' >> .gitattributes $ git config diff.exif.textconv exiftool </syntaxhighlight> 如果在專案中替換了一個影像檔,運行 git diff 命令的結果如下: <syntaxhighlight lang="XML"> diff --git a/image.png b/image.png index 88839c4..4afcb7c 100644 --- a/image.png +++ b/image.png @@ -1,12 +1,12 @@ ExifTool Version Number : 7.74 -File Size : 70 kB -File Modification Date/Time : 2009:04:21 07:02:45-07:00 +File Size : 94 kB +File Modification Date/Time : 2009:04:21 07:02:43-07:00 File Type : PNG MIME Type : image/png -Image Width : 1058 -Image Height : 889 +Image Width : 1056 +Image Height : 827 Bit Depth : 8 Color Type : RGB with Alpha </syntaxhighlight> 你會發現檔的尺寸大小發生了改變。 =關鍵字擴展= 使用 SVN 或 CVS 的開發人員經常要求關鍵字擴展。在 Git 中,你無法在一個檔被提交後修改它,因為 Git 會先對該檔計算校驗和。然而,你可以在簽出時注入文本,在提交前刪除它。Git 屬性提供了兩種方式來進行。 首先,你能夠把 blob 的 SHA-1 校驗和自動注入檔案的 $Id$ 欄位。如果在一個或多個檔案上設置了此欄位,當下次你簽出分支的時候,Git 用 blob 的 SHA-1 值替換那個欄位。注意,這不是提交對象的 SHA 校驗和,而是 blob 本身的校驗和: <syntaxhighlight lang="XML"> $ echo '*.txt ident' >> .gitattributes $ echo '$Id$' > test.txt </syntaxhighlight> 下次簽出文件時,Git 注入了 blob 的 SHA 值: <syntaxhighlight lang="XML"> $ rm text.txt $ git checkout -- text.txt $ cat test.txt $Id: 42812b7653c7b88933f8a9d6cad0ca16714b9bb3 $ </syntaxhighlight> 然而,這樣的顯示結果沒有多大的實際意義。這個 SHA 的值相當地隨機,無法區分日期的前後,所以,如果你在 CVS 或 Subversion 中用過關鍵字替換,一定會包含一個日期值。 因此,你能寫自己的篩檢程式,在提交文件到暫存區或簽出文件時替換關鍵字。有兩種篩檢程式,”clean” 和 ”smudge”。在 .gitattributes 檔中,你能對特定的路徑設置一個篩檢程式,然後設置處理檔案的腳本,這些腳本會在檔案簽出前(”smudge”,見圖 7-2)和提交到暫存區前(”clean”,見圖7-3)被調用。這些篩檢程式能夠做各種有趣的事。 [[圖片:Pro-git-7-2.png]] 圖7-2. 簽出時,“smudge”篩檢程式被觸發。 [[圖片:Pro-git-7-3.png]] 圖7-3. 提交到暫存區時,“clean”篩檢程式被觸發。 這裡舉一個簡單的例子:在暫存前,用 indent(縮進)程式過濾所有C原始程式碼。在. gitattributes 檔中設置 ”indent” 篩檢程式過濾 *.c 文件: <syntaxhighlight lang="XML"> *.c filter=indent </syntaxhighlight> 然後,通過以下配置,讓 Git 知道 ”indent” 篩檢程式在遇到 ”smudge” 和 ”clean” 時分別該做什麼: <syntaxhighlight lang="XML"> $ git config --global filter.indent.clean indent $ git config --global filter.indent.smudge cat </syntaxhighlight> 於是,當你暫存 *.c 檔時,indent程式會被觸發,在把它們簽出之前,cat程式會被觸發。但cat程式在這裡沒什麼實際作用。這樣的組合,使C原始程式碼在暫存前被indent程式過濾,非常有效。 另一個例子是類似 RCS 的 $Date$ 關鍵字擴展。為了演示,需要一個小腳本,接受檔案名參數,得到專案的最新提交日期,最後把日期寫入該檔。下麵用 Ruby 腳本來實現: <syntaxhighlight lang="XML"> #! /usr/bin/env ruby data = STDIN.read last_date = `git log --pretty=format:"%ad" -1` puts data.gsub('$Date$', '$Date: ' + last_date.to_s + '$') </syntaxhighlight> 該腳本從 git log 命令中得到最新提交日期,找到檔中的所有 $Date$ 字串,最後把該日期填充到 $Date$ 字串中 — 此腳本很簡單,你可以選擇你喜歡的程式設計語言來實現。把該腳本命名為 expand_date,放到正確的路徑中,之後需要在 Git 中設置一個篩檢程式(dater),讓它在簽出檔時調用 expand_date,在暫存檔時用 Perl 清除之: <syntaxhighlight lang="XML"> $ git config filter.dater.smudge expand_date $ git config filter.dater.clean 'perl -pe "s/\\\$Date[^\\\$]*\\\$/\\\$Date\\\$/"' </syntaxhighlight> 這個 Perl 小程式會刪除 $Date$ 字串裡多餘的字元,恢復 $Date$ 原貌。到目前為止,你的篩檢程式已經設置完畢,可以開始測試了。打開一個檔,在檔中輸入 $Date$ 關鍵字,然後設置 Git 屬性: <syntaxhighlight lang="XML"> $ echo '# $Date$' > date_test.txt $ echo 'date*.txt filter=dater' >> .gitattributes </syntaxhighlight> 如果暫存該檔,之後再簽出,你會發現關鍵字被替換了: <syntaxhighlight lang="XML"> $ git add date_test.txt .gitattributes $ git commit -m "Testing date expansion in Git" $ rm date_test.txt $ git checkout date_test.txt $ cat date_test.txt # $Date: Tue Apr 21 07:26:52 2009 -0700$ </syntaxhighlight> 雖說這項技術對自訂應用來說很有用,但還是要小心,因為 .gitattributes 檔會隨著專案一起提交,而篩檢程式(例如:dater)不會,所以,篩檢程式不會在所有地方都生效。當你在設計這些篩檢程式時要注意,即使它們無法正常工作,也要讓整個專案運作下去。 =匯出倉庫= Git 屬性在匯出專案歸檔時也能發揮作用。 ==export-ignore== 當產生一個歸檔(archive)時,可以設置 Git 不匯出某些檔案和目錄。如果你不想在歸檔中包含一個子目錄或檔案,但想將他們納入專案的版本管理中,你能對應地設置 export-ignore 屬性。 例如,在 test/ 子目錄中有一些測試檔,在專案的壓縮包中包含他們是沒有意義的。因此,可以增加下面這行到 Git 屬性檔中: <syntaxhighlight lang="XML"> test/ export-ignore </syntaxhighlight> 現在,當運行 git archive 來創建專案的壓縮包時,那個目錄不會在歸檔中出現。 ==export-subst== 還能對歸檔做一些簡單的關鍵字替換。在第2章中已經可以看到,可以以 --pretty=format 形式的簡碼在任何檔中放入 $Format:$ 字串。例如,如果想在專案中包含一個叫作 LAST_COMMIT 的檔,當運行 git archive 時,最後提交日期自動地注入進該檔,可以這樣設置: <syntaxhighlight lang="XML"> $ echo 'Last commit date: $Format:%cd$' > LAST_COMMIT $ echo "LAST_COMMIT export-subst" >> .gitattributes $ git add LAST_COMMIT .gitattributes $ git commit -am 'adding LAST_COMMIT file for archives' </syntaxhighlight> 執行 git archive 後,打開該檔,會發現其內容如下: <syntaxhighlight lang="XML"> $ cat LAST_COMMIT Last commit date: $Format:Tue Apr 21 08:38:48 2009 -0700$ </syntaxhighlight> =合併策略= 通過 Git 屬性,還能對專案中的特定檔使用不同的合併策略。一個非常有用的選項就是,當一些特定檔發生衝突,Git 不會嘗試合併他們,而使用你這邊的合併。 如果專案的一個分支有歧義或比較特別,但你想從該分支合併,而且需要忽略其中某些檔,這樣的合併策略是有用的。例如,你有一個資料庫設置檔 database.xml,在兩個分支中他們是不同的,你想合併一個分支到另一個,而不弄亂該資料庫檔,可以設置屬性如下: <syntaxhighlight lang="XML"> database.xml merge=ours </syntaxhighlight> 如果合併到另一個分支,database.xml 檔不會有合併衝突,顯示如下: <syntaxhighlight lang="XML"> $ git merge topic Auto-merging database.xml Merge made by recursive. </syntaxhighlight> 這樣,database.xml會保持原樣。
返回到「
Pro Git 7.2 Git 屬性
」。
導覽
導覽
首頁
近期變更
隨機頁面
MediaWiki說明
wiki工具
wiki工具
特殊頁面
頁面工具
頁面工具
使用者頁面工具
更多
連結至此的頁面
相關變更
頁面資訊
頁面日誌