用git config
配置 Git,要作的第一件事就是設置名字和郵箱地址:git
$ git config --global user.name "John Doe" $ git config --global user.email johndoe@example.com
從如今開始,你會了解到一些相似以上但更爲有趣的設置選項來自定義 Git。程序員
先過一遍第一章中提到的 Git 配置細節。Git 使用一系列的配置文件來存儲你定義的偏好,它首先會查找/etc/gitconfig
文件,該文件含有 對系統上全部用戶及他們所擁有的倉庫都生效的配置值(譯註:gitconfig是全局配置文件), 若是傳遞--system
選項給git config
命令, Git 會讀寫這個文件。編程
接下來 Git 會查找每一個用戶的~/.gitconfig
文件,你能傳遞--global
選項讓 Git讀寫該文件。vim
最後 Git 會查找由用戶定義的各個庫中 Git 目錄下的配置文件(.git/config
),該文件中的值只對屬主庫有效。 以上闡述的三層配置從通常到特殊層層推動,若是定義的值有衝突,之後面層中定義的爲準,例如:在.git/config
和/etc/gitconfig
的較量中, .git/config
取得了勝利。雖然你也能夠直接手動編輯這些配置文件,可是運行git config
命令將會來得簡單些。服務器
Git 可以識別的配置項被分爲了兩大類:客戶端和服務器端,其中大部分基於你我的工做偏好,屬於客戶端配置。儘管有數不盡的選項,但我只闡述 其中常用或者會對你的工做流產生巨大影響的選項,若是你想觀察你當前的 Git 能識別的選項列表,請運行app
$ git config --help
git config
的手冊頁(譯註:以man命令的顯示方式)很是細緻地羅列了全部可用的配置項。less
Git默認會調用你的環境變量editor定義的值做爲文本編輯器,若是沒有定義的話,會調用Vi來建立和編輯提交以及標籤信息, 你可使用core.editor
改變默認編輯器:編輯器
$ git config --global core.editor emacs
如今不管你的環境變量editor被定義成什麼,Git 都會調用Emacs編輯信息。工具
若是把此項指定爲你係統上的一個文件,當你提交的時候, 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指定 Git 運行諸如log
、diff
等所使用的分頁器,你能設置成用more
或者任何你喜歡的分頁器(默認用的是less
), 固然你也能夠什麼都不用,設置空字符串:
$ git config --global core.pager ''
這樣無論命令的輸出量多少,都會在一頁顯示全部內容。
若是你要建立經簽署的含附註的標籤(正如第二章所述),那麼把你的GPG簽署密鑰設置爲配置項會更好,設置密鑰ID以下:
$ git config --global user.signingkey <gpg-key-id>
如今你可以簽署標籤,從而沒必要每次運行git tag
命令時定義密鑰:
$ git tag -s <tag-name>
正如第二章所述,你能在項目庫的.gitignore
文件裏頭用模式來定義那些無需歸入 Git 管理的文件,這樣它們不會出如今未跟蹤列表, 也不會在你運行git add
後被暫存。然而,若是你想用項目庫以外的文件來定義那些需被忽略的文件的話,用core.excludesfile
通知 Git 該文件所處的位置,文件內容和.gitignore
相似。
該配置項只在 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
爲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 的版本很老,你就要用到和具體命令有關的顏色配置選項,它們都能被置爲true
、false
或always
:
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-file
和new-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工具,例如把extDiff
和extMerge
改爲KDiff3,要作的僅僅是編輯extMerge
腳本文件:
$ cat /usr/local/bin/extMerge #!/bin/sh /Applications/kdiff3.app/Contents/MacOS/kdiff3 $*
如今 Git 會使用KDiff3來作比較、合併和解決衝突。
Git預先設置了許多其餘的合併和解決衝突的工具,而你沒必要設置cmd。能夠把合併工具設置爲:kdiff三、opendiff、tkdiff、meld、xxdiff、emerge、vimdiff、gvimdiff。若是你不想用到KDiff3的全部功能,只是想用它來合併,那麼kdiff3正符合你的要求,運行:
$ git config --global merge.tool kdiff3
若是運行了以上命令,沒有設置extMerge
和extDiff
文件,Git 會用KDiff3作合併,讓一般內設的比較工具來作比較。
格式化與空白是許多開發人員在協做時,特別是在跨平臺狀況下,遇到的使人頭疼的細小問題。因爲編輯器的不一樣或者Windows程序員在跨平臺項目中的文件行尾加入了回車換行符,一些細微的空格變化會不經意地進入你們合做的工做或提交的補丁中。不用怕,Git 的一些配置選項會幫助你解決這些問題。
假如你正在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
Git預先設置了一些選項來探測和修正空白問題,其4種主要選項中的2個默認被打開,另2個被關閉,你能夠自由地打開或關閉它們。
默認被打開的2個選項是trailing-space
和space-before-tab
,trailing-space
會查找每行結尾的空格,space-before-tab
會查找每行開頭的製表符前的空格。
默認被關閉的2個選項是indent-with-non-tab
和cr-at-eol
,indent-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服務器端的配置選項並很少,但仍有一些饒有生趣的選項值得你一看。
Git默認狀況下不會在推送期間檢查全部對象的一致性。雖然會確認每一個對象的有效性以及是否仍然匹配SHA-1檢驗和,但 Git 不會在每次推送時都檢查一致性。對於 Git 來講,庫或推送的文件越大,這個操做代價就相對越高,每次推送會消耗更多時間,若是想在每次推送時 Git 都檢查一致性,設置 receive.fsckObjects
爲true來強迫它這麼作:
$ git config --system receive.fsckObjects true
如今 Git 會在每次推送生效前檢查庫的完整性,確保有問題的客戶端沒有引入破壞性的數據。
若是對已經被推送的提交歷史作衍合,繼而再推送,又或者以其它方式推送一個提交歷史至遠程分支,且該提交歷史沒在這個遠程分支中,這樣的推送會被拒絕。這一般是個很好的禁止策略,但有時你在作衍合併肯定要更新遠程分支,能夠在push命令後加-f
標誌來強制更新。
要禁用這樣的強制更新功能,能夠設置receive.denyNonFastForwards
:
$ git config --system receive.denyNonFastForwards true
稍後你會看到,用服務器端的接收鉤子也能達到一樣的目的。這個方法能夠作更細緻的控制,例如:禁用特定的用戶作強制更新。
規避denyNonFastForwards
策略的方法之一就是用戶刪除分支,而後推回新的引用。在更新的 Git 版本中(從1.6.1版本開始),把receive.denyDeletes
設置爲true:
$ git config --system receive.denyDeletes true
這樣會在推送過程當中阻止刪除分支和標籤 — 沒有用戶可以這麼作。要刪除遠程分支,必須從服務器手動刪除引用文件。經過用戶訪問控制列表也能這麼作,在本章結尾將會介紹這些有趣的方式