7.1 自定義 Git - 配置 Git

配置 Git

如第一章所言,用git config配置 Git,要做的第一件事就是設置名字和郵箱地址:

$ git config --global user.name "John Doe"
$ git config --global user.email [email protected]

從現在開始,你會瞭解到一些類似以上但更爲有趣的設置選項來自定義 Git。

先過一遍第一章中提到的 Git 配置細節。Git 使用一系列的配置文件來存儲你定義的偏好,它首先會查找/etc/gitconfig文件,該文件含有 對系統上所有用戶及他們所擁有的倉庫都生效的配置值(譯註:gitconfig是全局配置文件), 如果傳遞--system選項給git config命令, Git 會讀寫這個文件。

接下來 Git 會查找每個用戶的~/.gitconfig文件,你能傳遞--global選項讓 Git讀寫該文件。

最後 Git 會查找由用戶定義的各個庫中 Git 目錄下的配置文件(.git/config),該文件中的值只對屬主庫有效。 以上闡述的三層配置從一般到特殊層層推進,如果定義的值有衝突,以後面層中定義的爲準,例如:在.git/config/etc/gitconfig的較量中, .git/config取得了勝利。雖然你也可以直接手動編輯這些配置文件,但是運行git config命令將會來得簡單些。

客戶端基本配置

Git 能夠識別的配置項被分爲了兩大類:客戶端和服務器端,其中大部分基於你個人工作偏好,屬於客戶端配置。儘管有數不盡的選項,但我只闡述 其中經常使用或者會對你的工作流產生巨大影響的選項,如果你想觀察你當前的 Git 能識別的選項列表,請運行

$ git config --help

git config的手冊頁(譯註:以man命令的顯示方式)非常細緻地羅列了所有可用的配置項。

core.editor

Git默認會調用你的環境變量editor定義的值作爲文本編輯器,如果沒有定義的話,會調用Vi來創建和編輯提交以及標籤信息, 你可以使用core.editor改變默認編輯器:

$ git config --global core.editor emacs

現在無論你的環境變量editor被定義成什麼,Git 都會調用Emacs編輯信息。

commit.template

如果把此項指定爲你係統上的一個文件,當你提交的時候, Git 會默認使用該文件定義的內容。 例如:你創建了一個模板文件$HOME/.gitmessage.txt,它看起來像這樣:

subject line

what happened

[ticket: X]

設置commit.template,當運行git commit時, Git 會在你的編輯器中顯示以上的內容, 設置commit.template如下:

$ git config --global commit.template $HOME/.gitmessage.txt
$ git commit

然後當你提交時,在編輯器中顯示的提交信息如下:

subject line

what happened

[ticket: X]
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
# modified:   lib/test.rb
#
~
~
".git/COMMIT_EDITMSG" 14L, 297C

如果你有特定的策略要運用在提交信息上,在系統上創建一個模板文件,設置 Git 默認使用它,這樣當提交時,你的策略每次都會被運用。

core.pager

core.pager指定 Git 運行諸如logdiff等所使用的分頁器,你能設置成用more或者任何你喜歡的分頁器(默認用的是less), 當然你也可以什麼都不用,設置空字符串:

$ git config --global core.pager ''

這樣不管命令的輸出量多少,都會在一頁顯示所有內容。

user.signingkey

如果你要創建經簽署的含附註的標籤(正如第二章所述),那麼把你的GPG簽署密鑰設置爲配置項會更好,設置密鑰ID如下:

$ git config --global user.signingkey <gpg-key-id>

現在你能夠簽署標籤,從而不必每次運行git tag命令時定義密鑰:

$ git tag -s <tag-name>

core.excludesfile

正如第二章所述,你能在項目庫的.gitignore文件裏頭用模式來定義那些無需納入 Git 管理的文件,這樣它們不會出現在未跟蹤列表, 也不會在你運行git add後被暫存。然而,如果你想用項目庫之外的文件來定義那些需被忽略的文件的話,用core.excludesfile 通知 Git 該文件所處的位置,文件內容和.gitignore類似。

help.autocorrect

該配置項只在 Git 1.6.1及以上版本有效,假如你在Git 1.6中錯打了一條命令,會顯示:

$ git com
git: 'com' is not a git-command. See 'git --help'.

Did you mean this?
     commit

如果你把help.autocorrect設置成1(譯註:啓動自動修正),那麼在只有一個命令被模糊匹配到的情況下,Git 會自動運行該命令。

Git中的着色

Git能夠爲輸出到你終端的內容着色,以便你可以憑直觀進行快速、簡單地分析,有許多選項能供你使用以符合你的偏好。

color.ui

Git會按照你需要自動爲大部分的輸出加上顏色,你能明確地規定哪些需要着色以及怎樣着色,設置color.ui爲true來打開所有的默認終端着色。

$ git config --global color.ui true

設置好以後,當輸出到終端時,Git 會爲之加上顏色。其他的參數還有false和always,false意味着不爲輸出着色,而always則表明在任何情況下都要着色,即使 Git 命令被重定向到文件或管道。Git 1.5.5版本引進了此項配置,如果你擁有的版本更老,你必須對顏色有關選項各自進行詳細地設置。

你會很少用到color.ui = always,在大多數情況下,如果你想在被重定向的輸出中插入顏色碼,你能傳遞--color標誌給 Git 命令來迫使它這麼做,color.ui = true應該是你的首選。

color.*

想要具體到哪些命令輸出需要被着色以及怎樣着色或者 Git 的版本很老,你就要用到和具體命令有關的顏色配置選項,它們都能被置爲truefalsealways

color.branch
color.diff
color.interactive
color.status

除此之外,以上每個選項都有子選項,可以被用來覆蓋其父設置,以達到爲輸出的各個部分着色的目的。例如,讓diff輸出的改變信息以粗體、藍色前景和黑色背景的形式顯示:

$ git config --global color.diff.meta "blue black bold"

你能設置的顏色值如:normal、black、red、green、yellow、blue、magenta、cyan、white,正如以上例子設置的粗體屬性,想要設置字體屬性的話,可以選擇如:bold、dim、ul、blink、reverse。

如果你想配置子選項的話,可以參考git config幫助頁。

外部的合併與比較工具

雖然 Git 自己實現了diff,而且到目前爲止你一直在使用它,但你能夠用一個外部的工具替代它,除此以外,你還能用一個圖形化的工具來合併和解決衝突從而不必自己手動解決。有一個不錯且免費的工具可以被用來做比較和合並工作,它就是P4Merge(譯註:Perforce圖形化合並工具),我會展示它的安裝過程。

P4Merge可以在所有主流平臺上運行,現在開始大膽嘗試吧。對於向你展示的例子,在Mac和Linux系統上,我會使用路徑名,在Windows上,/usr/local/bin應該被改爲你環境中的可執行路徑。

下載P4Merge:

http://www.perforce.com/product/components/perforce-visual-merge-and-diff-tools

首先把你要運行的命令放入外部包裝腳本中,我會使用Mac系統上的路徑來指定該腳本的位置,在其他系統上,它應該被放置在二進制文件p4merge所在的目錄中。創建一個merge包裝腳本,名字叫作extMerge,讓它帶參數調用p4merge二進制文件:

$ cat /usr/local/bin/extMerge
#!/bin/sh
/Applications/p4merge.app/Contents/MacOS/p4merge $*

diff包裝腳本首先確定傳遞過來7個參數,隨後把其中2個傳遞給merge包裝腳本,默認情況下, Git 傳遞以下參數給diff:

path old-file old-hex old-mode new-file new-hex new-mode

由於你僅僅需要old-filenew-file參數,用diff包裝腳本來傳遞它們吧。

$ cat /usr/local/bin/extDiff
#!/bin/sh
[ $# -eq 7 ] && /usr/local/bin/extMerge "$2" "$5"

確認這兩個腳本是可執行的:

$ sudo chmod +x /usr/local/bin/extMerge
$ sudo chmod +x /usr/local/bin/extDiff

現在來配置使用你自定義的比較和合並工具吧。這需要許多自定義設置:merge.tool通知 Git 使用哪個合併工具;mergetool.*.cmd規定命令運行的方式;mergetool.trustExitCode會通知 Git 程序的退出是否指示合併操作成功;diff.external通知 Git 用什麼命令做比較。因此,你能運行以下4條配置命令:

$ git config --global merge.tool extMerge
$ git config --global mergetool.extMerge.cmd \
    'extMerge "$BASE" "$LOCAL" "$REMOTE" "$MERGED"'
$ git config --global mergetool.trustExitCode false
$ git config --global diff.external extDiff

或者直接編輯~/.gitconfig文件如下:

[merge]
  tool = extMerge
[mergetool "extMerge"]
  cmd = extMerge \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"
  trustExitCode = false
[diff]
  external = extDiff

設置完畢後,運行diff命令:

$ git diff 32d1776b1^ 32d1776b1

命令行居然沒有發現diff命令的輸出,其實,Git 調用了剛剛設置的P4Merge,它看起來像圖7-1這樣:


Figure 7-1. P4Merge.

當你設法合併兩個分支,結果卻有衝突時,運行git mergetool,Git 會調用P4Merge讓你通過圖形界面來解決衝突。

設置包裝腳本的好處是你能簡單地改變diff和merge工具,例如把extDiffextMerge改成KDiff3,要做的僅僅是編輯extMerge腳本文件:

$ cat /usr/local/bin/extMerge
#!/bin/sh
/Applications/kdiff3.app/Contents/MacOS/kdiff3 $*

現在 Git 會使用KDiff3來做比較、合併和解決衝突。

Git預先設置了許多其他的合併和解決衝突的工具,而你不必設置cmd。可以把合併工具設置爲:kdiff3、opendiff、tkdiff、meld、xxdiff、emerge、vimdiff、gvimdiff。如果你不想用到KDiff3的所有功能,只是想用它來合併,那麼kdiff3正符合你的要求,運行:

$ git config --global merge.tool kdiff3

如果運行了以上命令,沒有設置extMergeextDiff文件,Git 會用KDiff3做合併,讓通常內設的比較工具來做比較。

格式化與空白

格式化與空白是許多開發人員在協作時,特別是在跨平臺情況下,遇到的令人頭疼的細小問題。由於編輯器的不同或者Windows程序員在跨平臺項目中的文件行尾加入了回車換行符,一些細微的空格變化會不經意地進入大家合作的工作或提交的補丁中。不用怕,Git 的一些配置選項會幫助你解決這些問題。

core.autocrlf

假如你正在Windows上寫程序,又或者你正在和其他人合作,他們在Windows上編程,而你卻在其他系統上,在這些情況下,你可能會遇到行尾結束符問題。這是因爲Windows使用回車和換行兩個字符來結束一行,而Mac和Linux只使用換行一個字符。雖然這是小問題,但它會極大地擾亂跨平臺協作。

Git可以在你提交時自動地把行結束符CRLF轉換成LF,而在簽出代碼時把LF轉換成CRLF。用core.autocrlf來打開此項功能,如果是在Windows系統上,把它設置成true,這樣當簽出代碼時,LF會被轉換成CRLF:

$ git config --global core.autocrlf true

Linux或Mac系統使用LF作爲行結束符,因此你不想 Git 在簽出文件時進行自動的轉換;當一個以CRLF爲行結束符的文件不小心被引入時你肯定想進行修正,把core.autocrlf設置成input來告訴 Git 在提交時把CRLF轉換成LF,簽出時不轉換:

$ git config --global core.autocrlf input

這樣會在Windows系統上的簽出文件中保留CRLF,會在Mac和Linux系統上,包括倉庫中保留LF。

如果你是Windows程序員,且正在開發僅運行在Windows上的項目,可以設置false取消此功能,把回車符記錄在庫中:

$ git config --global core.autocrlf false

core.whitespace

Git預先設置了一些選項來探測和修正空白問題,其4種主要選項中的2個默認被打開,另2個被關閉,你可以自由地打開或關閉它們。

默認被打開的2個選項是trailing-spacespace-before-tabtrailing-space會查找每行結尾的空格,space-before-tab會查找每行開頭的製表符前的空格。

默認被關閉的2個選項是indent-with-non-tabcr-at-eolindent-with-non-tab會查找8個以上空格(非製表符)開頭的行,cr-at-eol讓 Git 知道行尾回車符是合法的。

設置core.whitespace,按照你的意圖來打開或關閉選項,選項以逗號分割。通過逗號分割的鏈中去掉選項或在選項前加-來關閉,例如,如果你想要打開除了cr-at-eol之外的所有選項:

$ git config --global core.whitespace \
    trailing-space,space-before-tab,indent-with-non-tab

當你運行git diff命令且爲輸出着色時,Git 探測到這些問題,因此你也許在提交前能修復它們,當你用git apply打補丁時同樣也會從中受益。如果正準備運用的補丁有特別的空白問題,你可以讓 Git 發警告:

$ git apply --whitespace=warn <patch>

或者讓 Git 在打上補丁前自動修正此問題:

$ git apply --whitespace=fix <patch>

這些選項也能運用於衍合。如果提交了有空白問題的文件但還沒推送到上游,你可以運行帶有--whitespace=fix選項的rebase來讓Git在重寫補丁時自動修正它們。

服務器端配置

Git服務器端的配置選項並不多,但仍有一些饒有生趣的選項值得你一看。

receive.fsckObjects

Git默認情況下不會在推送期間檢查所有對象的一致性。雖然會確認每個對象的有效性以及是否仍然匹配SHA-1檢驗和,但 Git 不會在每次推送時都檢查一致性。對於 Git 來說,庫或推送的文件越大,這個操作代價就相對越高,每次推送會消耗更多時間,如果想在每次推送時 Git 都檢查一致性,設置receive.fsckObjects 爲true來強迫它這麼做:

$ git config --system receive.fsckObjects true

現在 Git 會在每次推送生效前檢查庫的完整性,確保有問題的客戶端沒有引入破壞性的數據。

receive.denyNonFastForwards

如果對已經被推送的提交歷史做衍合,繼而再推送,又或者以其它方式推送一個提交歷史至遠程分支,且該提交歷史沒在這個遠程分支中,這樣的推送會被拒絕。這通常是個很好的禁止策略,但有時你在做衍合併確定要更新遠程分支,可以在push命令後加-f標誌來強制更新。

要禁用這樣的強制更新功能,可以設置receive.denyNonFastForwards

$ git config --system receive.denyNonFastForwards true

稍後你會看到,用服務器端的接收鉤子也能達到同樣的目的。這個方法可以做更細緻的控制,例如:禁用特定的用戶做強制更新。

receive.denyDeletes

規避denyNonFastForwards策略的方法之一就是用戶刪除分支,然後推回新的引用。在更新的 Git 版本中(從1.6.1版本開始),把receive.denyDeletes設置爲true:

$ git config --system receive.denyDeletes true

這樣會在推送過程中阻止刪除分支和標籤 — 沒有用戶能夠這麼做。要刪除遠程分支,必須從服務器手動刪除引用文件。通過用戶訪問控制列表也能這麼做,在本章結尾將會介紹這些有趣的方式。


本文來自 http://git-scm.com/ 保存下來,方便自己查閱。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章