上篇文章咱們主要簡單的介紹了有關git的一些基本常識和一些簡單的命令。但那終究是皮毛,咱們使用git最主要的目的仍是管理咱們的項目,多人協做。本篇文章主要涉及如下兩個大模塊:git
1、分支
在介紹分支以前,咱們首先先考慮爲何須要引入分支這個概念,究竟有哪些沒法解決的問題,須要咱們引入新的概念。github
在沒有分支這個概念以前,咱們對於一個項目的開發只有一個進度,可是一旦發現項目的以前版本的某個節點出現bug,難道放棄到目前爲止的全部開發,回退到bug節點進行修復嗎?這是第一個亟待解決的問題。服務器
對於咱們軟件業來講,一個軟件確定有不止一個版本,那麼你不能要求全部用戶所有升級到最新版本。那麼對於同一個項目,難道咱們放棄那些仍使用舊版本的用戶,直接在原項目中開發新功能嗎?這也是一個未解決的問題。ssh
下面咱們從解決上述問題出發,引出分支的概念。分佈式
咱們沿着一條路進行開發,head指向當前最新一次commit,整條線路咱們管它叫作分支(branch),可是咱們發現以前的某次提交中出現bug,咱們固然可使用reset指令回退版本,但會丟失掉很大一部分代碼。學習
針對這種狀況,咱們能夠建立一個分支用於修復bug,而主分支繼續開發,等bug修復完成以後,兩分支合併便可。fetch
對於上述的第二種問題,版本維護的問題。加密
這樣在不一樣分支上的開發,兩個分支徹底不相互影響。一條分支維護這舊版本,另外一條分支開發着新功能,等到舊版本再也不須要維護時,刪除該分支便可。那下面咱們開始介紹分支的的相關命令。版本控制
一、git branch
和branch相關的命令主要有四個。指針
git branch:顯示當前版本庫中全部分支
git branch <branchname>:建立一個分支
咱們都知道,版本庫中有一個head指針,它指向的是當前分支的最新提交,而咱們的上述命令只負責建立一個分支,可是不會將head指針移動到該分支上,也就是說head指針仍是指向原分支。
git branch -d <branchname>;嘗試刪除某個分支 git branch -D <branchname>:強制刪除某個分支
在執行分支刪除命令的時候,若是該分支沒有合併到其餘分支中,git會拒絕刪除,這是爲了防誤刪。可是若是你實在不滿意對新分支的開發也能夠強制刪除。
下面兩個命令主要用於修改分支的名稱。
git branch -m <oldbranchname> <newbranchname>:嘗試修改 git branch -M <oldbranchname> <newbranchname>:強制修改
若是重命名的分支名已經存在的話將會被拒絕。那麼強制修改分支名稱將會覆蓋被同名的分支,因此全部強制操做必定要慎重。
二、git merge
要分支就必然須要合併,不然新分支上的全部開發都沒法影響到主分支,這是沒有意義的。因此咱們每每在新分支開發結束以後往主分支上合併。下面咱們首先看一種快進式(Fast Forwarld)的合併方式。
快進式的合併就是直接將head指針快進到較遠的一個分支的最新提交,也就是說,快進式合併的兩個分支是一種從屬關係,像這樣的:
當前head指針是指向master分支的,而當咱們對newBranch分支進行合併的時候,git將會直接把head指針移動到newBranch的最新提交上,可是head指針依然是指向master的。
咱們在進行分支合併的時候,最常遇到的問題就是合併衝突,可是咱們快進式合併是不會出現衝突的,由於兩個分支是一種從屬關係,進度慢的是進度快的一部分。下面咱們看看合併時遇到衝突該如何解決。
分支合併的衝突指的是,兩個不一樣的分支在各自開發過程當中對相同文件進行了修改,那麼git在合併分支的時候將不知道選擇哪一個分支上的修改做爲該文件的修改,這樣就產生衝突了。例如,咱們在工做區建立兩個分支,在兩個分支上分別對文件test進行修改,而後再合併兩分支。
咱們打開致使兩個分支合併衝突的文件,
git爲咱們向其中添加了一些符號,其中"<<<<<<< HEAD"表示的是當前的master分支,">>>>>>> newbranch"表示的是咱們建立的新分支,而位於他們之間的"======="用於分隔兩個分支的內容。從中咱們很容易的看出來,master分支中這次的提交增長了如下信息,newbranch分支上也作了一次提交併增長了以上信息,因此兩個分支衝突的地方就是在這裏。
爲了解決這種衝突狀況,咱們能夠選擇刪除致使衝突的任意一方的修改,例如咱們刪除分支newbranch上的提交。
而後咱們能夠add,提交到當前分支便可完成衝突的解決。也就是說當咱們執行merge指令來合併兩個分支的時候,git會盡可能去合併,可是若是遇到衝突,git也會呈現出兩個文件之間的差別,要求咱們手動的去解決它。還有一些關於遠程分支的內容,咱們將在下一節遠程倉庫中介紹。
二、遠程倉庫
Git做爲分佈式的版本控制系統,你是你本地倉庫的主人,可是想要實現多人的協做開發,你就要將你本地的開發推送到遠程共享倉庫中供你們下載,本篇主要以github做爲遠程服務器來介紹有關遠程倉庫這塊內容。
做爲咱們的服務器,並不能讓任何人向咱們的git服務器上推送代碼,只能讓有憑證的人向服務器推送。git本地和github服務器之間是經過ssh對稱祕鑰來完成二者的身份確認的,至於ssh是什麼,不瞭解的同窗能夠自行學習下,簡單來講,它就是一個通信加密協議。下面咱們先生成一對ssh祕鑰,執行如下代碼:
$ ssh-keygen -t rsa -C "youremail@example.com"
而後一路回車便可,等生成成功以後,咱們打開這個.ssh文件夾(這個文件夾的保存路徑git已經給出,每一個人都不同),這裏就是一對祕鑰,一個是公鑰,一個是私鑰。公鑰能夠泄露出去,私鑰必定保存好。接着,咱們將公鑰添加到github上,
這樣咱們本地的提交,github服務器就能夠用列表中的公鑰來識別提交者的身份,對於不認識的提交者服務器將予以拒絕。接下來咱們看如何將本地的倉庫關聯服務器上的某個倉庫。首先,咱們在服務器上建立一個git倉庫,
而後咱們執行如下這條命令來爲本地git庫關聯遠程倉庫,
$ git remote add origin git@github.com:Programer-yang/TestGit.git
上述這條命令不是絕對的,讀者要根據本身的github帳戶和建立的遠程倉庫作適當的改動。執行成功以後,git是沒有任何提示的,只有出現錯誤纔會有所提示。這裏的遠程倉庫名字,咱們默認爲origin,固然也是能夠修改的,這個遠程倉庫的簡稱是爲了簡單替代長串的URL,在之後的推送和拉取中就可使用這個簡稱來簡化命令了。下面咱們將介紹兩個命令,一個用於將本地分支推送合併到遠程倉庫中,一個用於從遠程倉庫拉取最新分支。
一、git push
該命令用於將本地分支提交到遠程分支上,它的完整命令格式爲:
$ git push <遠程主機名> <本地分支名>:<遠程分支名>
例如咱們向在本地分支新建一個test文件,而後向github推送。
而後咱們打開github帳戶,能夠明顯看到咱們建立的倉庫收到一次提交,時間顯示幾分鐘以前,而咱們本地新建的文件也隨着提交被建立在服務器上。
二、git pull
該命令主要用於拉取位於服務器上的最新分支到本地併合並,它等效於 git fetch + git merge。命令git fetch 會拉取服務器上的分支並保存在版本庫的某個文件夾下,命令git merge則會將拉取下來的版本庫與本地版本庫進行合併。而咱們的git pull命令就是兩個命令的結合。它的格式以下:
git pull <遠程主機名> <遠程分支名>:<本地分支名>
基本格式和上述介紹的push 命令相似,下面咱們在服務器上新建一個文件index,模擬他人對倉庫的提交,這樣服務器上的分支就比本地的分支上游一次提交,咱們在本地拉取服務器上最新分支。
打開咱們工做目錄,便可看到拉取下來的index文件,此時咱們的本地版本庫就和服務器上的倉庫如出一轍。
至此,咱們簡單的介紹了git中較爲強大的兩部份內容,分支的遠程倉庫。不少命令都有其簡寫的方式,以及使用參數和選項來簡化操做,這裏咱們並無介紹,在後續更加深刻的文章中,這裏的某些命令可能還會出現。整體上來講,本篇介紹的內容還算簡單,總結不到之處,望指出,下一篇咱們將介紹強大的檢出和重置命令。