從0開始學習 GitHub 系列之「Git 進階」

關於 Git 相信你們看了以前一系列的文章已經初步會使用了, 可是關於Git還有不少知識與技巧是你不知道的,今天就來給你們介紹下一些 Git 進階的知識。git

1. 用戶名和郵箱

咱們知道咱們進行的每一次commit都會產生一條log,這條log標記了提交人的姓名與郵箱,以便其餘人方便的查看與聯繫提交人,因此咱們在進行提交代碼的第一步就是要設置本身的用戶名與郵箱。執行如下代碼:vim

git config --global user.name "stormzhang"
git config --global user.email "stormzhang.dev@gmail.com"

以上進行了全局配置,固然有些時候咱們的某一個項目想要用特定的郵箱,這個時候只需切換到你的項目,以上代碼把 --global 參數去除,再從新執行一遍就ok了。微信

PS:咱們在 GitHub 的每次提交理論上都會在 主頁的下面產生一條綠色小方塊的記錄,若是你確認你提交了,可是沒有綠色方塊顯示,那確定是你提交代碼配置的郵箱跟你 GitHub 上的郵箱不一致,GitHub 上的郵箱能夠到 Setting -> Emails裏查看。app

2. alias

咱們知道咱們執行的一些Git命令其實操做很頻繁的相似有:編輯器

git commit
git checkout
git branch
git status
...

這些操做很是頻繁,每次都要輸入徹底是否是有點麻煩,有沒有一種簡單的縮寫輸入呢?好比我對應的直接輸入如下:gradle

git c
git co
git br
git s
...

是否是很簡單快捷啊?這個時候就用到了alias配置了,翻譯過來就是別名的意思,輸入如下命令就能夠直接知足了以上的需求。ui

git config --global alias.co checkout  # 別名
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.br branch

固然以上別名不是固定的,你徹底能夠根據本身的習慣去定製,除此以外還能夠設置組合,好比:spa

git config --global alias.psm 'push origin master'
git config --global alias.plm 'pull origin master'

以後常常用到的git push origin mastergit pull origin master 直接就用 git psmgit plm 代替了,是否是很方便?插件

另外這裏給你們推薦一個很強大的 alias 命令,咱們知道咱們輸入 git log 查看日誌的時候是相似這樣的:翻譯

告訴你們一個比較屌的命令,輸入git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative 而後日誌這樣了:

是否是比較清晰,整個分支的走向也很明確,可是每次都要輸這麼一大串是否是也很煩?這時候你就該想到 alias 啊:

git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative"

這樣之後直接輸入 git lg 就好了。

3. 其餘配置

固然還有一些其餘有用的配置,默認狀況下 git 用的編輯器是 vi ,若是不喜歡能夠改爲其餘編輯器,好比我習慣 vim 。

git config --global core.editor "vim"  # 設置Editor使用vim

大家若是喜歡其餘編輯器可自行搜索配置,前提是本機有安裝。

有些人納悶個人終端怎麼有各類顏色,本身卻不是這樣的,那是由於大家沒有開啓給 Git 着色,輸入以下命令便可:

git config --global color.ui true

還有些其餘的配置如:

git config --global core.quotepath false # 設置顯示中文文件名

以上基本全部的配置就差很少了,默認這些配置都在 ~/.gitconfig 文件下的,你能夠找到這個文件查看本身的配置,也能夠輸入 git config -l 命令查看。

4. diff

diff命令算是很經常使用的,使用場景是咱們常常在作代碼改動,可是有的時候2天前的代碼了,作了哪些改動都忘記了,在提交以前須要確認下,這個時候就能夠用diff來查看你到底作了哪些改動,舉個例子,好比我有一個 a.md 的文件,我如今作了一些改動,而後輸入 git diff 就會看到以下:

紅色的部分前面有個 - 表明我刪除的,綠色的部分前面有個 + 表明我增長的,因此從這裏大家很一目瞭然的知道我到底對這個文件作了哪些改動。

值得一提的是直接輸入 git diff 只能比較當前文件和暫存區文件差別,什麼是暫存區?就是你尚未執行 git add 的文件。

固然跟暫存區作比較以外,他還能夠有其餘用法,如比較兩次 commit 之間的差別,比較兩個分支之間的差別,比較暫存區和版本庫之間的差別等,具體用法以下:

git diff <$id1> <$id2>   # 比較兩次提交之間的差別
git diff <branch1>..<branch2> # 在兩個分支之間比較 
git diff --staged   # 比較暫存區和版本庫差別

5. checkout

咱們知道 checkout 通常用做切換分支使用,好比切換到 develop 分支,能夠執行:

git checkout develop

可是 checkout 不僅用做切換分支,他能夠用來切換tag,切換到某次commit,如:

git checkout v1.0
git checkout ffd9f2dd68f1eb21d36cee50dbdd504e95d9c8f7 # 後面的一長串是commit_id,是每次commit的SHA1值,能夠根據 git log 看到。

除了有「切換」的意思,checkout 還有一個撤銷的做用,舉個例子,假設咱們在一個分支開發一個小功能,剛寫完一半,這時候需求變了,並且是大變化,以前寫的代碼徹底用不了了,好在你剛寫,甚至都沒有 git add 進暫存區,這個時候很簡單的一個操做就直接把原文件還原:

git checkout a.md

這裏稍微提下,checkout 命令只能撤銷尚未 add 進暫存區的文件。

6. stash

設想一個場景,假設咱們正在一個新的分支作新的功能,這個時候忽然有一個緊急的bug須要修復,並且修復完以後須要當即發佈。固然你說我先把剛寫的一點代碼進行提交不就好了麼?這樣理論上固然是ok的,可是這會產品垃圾commit,原則上咱們每次的commit都要有實際的意義,你的代碼只是剛寫了一半,尚未什麼實際的意義是不建議就這樣commit的,那麼有沒有一種比較好的辦法,可讓我暫時切到別的分支,修復完bug再切回來,並且代碼也能保留的呢?

這個時候 stash 命令就大有用處了,前提是咱們的代碼沒有進行 commit ,哪怕你執行了 add 也不要緊,咱們先執行

git stash

命令,什麼意思呢?意思就是把當前分支全部沒有 commit 的代碼先暫存起來,這個時候你再執行 git status 你會發現當前分支很乾淨,幾乎看不到任何改動,你的代碼改動也看不見了,但實際上是暫存起來了。執行

git stash list

你會發現此時暫存區已經有了一條記錄。

這個時候你能夠切換會其餘分支,趕忙把bug修復好,而後發佈。以後一切都解決了,你再切換回來繼續作你以前沒作完的功能,可是以前的代碼怎麼還原呢?

git stash apply

你會發現你以前的代碼所有又回來了,就好像一切都沒發生過同樣,緊接着你最好須要把暫存區的此次 stash 記錄刪除,執行:

git stash drop

就把最近一條的 stash 記錄刪除了,是否是很方便?其實還有更方便的,你可使用:

git stash pop

來代替 apply 命令,popapply 的惟一區別就是 pop 不但會幫你把代碼還原,還自動幫你把這條 stash 記錄刪除,省的本身再 drop 一次了,爲了驗證你能夠緊接着執行 git stash list 命令來確認是否是已經沒有記錄了。

最後還有一個命令介紹下:

git stash clear

就是清空全部暫存區的記錄,drop 是隻刪除一條,固然後面能夠跟 stash_id 參數來刪除指定的某條記錄,不跟參數就是刪除最近的,而 clear 是清空。

7. merge & rebase

咱們知道 merge 分支是合併的意思,咱們在一個 featureA 分支開發完了一個功能,這個時候須要合併到主分支 master 上去,咱們只須要進行以下操做:

git checkout master
git merge featureA

其實 rebase 命令也是合併的意思,上面的需求咱們同樣能夠以下操做:

git checkout master
git rebase featureA

rebasemerge 的區別大家能夠理解成有兩個書架,你須要把兩個書架的書整理到一塊兒去,第一種作法是 merge ,比較粗魯暴力,就直接騰出一塊地方把另外一個書架的書所有放進去,雖然暴力,可是這種作法你能夠知道哪些書是來自另外一個書架的;第二種作法就是 rebase ,他會把兩個書架的書先進行比較,按照購書的時間來給他從新排序,而後從新放置好,這樣作的好處就是合併以後的書架看起來頗有邏輯,可是你很難清晰的知道哪些書來自哪一個書架的。

只能說各有好處的,不一樣的團隊根據不一樣的須要以及不一樣的習慣來選擇就好。

8. 解決衝突

假設這樣一個場景,A和B兩位同窗各自開了兩個分支來開發不一樣的功能,大部分狀況下都會盡可能互不干擾的,可是有一個需求A須要改動一個基礎庫中的一個類的方法,不巧B這個時候因爲業務須要也改動了基礎庫的這個方法,由於這種狀況比較特殊,A和B都認爲不會對地方形成影響,等兩人各自把功能作完了,須要合併的到主分支 master 的時候,咱們假設先合併A的分支,這個時候沒問題的,以後再繼續合併B的分支,這個時候想一想也知道就有衝突了,由於A和B兩我的同時更改了同一個地方,Git 自己他無法判斷大家兩個誰更改的對,可是這個時候他會智能的提示有 conflicts ,須要手動解決這個衝突以後再從新進行一次 commit 提交。我隨便在項目搞了一個衝突作下示例:

以上截圖裏就是衝突的示例,衝突的地方由 ==== 分出了上下兩個部分,上部分一個叫 HEAD 的字樣表明是我當前所在分支的代碼,下半部分是一個叫 baidu_activity 分支的代碼,能夠看到 HEAD 對 gradle 插件進行了升級,同時新增了一個插件,因此咱們很容易判斷哪些代碼該保留,哪些代碼該刪除,咱們只須要移除掉那些老舊代碼,並且同時也要把那些 <<< HEAD==== 以及 >>>>>>baidu_activity 這些標記符號也一併刪除,最後進行一次 commit 就ok了。

咱們在開發的過程當中通常都會約定儘可能你們寫的代碼不要彼此影響,以減小出現衝突的可能,可是衝突總歸沒法避免的,咱們須要瞭解並掌握解決衝突的方法。


本文原創發佈於微信公衆號 AndroidDeveloper「googdev」,轉載請務必註明出處!

相關文章
相關標籤/搜索