其實上一篇《開發中關於Git那些事》寫的內容僅僅是Git的冰山一角,若是你認爲Git就是簡簡單單的幾行命令,那隻能說明你尚未真正瞭解Git這個強大的內容尋址文件系統。這篇文章,仍是接着介紹一些實用可是不多有人知曉的一些命令,比如說具備魔性的Git變基(git rebase)以及經常使用的GUI。
我以前詢問過一些人,討論到Git這塊,他們當中有的直接使用GUI,說簡單省事。其實,每個GUI都有它的側重點,並非全部的GUI都適合用。我卻是建議你們使用命令行。況且有些功能GUI不必定支持,並且有時候一行命令的事,還要點來點去,也不省事。以前看到過一篇文章,是關於如何使用Vim編輯器的,對,你們平時開發習慣了IDE,愛上了IDE。可是好的程序員怎麼會由於簡單省事而放棄學習呢。這樣說可能更好提現,學習任意一款IDE,你都須要耗時好久,可是若是你平時習慣了使用Vim編輯器,愛上用Vim編輯器寫代碼,那麼任意一款集成Vim編輯器的IDE,一上來就會很是順手。一樣的道理,若是你瞭解了Git內部原理,平時習慣使用命令處理,那麼給你任意一款GitGUI,相信你一看就會用,並且很快就上手。因此,學習順序有時候很重要,基礎紮實了,纔不會被問題難倒,地基決定高度。html
默認使用Vim編輯器,固然可使用core.editor修改git
git config --global core.editor emacs
默認使用less,可使用core.pager來設置爲more或則其餘,也可使用空字符串,關閉分頁,一次性加載全部內容程序員
git config --global core.pager ''
使用到color.ui,默認auto,若是你不喜歡可使用false關閉。github
git config --global color.ui false
其實若是想具體到某些特定命令,都是有true、false 或 always能夠設置的,好比如下服務器
color.branch color.diff color.interactive color.status
以上每一個配置項都有子選項,它們能夠被用來覆蓋其父設置,以達到爲輸出的各個部分着色的目的。例如,爲了讓 diff 的輸出信息以藍色前景、黑色背景和粗體顯示,你能夠運行app
git config --global color.diff.meta "blue black bold"
你能設置的顏色有:normal、black、red、green、yellow、blue、magenta、cyan 或 white。正如以 上例子設置的粗體屬性,想要設置字體屬性的話,能夠選擇包括:bold、dim、ul(下劃線)、blink 、reverse(交換前景色和背景色)。less
git branch -v
該命令顯示本地分支最後一次提交說明編輯器
* dev cdc7241a fixbug master f586f6b5 ****
若是須要顯示本地和遠程,加上-a即git branch -v -a
學習
* dev cdc7241a fixbug master f586f6b5 **** remotes/origin/HEAD -> origin/master remotes/origin/dev cdc7241a fixbug remotes/origin/master f586f6b5 **** remotes/origin/oldIm 97d131bb 2.5.1 封版
git branch -vv
除了具備git branch -v
命令的做用,還能夠顯示出每個分支正在跟蹤哪一個遠程分支,以及本地分支與遠程分支是不是領先、落後。一樣,若是想看遠程加上-a
,也就是all(全部),反正我就是這麼記憶的字體
* dev 6512ef90 [origin/dev: ahead 1] test master 78b4b30a [origin/master] 171227122 2.12.2 封版
其實在Git當中整合兩個分支的方式除了merge,還有一種方式,那就是rebase。如上圖,如今要合併C3和C4,若是使用merge合併是這樣子的。它會把兩個分支的最新快照(C3 和 C4)以及兩者最近的共同祖先(C2)進行三方合併,合併的結果是生成一個新的快照(並提交)。
可是若是使用rebase:你能夠提取在 C4 中引入的補丁和修改,而後在 C3 的基礎上再應用一次。在 Git 中,這種操做就叫作變基。你可使用 rebase 命令將提交到某一分支上的全部修改都移至另外一分支上,就好像「從新播放」同樣。
執行步驟就是,首先切換的experiment分支git checkout experiment
,而後運行git rebase master
,此時準備「重演」,接下來就是看你要在哪一個分支重演,就切換到哪一個分支,這邊在主分支重演,切換到主分支git checkout master
,而後整合便可git merge experiment
。其實此時的merge和以前的merge不同,這邊的merge只須要進行一次fast-forward,就是快速合併,head快速前進到C4'。
它的原理是首先找到這兩個分支(即當前分支 experiment、變基操做的目標基底分支 master)的最近共同祖 先 C2,而後對比當前分支相對於該祖先的歷次提交,提取相應的修改並存爲臨時文件,而後將當前分支指向目標基底C3, 最後以此將以前另存爲臨時文件的修改依序應用。
git checkout experiment git rebase master First, rewinding head to replay your work on top of it... Applying: added staged command
git checkout master git merge experiment
此時,C4' 指向的快照就和上面使用merge命令的例子中 C5 指向的快照如出一轍了。這兩種整合方法的最終結果沒有任何區別,可是變基使得提交歷史更加整潔。你在查看一個通過變基的分支的歷史記錄時會發現,儘管實際的開發工做是並行的,但它們看上去就像是前後串行的同樣,提交歷史是一條直線沒有分叉。
直接看下圖,如今我有這樣的需求,就是將C8,C9提交到主分支,可是不要C3,你如何作?
其實辦法老是有的,在前篇文章中,有講到git stash命令,其實,咱們能夠在client分支找到C3的哈希值直接執行git reset 哈希值(C3)
而後把C8,C9的修改直接git stash 貯存起來,切換到master分支,來個git stash pop
搞定。如今咱們使用變基來操做,感覺下變基的魔性。
git rebase --onto master server client
以上命令含義:取出 client 分支,找出處於 client 分支和 server 分支的共同祖先以後的修改,而後把它們在 master 分支上重演一遍。
如今能夠快進合併 master 分支了。
git checkout master git merge client
再舉一個例子,也是關於git rebase --onto的使用
H---I---J topicB / E---F---G topicA / A---B---C---D master git rebase --onto master topicA topicB H'--I'--J' topicB / | E---F---G topicA |/ A---B---C---D master This is useful when topicB does not depend on topicA.
這樣的例子好多,感興趣可使用git rebase --help
查看。
注意事項
這點必定要看,不要對在你的倉庫外還有副本的分支執行變基。也就是說,一我的開發隨便搞,多人開發有原則的搞。若是你不遵循這個原則,多人開發出現問題別來找我。
爲何呢?假若有我的在本地使用了merge合併分支後,push到了遠程服務器,後來他感受不爽,想經過變基處理,恰是這個時候你pull了服務器的代碼,那就會出現問題。問題就是,之後看記錄會出現相同的提交,原本張三想丟棄的東西被你保留了。若是想看詳細舉例,推薦查看Pro Git這本書中關於Git變基一節。
總之,只要是你的代碼和你創建的分支,尚未執行push以前,隨意搞,push後就不要再想着使用變基了,避免出問題。若是你更喜歡merge,喜歡看Git實際發生的事,那就使用merge吧。反之,你更喜歡流水線同樣的記錄,從前到後,沒有一堆堆複雜的合併,那就用rebase。
十幾款GUI,點開查看便可。
SourceTree
GitHub Desktop
TortoiseGit
GitUp ...... 我比較喜歡GitUp,簡潔些。可是我仍舊在使用命令行,就當爲了給電腦省空間吧。