天天看點

記錄我學github的路程(二)

2015-12-09 更新

1,現在,本地有了一個庫,你可能會想到GitHub建立一個庫,并且關聯起來。這樣,遠端的庫既可以當作備份,又可以讓其他人通過該倉庫來協作。

2,步驟:

(1)登入GitHub,應該會有提示,(我還沒建立過遠端庫,很容易看到這個界面)

記錄我學github的路程(二)
(2)點選那個 Create a respository:
記錄我學github的路程(二)

(3)這就建立好了一個庫,這時候庫還是空的,GitHub告訴我們可以從這個倉庫克隆出新的倉庫。也可以把一個已有的本地倉庫與之關聯。

(4)本地倉庫與之關聯:

打開Git Bash: 輸入

$ git remote add origin [email protected]:yourname/yourname.git 

注意:把yourname換成你自己的賬戶名和庫名

若你關聯了别人的 ,你是推送不上去的,因為你的SSH Key公鑰不在别人的賬戶清單中

添加後,遠端庫的名字就是origin,這是Git預設叫法,可以改成别的

下一步,就可以把本地庫的東西推送到遠端庫中了

$ git push -u origin master 

記錄我學github的路程(二)

本地内容推送到遠端,用git push 指令,其實就是把目前分支master推送到遠端

由于這時遠端庫是空的,第一次推送master時,加上-u參數,Git不但把本地分支推送給了遠端新的master分支,還會把本地的master分支和遠端的master分支關聯起來,以後推送或拉取就可以簡化指令。

推送成功後,再GitHub頁面中可以看到遠端庫的内容和本地已經一樣了

3,從現在起,隻有本地做了修改,就可以用下面的指令

$ git push origin master

把本地master分支的最新修改推送到GitHub。

4,小結:

關聯一個遠端庫: $ git remote add origin [email protected]:yourname/yourname.git 

第一次推送到遠端庫: $ git push -u origin master 

後面再送出: $ git push origin master

----- 分割線 -----

  從遠端庫克隆

1,先建立一個庫,和上面的方法有點不一樣

記錄我學github的路程(二)

2,這樣建立好之後,這個庫會有一個README.md檔案。這樣就有了一個遠端庫,

3,打開git bash,輸入指令

$ git clone [email protected]:yourname/yourname.git 

這樣,就把一個遠端庫克隆到本地了,就像這樣子

記錄我學github的路程(二)

要克隆一個庫,就必須要知道倉庫的位址,然後用git clone 指令克隆。

2015-12-10   20:14:09

1,分支管理:可以建立一個屬于自己的分支,别人看不到,别人還繼續在原來的分支上工作,而你自己在自己的分支上幹活,想送出就送出,開完完畢後,再一起合并到原來的分支上,安全又不影響别人工作。

2,建立與合并分支

(1)在版本回退裡,每次送出,Git都把它們串成一條時間線,這條時間線就是一個分支。目前為止,隻有一條時間線,在Git裡,這個分支叫做主分支(master分支 )。

HEAD嚴格來說不是指向送出,而是指向master,master才是指向送出的,是以HEAD指向的就是目前分支。(這個有點拗口)

(2)開始的時候,master分支是一條線,Git用master指向最新的送出,再用HEAD指向master,這樣就能确定目前的分支,以及目前分支的送出點:

記錄我學github的路程(二)

就這樣,每次送出後,master分支就會向前移動一步,随着不斷送出,master分支的線就越來越長。(在沒有建立新的分支時)

(3)當我們建立新的分支,比如dev時,Git建立了一個指針叫dev,指向master相同的送出。再把HEAD指向dev,就表示目前分支在dev上:

記錄我學github的路程(二)

就像上圖一樣,僅僅是多了一個dev指針,再改變HEAD的指向,工作區的檔案沒有任何變化。(HEAD始終指向目前分支,在這裡就是dev)

從現在開始,對工作區的修改和送出就是針對dev分支了,每次送出HEAD會往前,而master指針不變。

(4)當dev的工作做完了,要怎樣和master合并呢。最簡單的方法就是:用master指向dev的目前送出。就像這樣,改改指針,工作區的内容不變。

記錄我學github的路程(二)

合并完分支以後,就可以删除dev指針了。這時候就隻剩一條master分支了。

3,開始操刀實戰了:

(1)建立 dev分支,然後切換到dev分支

$ git checkout -b dev

git checkout 加上 -b參數表示建立并切換,相當于下面兩條指令 :

$ git branch dev

$ git checkout dev

然後,可以檢視一下目前分支 ,git branch會列出所有分支,目前分支前面會标*号

記錄我學github的路程(二)
接下來在dev修改送出,并切換回master分支
記錄我學github的路程(二)
接下來合并,并且删除dev指針,就可以看到剛剛在dev所做的修改了
記錄我學github的路程(二)

檢視分支: git branch        // 帶*的表示目前分支

建立分支: git branch **name

切換分支: git checkout **name

建立+切換分支: git checkout -b **name

合并某分支到目前分支: git merge **name

删除分支: git branch -d **name

2015-12-21  更新

  最近都挺忙的,公司項目好多bug,真是艱難。哈哈哈

1,解決沖突

現在假設如下場景:

$ git checkout -b feature1 // 建立并切換到新分支

然後對readme.txt進行修改,并送出

再切換回master分支   $ git checkout master

在master分支對readme.txt進行修改送出

這時候再把master和feature1分支進行合并 $ git merge feature1

這時候就會有沖突 ,Git告訴我們 readme.txt檔案存在沖突,必須手動解決沖突再送出。可以用$ git status 檢視沖突的檔案

記錄我學github的路程(二)
 這時候運作 $ cat readme.txt  可以檢視檔案内容,如下圖,隻截部分内容
記錄我學github的路程(二)

Git用 <<<<<<<,=======,>>>>>>> 标記不同分支的内容。

現在master分支和feature1分支變成了下圖所示:

記錄我學github的路程(二)
使用下面指令可以看到分支的合并情況:
記錄我學github的路程(二)

小結:Git無法自動合并分支時,就要先解決沖突,這樣才可以送出。

  $ git log --graph 可以看到分支合并圖

2,分支管理政策

(1)通常,合并分支時 ,如果可能,Git會用“Fast forward”模式。(這樣删除分支後,會丢掉分支資訊)

(2)要強制禁用“Fast forward”模式,Git會在merge時生成一個新的commit,這樣從分支曆史就可以看出分支資訊

(3)執行個體:

$ git checkout -b dev   // 後面對readme.txt修改,原諒我寫注釋習慣了這樣,雖然我也知道這樣不正确,哈哈哈

$ git add readme.txt

$ git commit -m "add merge"  //  截圖從這裡開始

$ git checkout master

$ git merge --no-ff -m "merge with np-ff" dev   //  --no-ff  禁用“Fast forward”

  // 因為本次合并要建立一個新的commit ,是以加上 -m,把commi描述寫進去,合并後,再 檢視分支曆史

$ git log --graph --pertty=oneline --abbrev-commit

記錄我學github的路程(二)
不用fast forward模式,merge之後就像這樣
記錄我學github的路程(二)

(4)分支政策:實際開發中應該按照幾個原則進行分支管理

首先,master分支應該是非常穩定的, 平時不能在這幹活。在master分支上釋出。

幹活都在dev分支上,每個人都在dev分支上幹活,每個人都有自己的分支,時不時的合并就可以了。

是以團隊合作的分支就是這樣子:

記錄我學github的路程(二)

  小結:合并分支時加上 --no-ff 參數就可以用普通模式合并,合并後的曆史有分支。能看出來做過合并

而fast foward合并就看不出來曾經合并過。

注:.Fast forward模式介紹。   參考:http://bbs.scmlife.com/thread-22570-1-1.html

在使用git merge時,可能是以下三種模式中的某一種9 m& _7 c% N) j( B. M3 m

5 p6 U4 G0 N* s" L3 F# I

1.Fast forward

   當待合并的2個branch最近的commit是線性關系時' C& V: Y- n+ p  n+ B+ v# R

   或者說,某個branch自上次更新後沒有commit資訊時

   git則直接移動指針即可,并沒有真正的merge操作,也沒有對應的merge commit資訊

# S7 O' l" R, r3 R1 Z

2.Merge made by recursive% N$ X7 o' {" ]% N0 z2 g# q

   當要合并的2個branch的最近的commit對應的直接祖先不同時  p. Z4 W  s- l/ O

   git就無法通過簡單的移動指針來進行合并

   隻能以2個branch的最新commit和他們的共同祖先進行一次merge: l+ D& R5 z4 _* P, z  h, \

   并對應有一個merge commit資訊3 G1 _+ Q! W) a- v) N8 S

3.Conflict

   當2個branch都修改了同一個檔案的同一部分時4 ~5 H) g) p' y8 I* ?6 p1 J! J

   這時,就會發生沖突,git的自動合并就會失敗

   這時,使用git status會看到- F# r+ [- g1 j. m. _% Z- P# d! r4 H6 ; l7 w# M3 E! Y8 U2  ^/ V" D* E5 k

   需要手工合并沖突後,git add一下,表明沖突修改完了

   然後,再git commit即可!