linux之父Linus爲了更好的管理他本身的開源項目linux系統而本身開發了一個軟件,這個軟件能夠幫助Linux更好的進行開源開發,名字就叫Git。linux
它是個分佈式版本控制系統,Git是最當前流行的分佈式版本控制系統,尤爲是2008年,GitHub網站上線了,它爲開源項目免費提供Git存儲,無數開源項目開始遷移至GitHub,包括jQuery,PHP,Ruby等等。git
sudo apt-get install gi
./config make sudo make install
什麼是版本庫呢?版本庫又名倉庫,英文名repository,你能夠簡單理解成一個目錄,這個目錄裏面的全部文件均可以被Git管理起來,每一個文件的修改、刪除,Git都能跟蹤,以便任什麼時候刻均可以追蹤歷史,或者在未來某個時刻能夠「還原」github
建立完版本庫,當前路徑裏就會發現一個.git的文件夾,這個就是Git的版本庫。Git版本庫裏面有一個稱爲stage(或者叫index)的暫存區,和還有Git爲咱們自動建立的第一個分支master,以及指向master的第一個指針HEAD,示意圖以下:算法
$ git status On branch master nothing to commit, working tree clean
$ git remote add origin git@github.com:slaming/learngit.git
添加後,遠程庫的名字就是origin,這是Git默認的叫法,也能夠改爲別的,可是origin這個名字一看就知道是遠程庫。ubuntu
$ git push -u origin master
若是遠程庫是空的,咱們第一次推送master分支時,加上了-u參數,Git不但會把本地的master分支內容推送的遠程新的master分支,還會把本地的master分支和遠程的master分支關聯起來,在之後的推送或者拉取時就能夠簡化命令。緩存
建立新的分支:服務器
$ git branch dev
切換到dev分支:分佈式
$ git checkout dev
爲了簡單,經常使用下面命令,建立新的分支dev,而且切換到dev分支:工具
$ git checkout -b dev
查看版本庫有什麼分支,git branch命令會列出全部分支,當前分支前面會標一個*號:佈局
$ git branch * dev master
合併分支:
$ git merge dev
每次提交,Git都把它們串成一條時間線,這條時間線就是一個分支。截止到目前,只有一條時間線,在Git裏,這個分支叫主分支,即master分支。HEAD嚴格來講不是指向提交,而是指向master,master纔是指向提交的,因此,HEAD指向的就是當前分支。
一開始的時候,master分支是一條線,Git用master指向最新的提交,再用HEAD指向master,就能肯定當前分支,以及當前分支的提交點
,每次提交,master分支都會向前移動一步,這樣,隨着你不斷提交,master分支的線也愈來愈長:
當咱們建立新的分支,例如dev時,Git新建了一個指針叫dev,指向master相同的提交,再把HEAD指向dev,就表示當前分支在dev上:
從如今開始,對工做區的修改和提交就是針對dev分支了,好比新提交一次後,dev指針往前移動一步,而master指針不變:
假如咱們在dev上的工做完成了,就能夠把dev合併到master上。Git怎麼合併呢?最簡單的方法,就是切換到master分支,直接把master指向dev的當前提交,這樣就完成了合併:
假如開闢了新的分支features1
$ git checkout -b feature1
修改readme.txt最後一行,改成:
Creating a new branch is quick AND simple.
提交:
$ git add readme.txt $ git commit -m "AND simple"
切換到master分支:
$ git checkout master
在master分支上把readme.txt文件的最後一行改成:
Creating a new branch is quick & simple.
提交:
$ git add readme.txt $ git commit -m "& simple"
合併:
$ git merge feature1
這時Git不能自動合併,會出現衝突。
三路合併就是先找出一個基準,而後以基準爲Base 進行合併,若是2個文件相對基準(base)都發生了改變 那git 就報衝突,而後讓你人工決斷。不然,git將取相對於基準(base)變化的那個爲最終結果。
Base 表明上一個版本,即公共祖先
Mine 表明你本地修改
Theirs 表明其餘人修改
這樣當git進行合併的時候,git就知道是其餘人修改了,本地沒有更改,git就會自動把最終結果變成以下,這個結構也是大多merge 工具的常見佈局。
若是換成下面的這樣,就須要人工解決了:
上面就是git merge 最基本的原理 「三路合併」。
上面①~⑨表明一個個修改集合(commit)每一個commit都有一個惟一7位SHA-1惟一表示。
①,②,④,⑦修改集串聯起來就是一個鏈,此時用master指向這個集合就表明master分支,分支本質是一個快照,其實類比C中指針
一樣dev分支也是由一個個commit組成
如今在dev分支上因爲各類緣由要運行git merge master須要把master分支的更新合併到dev分支上,本質上就是合併修改集 ⑦(Mine) 和 ⑧(Theirs) ,此時咱們要 利用DAG(有向無環圖)相關算法找到咱們公共的祖先 ②(Base)而後進行三方合併,最後合併生成 ⑨。
你從遠程倉庫克隆到本地,就能夠開始你的開發了。
要查看遠程庫的信息,用git remote:
$ git remote origin
或者,用git remote -v顯示更詳細的信息:
$ git remote -v origin git@github.com:slaming/learngit.git (fetch) origin git@github.com:slaming/learngit.git (push)
上面顯示了能夠抓取和推送的origin的地址。若是沒有推送權限,就看不到push的地址。
把分支上的全部本地提交推送到遠程庫。推送時,要指定本地分支,這樣,Git就會把該分支推送到遠程庫對應的遠程分支上:
$ git push origin dev
可是,並非必定要把本地分支往遠程推送,那麼,哪些分支須要推送,哪些不須要呢?
master分支是主分支,所以要時刻與遠程同步;
feature分支是否推到遠程,取決於你是否和你的小夥伴合做在上面開發。
在實際開發中,咱們應該按照幾個基本原則進行分支管理:
首先,master分支應該是很是穩定的,也就是僅用來發布新版本,平時不能在上面幹活;
那在哪幹活呢?幹活都在dev分支上,也就是說,dev分支是不穩定的,到某個時候,好比1.0版本發佈時,再把dev分支合併到master上,在master分支發佈1.0版本;
你和你的小夥伴們每一個人都在dev分支上幹活,每一個人都有本身的分支,時不時地往dev分支上合併就能夠了。
因此,團隊合做的分支看起來就像這樣:
多人協做時,你們都會往master和dev分支上推送各自的修改。
當你的小夥伴已經向origin/dev分支推送了他的提交,而碰巧你也對一樣的地方做了修改,並試圖推送:
$ git push origin dev
推送會失敗,由於你的小夥伴的最新提交和你試圖推送的提交有衝突,和merge相似。這時須要手動改寫。