Git學習筆記(5)——分支管理


本文主要記錄了分支的原理、分支的創建,刪除,合並、以及分支的使用策略。


分支在實際中的作用

假設你准備開發一個新功能,但是需要兩周才能完成,第一周你寫了50%的代碼,如果立刻提交,由於代碼還沒寫完,不完整的代碼庫會導致別人不能干活了。如果等代碼全部寫完再一次提交,又存在丟失每天進度的巨大風險。現在有了分支,就不用怕了。你創建了一個屬於你自己的分支,別人看不到,還繼續在原來的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到開發完畢后,再一次性合並到原來的分支上,這樣,既安全,又不影響別人工作。


分支的原理描述

在版本回退里,每次提交,Git都把它們串成一條時間線,這條時間線就是一個分支。開始的時候,只有一條時間線,在Git里,這個分支叫主分支,即master分支。HEAD嚴格來說不是指向提交,而是指向mastermaster才是指向提交的,所以,HEAD指向的就是當前分支。

一開始的時候,master分支是一條線,Git用master指向最新的提交,再用HEAD指向master,就能確定當前分支,以及當前分支的提交點.

每次提交,master分支都會向前移動一步,這樣,隨着你不斷提交,master分支的線也越來越長:

當我們創建新的分支,例如dev時,Git新建了一個指針叫dev,指向master相同的提交,再把HEAD指向dev,就表示當前分支在dev上.

這樣一個dev的分支就建成了,不過,從現在開始,對工作區的修改和提交就是針對dev分支了,比如新提交一次后,dev指針往前移動一步,而master指針不變。

我們在dev上的工作完成了,就可以把dev合並到master上。最簡單的方法,就是直接把master指向dev的當前提交,就完成了合並。合並完分支后,就可以刪除無用的dev分支。刪除dev分支就是把dev指針給刪掉,刪掉后,我們就剩下了一條master分支。


分支的創建與刪除

ubuntu@myUbuntu:~/joe/learngit$ ls
abc.c  readme.txt
ubuntu@myUbuntu:~/joe/learngit$ git status
位於分支 master        //當前位於主分支
您的分支與上游分支 'origin/master' 一致。
無文件要提交,干凈的工作區
ubuntu@myUbuntu:~/joe/learngit$ 
git checkout -b dev
    //創建一個分支並切換到當前分支
切換到一個新分支 'dev'
ubuntu@myUbuntu:~/joe/learngit$ 
git branch
    //查看所有分支,(當前的分支前會有*號)
* dev
  master
ubuntu@myUbuntu:~/joe/learngit$ ls
abc.c  readme.txt
ubuntu@myUbuntu:~/joe/learngit$ vi readme.txt     //在dev分支下修改文件
ubuntu@myUbuntu:~/joe/learngit$ 
git status
    //查看狀態,是在dev分支下
位於分支 dev
尚未暫存以備提交的變更:
  (使用 "git add <file>..." 更新要提交的內容)
  (使用 "git checkout -- <file>..." 丟棄工作區的改動)

    修改:     readme.txt

修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
ubuntu@myUbuntu:~/joe/learngit$ git add readme.txt 
ubuntu@myUbuntu:~/joe/learngit$ 
git commit -m "new dev branch"

[dev 9409b92] new dev branch
 1 file changed, 2 insertions(+), 1 deletion(-)
ubuntu@myUbuntu:~/joe/learngit$ 
git checkout master
    //將dev分支下的工作提交以后,切換到主分支
切換到分支 'master'
您的分支與上游分支 'origin/master' 一致。
ubuntu@myUbuntu:~/joe/learngit$ 
cat readme.txt
         //主分支下查看文件發現文件內容並沒有修改
Git is a distributed version control system
Git is free software distributed under the
Are you ok?
Yes,i am fine.
What about you?
ubuntu@myUbuntu:~/joe/learngit$ 
git merge dev
        //dev分支和master分支合並
更新 f10fe58..9409b92
Fast
-
forward//Fast-forward信息,Git告訴我們,這次合並是“快進模式”,也就是直接把master指向dev的當前提交,所以合並速度非常快。當然,也不是每次合並都能Fast-forward,就如下面的沖突
 readme.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
ubuntu@myUbuntu:~/joe/learngit$ 
cat readme.txt
         //合並以后,再次查看,文件內容已經修改
Git is a distributed version control system
Git is free software distributed under the
Are you ok?
Yes,i am fine.
What about you
Create a branch is so quick.
ubuntu@myUbuntu:~/joe/learngit$ 
git branch -d dev
    //刪除分株
已刪除分支 dev(曾為 9409b92)。
ubuntu@myUbuntu:~/joe/learngit$ git branch
* master
//git checkout命令加上-b參數表示創建並切換,相當於以下兩條命令:

$ git branch dev    //創建分支
$ git checkout dev    //切換分支
Switched to branch 'dev'

分支的沖突

ubuntu@myUbuntu:~/joe/learngit$ git status
位於分支 master
您的分支領先 'origin/master'1 個提交。
  (使用 "git push" 來發布您的本地提交)
無文件要提交,干凈的工作區
ubuntu@myUbuntu:~/joe/learngit$ 
git checkout -b bran
    //新建bran分支,修改文件內容並提交
切換到一個新分支 'bran'
ubuntu@myUbuntu:~/joe/learngit$ vi abc.c 
ubuntu@myUbuntu:~/joe/learngit$ cat abc.c 
I am a new branch
ubuntu@myUbuntu:~/joe/learngit$ git add abc.c 
ubuntu@myUbuntu:~/joe/learngit$ 
git commit -m "new bran"

[bran 5aa28d8] new bran
 1 file changed, 1 insertion(+), 1 deletion(-)
ubuntu@myUbuntu:~/joe/learngit$ 
git checkout master
    //切換回主分支,修改同一個文件,並提交
切換到分支 'master'
您的分支領先 'origin/master'1 個提交。
  (使用 "git push" 來發布您的本地提交)
ubuntu@myUbuntu:~/joe/learngit$ vi abc.c 
ubuntu@myUbuntu:~/joe/learngit$ cat abc.c 
I am not a branch
ubuntu@myUbuntu:~/joe/learngit$ git add abc.c 
ubuntu@myUbuntu:~/joe/learngit$ git 
commit -m "not a branch"

[master fe42f3e] not a branch
 1 file changed, 1 insertion(+), 1 deletion(-)
ubuntu@myUbuntu:~/joe/learngit$ 
git merge bran
    //此時合並分支的時候,出現了沖突(2個分支都對文件做了修改,那么合並的時候應該合並哪一個呢?此時需要手動解決以后,才可以合並。)
自動合並 abc.c
沖突(內容):合並沖突於 abc.c
自動合並失敗,修正沖突然后提交修正的結果。
ubuntu@myUbuntu:~/joe/learngit$ git status
位於分支 master
您的分支領先 'origin/master'2 個提交。
  (使用 "git push" 來發布您的本地提交)
您有尚未合並的路徑。
  (解決沖突並運行 "git commit"未合並的路徑:
  (使用 "git add <file>..." 標記解決方案)

    雙方修改:   abc.c

修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
ubuntu@myUbuntu:~/joe/learngit$ 
cat abc.c
     //查看文件內容
<<<<<<< HEAD
I am not a branch
=======
I am a new branch
>>>>>>> bran
//Git用<<<<<<<,=======,>>>>>>>標記出不同分支的內容
ubuntu@myUbuntu:~/joe/learngit$ 
vi abc.c
     //將其文件內容修改統一后,提交
ubuntu@myUbuntu:~/joe/learngit$ cat abc.c 
I am not a branch
ubuntu@myUbuntu:~/joe/learngit$ git add abc.c 
ubuntu@myUbuntu:~/joe/learngit$
git commit -m "conflict ok"

[master f73e798] conflict ok
ubuntu@myUbuntu:~/joe/learngit$ 
git log --graph --pretty=oneline --abbrev-commit
//查看分支歷史,形象的描寫了沖突的位置
*   f73e798 conflict ok
|\  
| * 5aa28d8 new bran
* | fe42f3e not a branch
|/  
* 9409b92 new dev branch
* f10fe58 new abc
* 0ad1dfe del ab.c
* 7b6507e new ab.c
* 020f927 del abc
* 010726f del a line
* c834e17 nothing
* aa6b706 new abc.c
* 82f4ed9 modify read
* e32e92b del abc.c
* ab22d92 test stage
* d4e3943 understand how stage workd
* 71038bf append GPL
* 942f575 add distributed
* b401faf joe's first txt
ubuntu@myUbuntu:~/joe/learngit$ 
git branch -
d bran
已刪除分支 bran(曾為 5aa28d8)。

分支管理策略

合並分支時,Git會用Fast forward模式,但這種模式下,刪除分支后,會丟掉分支信息。

如果要強制禁用Fast forward模式,Git就會在merge時生成一個新的commit,這樣,從分支歷史上就可以看出分支信息。

ubuntu@myUbuntu:~/joe/learngit$ 
git checkout -b dev
    //新建dev分支,修改文件並提交
切換到一個新分支 'dev'
ubuntu@myUbuntu:~/joe/learngit$ vi abc.c 
ubuntu@myUbuntu:~/joe/learngit$ cat abc.c 
I like you
!

ubuntu@myUbuntu:~/joe/learngit$ git add abc.c 
ubuntu@myUbuntu:~/joe/learngit$ 
git commit -m "dev branch"

[dev cef4924] dev branch
 1 file changed, 1 insertion(+), 1 deletion(-)
ubuntu@myUbuntu:~/joe/learngit$ git checkout master
切換到分支 'master'
您的分支領先 'origin/master'4 個提交。
  (使用 "git push" 來發布您的本地提交)
//合並dev分支,--no-ff參數,表示禁用Fast forward,本次合並要創建一個新的commit,所以加上-m參數,把commit描述寫進去
ubuntu@myUbuntu:~/joe/learngit$ 
git merge --no-ff -m "merge with no-ff"
 dev
Merge made by the 'recursive' strategy.
 abc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
ubuntu@myUbuntu:~/joe/learngit$ 
git log --graph --pretty=oneline --abbrev-
commit
*   7877628 merge with no-ff
|\  
| * cef4924 dev branch
|/  
*   f73e798 conflict ok
|\  
| * 5aa28d8 new bran
* | fe42f3e not a branch
|/  
* 9409b92 new dev branch
* f10fe58 new abc

使用fast forward的情況

ubuntu@myUbuntu:~/joe/learngit$ 
git checkout -
b dev
切換到一個新分支 'dev'
ubuntu@myUbuntu:~/joe/learngit$ vi abc.c 
ubuntu@myUbuntu:~/joe/learngit$ cat abc.c 
I don
't like you!
ubuntu@myUbuntu:~/joe/learngit$ git add abc.c 
ubuntu@myUbuntu:~/joe/learngit$ 
git commit -m "dev"

[dev b961f85] dev
 1 file changed, 1 insertion(+), 1 deletion(-)
ubuntu@myUbuntu:~/joe/learngit$ git checkout master
切換到分支 'master'
您的分支領先 'origin/master'6 個提交。
  (使用 "git push" 來發布您的本地提交)
ubuntu@myUbuntu:~/joe/learngit$ git merge dev
更新 7877628..b961f85
Fast-forward
 abc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
ubuntu@myUbuntu:~/joe/learngit$ 
git log --graph --pretty=oneline --abbrev-
commit
*
 b961f85 dev
*   7877628 merge with no-ff
|\      //注意這2次分支的對比
| * cef4924 dev branch
|/  
*   f73e798 conflict ok
|\  
| * 5aa28d8 new bran
* | fe42f3e not a branch
|/  
* 9409b92 new dev branch
* f10fe58 new abc
* 0ad1dfe del ab.c

分支策略

  1. 首先,master分支應該是非常穩定的,也就是僅用來發布新版本,平時不能在上面干活;
  2. 干活都在dev分支上,dev分支是不穩定的,新版本版本發布時,再把dev分支合並到master上,在master分支發布新版本;
  3. 每個人都在dev分支上干活,每個人都有自己的分支,時不時地往dev分支上合並就可以了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM