上一節(jié)操作中每次提交都要手動(dòng)輸入用戶名和密碼,若想避免這些麻煩,可以在系統(tǒng)中創(chuàng)建 SSH 公私鑰,并將公鑰放到 GitHub 指定位置。如此操作即可生成 GitHub 賬戶對(duì)于當(dāng)前系統(tǒng)中的 Git 授權(quán)。
終端執(zhí)行 ssh-keygen
命令按幾次回車生成公私鑰,公私鑰存放在家目錄下的隱藏目錄 .ssh
中的兩個(gè)文件下:
將 ~/.ssh/id_rsa.pub
文件中的公鑰內(nèi)容復(fù)制出來,實(shí)驗(yàn)環(huán)境中可用使用右側(cè)工具欄中的剪切板復(fù)制:
Title 自定義,把剪切板中的內(nèi)容粘貼到 Key 中,點(diǎn)擊綠色按鈕添加 SSH Key 即可:
回到倉(cāng)庫(kù)主目錄,點(diǎn)擊下圖所示的綠色按鈕,點(diǎn)擊紫色框中的 “Use SSH”,然后復(fù)制這個(gè)鏈接,在實(shí)驗(yàn)環(huán)境里刪除原倉(cāng)庫(kù),使用此鏈接重新克隆倉(cāng)庫(kù)。克隆倉(cāng)庫(kù)是需要確認(rèn)連接,輸入 yes 即可:
重要的一點(diǎn):只有使用這種 git 開頭的地址克隆倉(cāng)庫(kù),SSH 關(guān)聯(lián)才會(huì)起作用。
使用 SSH 的好處主要有兩點(diǎn):1、免密碼推送,執(zhí)行 git push
時(shí)不再需要輸入用戶名和密碼了;2、提高數(shù)據(jù)傳輸速度。它不是必須的,比如在實(shí)驗(yàn)樓的課程中挑戰(zhàn)環(huán)境是不可保存的,一次性的,這種環(huán)境就沒有必要?jiǎng)?chuàng)建 SSH 了,因?yàn)橄噍^好處來說,還是太麻煩了。
上一節(jié)課程中的操作,有些命令的重復(fù)度極高,比如 git status
和 git branch -avv
等,Git 可以對(duì)這些命令設(shè)置別名,以便簡(jiǎn)化對(duì)它們的使用,設(shè)置別名的命令是 git config --global alias.[別名] [原命令]
,如果原命令中有選項(xiàng),需要加引號(hào)。別名是自定義的,可以隨意命名,設(shè)置后,原命令和別名具有同等作用。操作如下:
自己設(shè)置的別名要記住,也可以使用 git config -f
命令查看或者查看配置文件。下面的命令將使用這些別名。
在介紹分支前,先講解另一個(gè)命令 git fetch
,它的作用是將遠(yuǎn)程倉(cāng)庫(kù)的分支信息拉取到本地倉(cāng)庫(kù),注意,僅僅是更新了本地的遠(yuǎn)程分支信息,也就是執(zhí)行 git branch -avv
命令時(shí),查看到的 remotes
開頭的行的分支信息。舉例說明一下,首先,我們?cè)?GitHub 頁面上對(duì) one.txt 文件進(jìn)行修改并增加一次提交。
提交完成后,提交數(shù)變成 3 個(gè),點(diǎn)下圖紫色框中的鏈接可以看到提交記錄:
在實(shí)驗(yàn)環(huán)境中執(zhí)行 git fetch
命令,然后執(zhí)行 git branch -avv
查看分支信息:
可以看到,本地分支 master 的版本號(hào)無變化,而遠(yuǎn)程分支已經(jīng)更新。所以,fetch
命令的作用是刷新保存在本地倉(cāng)庫(kù)的遠(yuǎn)程分支信息,此命令需要聯(lián)網(wǎng)。此時(shí)若想使本地 master 分支的提交版本為最新,可以執(zhí)行 git pull
命令來拉取遠(yuǎn)程分支到本地,pull
是拉取遠(yuǎn)程倉(cāng)庫(kù)的數(shù)據(jù)到本地,需要聯(lián)網(wǎng),而由于前面執(zhí)行過 git fetch
命令,所以也可以執(zhí)行 git rebase origin/master
命令來實(shí)現(xiàn) “使本地 master 分支基于本地 origin/master 分支”,rebase
命令在后面還會(huì)經(jīng)常用到,這里只需按部就班操作即可:
可以看到,遠(yuǎn)程倉(cāng)庫(kù) master 分支、本地倉(cāng)庫(kù)的 origin/master 分支、本地倉(cāng)庫(kù)的 master 分支已經(jīng)一致。
下面介紹 Git 作為分布式版本控制器最強(qiáng)大的功能:分支管理。
分支在項(xiàng)目開發(fā)中作用重大,多人協(xié)作時(shí)尤其不可或缺。例如一個(gè)項(xiàng)目上線了 1.0 版本,研發(fā)部門需要開發(fā) 1.1、1.2 兩個(gè)測(cè)試版,增加不同的新功能,測(cè)試版的代碼顯然不能在正式版所在的分支上,此時(shí)需要新的分支來存放不同版次的代碼。再例如實(shí)驗(yàn)樓的課程團(tuán)隊(duì)在維護(hù)課程倉(cāng)庫(kù)時(shí),每個(gè)人都有各自的分支,在自己的分支上進(jìn)行修改,然后向 master 分支提 PR(pull request),最后從 master 分支推送到線上。
首先,克隆遠(yuǎn)程倉(cāng)庫(kù)到本地,進(jìn)入倉(cāng)庫(kù)主目錄,執(zhí)行 git br
查看分支信息:
執(zhí)行 git branch [分支名]
可以創(chuàng)建新的分支:
此命令創(chuàng)建新分支后并未切換到新分支,還是在 master 分支上,執(zhí)行 git checkout [分支名]
切換分支,checkout
也是常用命令,先給它設(shè)置別名,然后切換分支:
創(chuàng)建新分支還要手動(dòng)切換太麻煩,介紹另一個(gè)常用的命令 git checkout -b [分支名]
創(chuàng)建分支并切換到新分支:
如上圖所示的分支信息,前兩行是新建的本地分支信息,它們的版本號(hào)與主分支 master 一致,這是因?yàn)樵谀膫€(gè)分支上創(chuàng)建新分支,新分支的提交記錄就與哪個(gè)分支一致。新建分支并無跟蹤任何遠(yuǎn)程分支,所以沒有 master 分支中的中括號(hào)和括號(hào)內(nèi)的藍(lán)色遠(yuǎn)程分支名。
假設(shè)我們要在當(dāng)前分支 dev1 上開發(fā)一個(gè)新的功能,需要增加一個(gè)文件 new_func,然后生成一個(gè)新的提交:
好,新功能已經(jīng)寫好并提交到了版本區(qū),現(xiàn)在要推送了,推送到哪里呢?正常邏輯當(dāng)然要推送到遠(yuǎn)程倉(cāng)庫(kù)的同名分支,不過現(xiàn)在遠(yuǎn)程倉(cāng)庫(kù)里只有一個(gè)分支:
上圖紫色框中是一個(gè)下拉按鈕,點(diǎn)擊后顯示倉(cāng)庫(kù)中的全部分支,按鈕上顯示的是當(dāng)前所在分支。
執(zhí)行 git push [主機(jī)名] [本地分支名]:[遠(yuǎn)程分支名]
即可將本地分支推送到遠(yuǎn)程倉(cāng)庫(kù)的分支中,通常冒號(hào)前后的分支名是相同的,如果是相同的,可以省略 :[遠(yuǎn)程分支名]
,如果遠(yuǎn)程分支不存在,會(huì)自動(dòng)創(chuàng)建:
上圖命令可以簡(jiǎn)寫為 git push origin dev1
。注意哦,這是我們創(chuàng)建 SSH 關(guān)聯(lián)后第一次執(zhí)行 push
命令,可以看到傳輸速度有明顯的提高,更重要的是,不再需要重復(fù)輸入用戶名和密碼了,另外打印信息的第一行是警告信息,因?yàn)槭沁@個(gè)分支的第一次推送嘛,下次執(zhí)行推送就不會(huì)再出現(xiàn)了。現(xiàn)在執(zhí)行 git br
查看一下分支情況:
可以看到,遠(yuǎn)程分支 origin/dev1 的信息已經(jīng)在本地存在,且與本地同名分支一致。再看下 GitHub 頁面的情況:
很好,與預(yù)期毫無二致。
現(xiàn)在有個(gè)問題,當(dāng)我們?cè)俅卧?dev1 分支上修改并提交,推送到遠(yuǎn)程倉(cāng)庫(kù)時(shí)還是要輸入上面的那個(gè)長(zhǎng)長(zhǎng)的命令,好不方便。如果能和 master 分支一樣跟蹤遠(yuǎn)程同名分支,就可以直接使用 git push
命令推送了。有辦法的,執(zhí)行這個(gè)命令 git branch -u [主機(jī)名/遠(yuǎn)程分支名] [本地分支名]
將本地分支與遠(yuǎn)程分支關(guān)聯(lián),或者說使本地分支跟蹤遠(yuǎn)程分支。如果是設(shè)置當(dāng)前所在分支跟蹤遠(yuǎn)程分支,最后一個(gè)參數(shù)本地分支名可以省略不寫:
這個(gè)命令的 -u
選項(xiàng)是 --set-upstream
的縮寫。可不可以讓本地分支跟蹤遠(yuǎn)程非同名分支呢?可以的,盡管幾乎遇不到這種自找麻煩的需求。可不可以撤銷本地分支對(duì)遠(yuǎn)程分支的跟蹤呢?也是可以的,執(zhí)行 git branch --unset-upstream [分支名]
即可撤銷該分支對(duì)遠(yuǎn)程分支的跟蹤,同樣地,如果撤銷當(dāng)前所在的分支的跟蹤,分支名可以省略不寫:
問題又來了,前面的操作是先將本地分支推送到遠(yuǎn)程倉(cāng)庫(kù),使遠(yuǎn)程倉(cāng)庫(kù)創(chuàng)建新分支,然后再執(zhí)行命令使本地分支跟蹤遠(yuǎn)程分支,有沒有辦法在推送時(shí)就自動(dòng)跟蹤遠(yuǎn)程分支呢?有的,在推送的時(shí)候,加個(gè) --set-upstream
或其簡(jiǎn)寫 -u
選項(xiàng)即可,現(xiàn)在切換到 dev 分支試一下這個(gè)命令:
接下來,介紹一下刪除分支的方法。
首先,刪除遠(yuǎn)程分支,使用 git push [主機(jī)名] :[遠(yuǎn)程分支名]
,如果一次性刪除多個(gè),可以這樣:git push [主機(jī)名] :[遠(yuǎn)程分支名] :[遠(yuǎn)程分支名] :[遠(yuǎn)程分支名]
。此命令的原理是將空分支推送到遠(yuǎn)程分支,結(jié)果自然就是遠(yuǎn)程分支被刪除。另一個(gè)刪除遠(yuǎn)程分支的命令:git push [主機(jī)名] --delete [遠(yuǎn)程分支名]
。刪除遠(yuǎn)程分支的命令可以在任意本地分支中執(zhí)行。兩個(gè)命令分別試一下:
可以看到本地倉(cāng)庫(kù)已經(jīng)沒有遠(yuǎn)程分支 dev 和 dev1 的分支信息。查看 GitHub 倉(cāng)庫(kù)頁面:
也只剩 master 一個(gè)分支。操作成功。
回到實(shí)驗(yàn)環(huán)境,使用 git branch -D [分支名]
刪除本地分支,同樣地,此命令也可以一次刪除多個(gè),將需要?jiǎng)h除的分支名羅列在命令后面即可。在此之前,先介紹一個(gè)極少用到的命令:給本地分支改名 git branch -m [原分支名] [新分支名]
,若修改當(dāng)前所在分支的名字,原分支名可以省略不寫:
好,現(xiàn)在要一次性刪除本地分支 ved 和 dev1。需要注意的一點(diǎn):當(dāng)前所在的分支不能被刪除。切換到 master 分支,然后執(zhí)行 git branch -D ved dev1
命令:
執(zhí)行 git branch -avv
查看當(dāng)前倉(cāng)庫(kù)分支狀態(tài):
很好,一切都回到了課程開始時(shí)的樣子,就像什么都沒有發(fā)生。本節(jié)課程就到這里。