文章目錄
- 理解分支
- 創建分支
- 切換分支
- 合并分支
- 刪除分支
- 合并沖突
- 分支管理策略
- 分支策略
- bug 分支
- 刪除臨時分支
- 小結
理解分支
本章開始介紹 Git 的殺手級功能之一(注意是之一,也就是后面還有之二,之三……):分支。分支就是科幻電影里面的平行宇宙,當你正在電腦前努力學習 C++ 的時候,另一個你正在另一個平行宇宙里努力學習 JAVA。
如果兩個平行宇宙互不干擾,那對現在的你也沒啥影響。不過,在某個時間點,兩個平行宇宙合并了,結果,你既學會了 C++ 又學會了 JAVA!
在版本回退里,你已經知道,每次提交,Git都把它們串成一條時間線,這條時間線就可以理解為是一個分支。截止到目前,只有一條時間線,在Git里,這個分支叫主分支,即 master 分支。
再來理解一下HEAD,HEAD 嚴格來說不是指向提交,而是指向master,master才是指向提交的,所以,HEAD 指向的就是當前分支。
每次提交,master分支都會向前移動一步,這樣,隨著你不斷提交,master分支的線也越來越長,而HEAD只要一直指向master分支即可指向當前分支。
通過查看當前的版本庫,我們也能清晰的理出思路:
[root@MyComputer:gitcode]# cat .git/HEAD
ref: refs/heads/master
[root@MyComputer:gitcode]# cat .git/refs/heads/master
d68ea84a1142d3d517478ff5715b428a5d32657d
創建分支
Git 支持我們查看或創建其他分支,在這里我們來創建第一個自己的分支 dev ,對應的命令為:
[root@MyComputer:gitcode]# git branch # 查看當前本地所有分?
* master
[root@MyComputer:gitcode]# git branch dev # 新建分?dev
[root@MyComputer:gitcode]# git branchdev
* master
當我們創建新的分支后,Git 新建了一個指針叫 dev, * 表示當前 HEAD 指向的分支是 master 分支。另外,可以通過目錄結構發現,新的 dev 分支:
[root@MyComputer:gitcode]# ls .git/refs/heads/
dev master
[root@MyComputer:gitcode]# cat .git/refs/heads/*
d68ea84a1142d3d517478ff5715b428a5d32657d
d68ea84a1142d3d517478ff5715b428a5d32657d
發現目前 dev 和 master 指向同一個修改。并且也可以驗證下 HEAD 目前是指向 master 的。
[root@MyComputer:gitcode]# cat .git/HEAD
ref: refs/heads/master
一張圖總結:
切換分支
那如何切換到 dev 分支下進行開發呢?使用 git checkout
命令即可完成切換,示例如下:
[root@MyComputer:gitcode]# git branchdev
* master
[root@MyComputer:gitcode]# git checkout dev
Switched to branch 'dev'
[root@MyComputer:gitcode]# git branch
* devmaster
[root@MyComputer:gitcode]# cat .git/HEAD
ref: refs/heads/dev
我們發現 HEAD 已經指向了 dev,就表示我們已經成功的切換到了 dev 上!
接下來,在 dev 分支下修改 ReadMe 文件,新增一行內容,并進行一次提交操作:
[root@MyComputer:gitcode]# vim ReadMe
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
Hello dev
[root@MyComputer:gitcode]# git add ReadMe
[root@MyComputer:gitcode]# git commit -m "modify ReadMe add dev"
[dev f36c45f] modify ReadMe add dev1 file changed, 1 insertion(+)
現在,dev 分支的工作完成,我們就可以切換回 master 分支:
[root@MyComputer:gitcode]# git checkout master
Switched to branch 'master'
[root@MyComputer:gitcode]# cat .git/HEAD
ref: refs/heads/master
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
切換回 master 分支后,發現ReadMe文件中新增的內容不見了!!!趕緊再切回 dev 看看:
[root@MyComputer:gitcode]# git checkout dev
Switched to branch 'dev'
[root@MyComputer:gitcode]# cat .git/HEAD
ref: refs/heads/dev
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
Hello dev
在 dev 分支上,內容還在。為什么會出現這個現象呢?我們來看看 dev 分支和 master 分支指向,發現兩者指向的提交是不一樣的:
[root@MyComputer:gitcode]# cat .git/refs/heads/dev
f36c45f7e5d5cd32453976357dda2e4a8d2067de
[root@MyComputer:gitcode]# cat .git/refs/heads/master
d68ea84a1142d3d517478ff5715b428a5d32657d
[root@MyComputer:gitcode]# git log --pretty=oneline
f36c45f7e5d5cd32453976357dda2e4a8d2067de (HEAD -> dev) modify ReadMe add dev
d68ea84a1142d3d517478ff5715b428a5d32657d (master) add version3
看到這里就能明白了,因為我們是在dev分支上提交的,而master分支此刻的提交點并沒有變,此時的狀態如圖如下所示。
當切換到 master 分支之時,HEAD 就指向了 master,當然看不到提交了!
合并分支
為了在 master 主分支上能看到新的提交,就需要將 dev 分支合并到 master 分支,示例如下:
[root@MyComputer:gitcode]# git branch
* devmaster
[root@MyComputer:gitcode]# git checkout master # 必須要切換到 master 上進行合并
Switched to branch 'master'
[root@MyComputer:gitcode]# git merge dev # 合并 dev 分支
Updating d68ea84..f36c45f
Fast-forward # 代表“快進模式”ReadMe | 1 +1 file changed, 1 insertion(+)
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
Hello dev
git merge
命令用于合并指定分支到當前分支。合并后,master 就能看到 dev 分支提交的內容了。此時的狀態如圖如下所示。
Fast-forward
代表“快進模式”,也就是直接把master指向dev的當前提交,所以合并速度非常快。
當然,也不是每次合并都能 Fast-forward
,我們后面會講其他方式的合并。
刪除分支
合并完成后, dev 分支對于我們來說就沒用了, 那么dev分支就可以被刪除掉,注意如果當前正處于某分支下,就不能刪除當前分支,如:
[root@MyComputer:gitcode]# git branch
* devmaster
[root@MyComputer:gitcode]# git branch -d dev # 刪除分支的選項(等同于 --delete)
error: Cannot delete branch 'dev' checked out at '/root/gitcode'
而可以在其他分支下刪除當前分支,如:
[root@MyComputer:gitcode]# git checkout master
Switched to branch 'master'
[root@MyComputer:gitcode]# git branch -d dev
Deleted branch dev (was f36c45f).
[root@MyComputer:gitcode]# git branch
* master
此時的狀態如圖如下所示。
因為創建、合并和刪除分支非常快,所以Git鼓勵你使用分支完成某個任務,合并后再刪掉分支,這和直接在master分支上工作效果是一樣的,但過程更安全。
合并沖突
可是,在實際分支合并的時候,并不是想合并就能合并成功的,有時候可能會遇到代碼沖突的問題。
為了演示這問題,創建一個新的分支 dev1 ,并切換至目標分支,我們可以使用 git checkout -b dev1
一步完成創建并切換的動作,-b:它是 --branch 的簡寫形式,其功能是在切換分支之前先創建新分支,示例如下:
[root@MyComputer:gitcode]# git branch
* master
[root@MyComputer:gitcode]# git checkout -b dev1
Switched to a new branch 'dev1'
[root@MyComputer:gitcode]# git branch
* dev1master
在 dev1 分支下修改 ReadMe 文件,更改文件內容如下,并進行一次提交,如:
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
Hello dev
[root@MyComputer:gitcode]# vim ReadMe
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
Hello dev aaa
[root@MyComputer:gitcode]# git add .
[root@MyComputer:gitcode]# git commit -m "modify add aaa"
[dev1 4935122] modify add aaa1 file changed, 1 insertion(+), 1 deletion(-)
切換至 master 分支,觀察 ReadMe 文件內容:
[root@MyComputer:gitcode]# git branchdev1
* master
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
Hello dev
我們發現,切回來之后,文件內容由變成了老的版本,這種現象很正常,我們現在也完全能理解。
此時在 master 分支上,我們對 ReadMe 文件再進行一次修改,并進行提交,如下:
[root@MyComputer:gitcode]# vim ReadMe
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
Hello dev bbb
[root@MyComputer:gitcode]# git add .
[root@MyComputer:gitcode]# git commit -m "modify add bbb"
[master 0e50368] modify add bbb1 file changed, 1 insertion(+), 1 deletion(-)
現在, master 分支和 dev1 分支各自都分別有新的提交,變成了這樣:
這種情況下,Git 只能試圖把各自的修改合并起來,但這種合并就可能會有沖突,如下所示:
[root@MyComputer:gitcode]# git branchdev1
* master
[root@MyComputer:gitcode]# git merge dev1
Auto-merging ReadMe
CONFLICT (content): Merge conflict in ReadMe
Automatic merge failed; fix conflicts and then commit the result.
[root@MyComputer:gitcode]# git status
On branch master
You have unmerged paths.(fix conflicts and run "git commit")(use "git merge --abort" to abort the merge)Unmerged paths:(use "git add <file>..." to mark resolution)both modified: ReadMeno changes added to commit (use "git add" and/or "git commit -a")
發現 ReadMe 文件有沖突后,可以直接查看文件內容,要說的是 Git 會用 <<<<<<<,=======,>>>>>>> 來標記出不同分支的沖突內容,如下所示:
1 Hello lwz2 Hello lwz3 Hello world!!!!4 Hello Git5 Hello version16 Hello version27 Hello version38 <<<<<<< HEAD 9 Hello dev bbb10 =======11 Hello dev aaa12 >>>>>>> dev1
此時我們必須要手動調整沖突代碼,并需要再次提交修正后的結果!!(再次提交很重要,切勿忘記)
[root@MyComputer:gitcode]# vim ReadMe
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
Hello dev bbb
[root@MyComputer:gitcode]# git add .
[root@MyComputer:gitcode]# git commit -m "fix over"
[master 2fa65b5] fix over
到這里沖突就解決完成,此時的狀態變成了
用帶參數的 git log也可以看到分支的合并情況,git log --graph --pretty=oneline --abbrev-commit
下面是各部分參數的具體解釋:
1. git log:基礎命令,用于顯示提交歷史記錄。
2. --graph:
- 功能:以 ASCII 圖形方式展示分支合并歷史,用豎線和斜杠表示提交之間的關系。
- 效果:讓分支結構更加直觀,便于理解提交的分叉和合并點。
3. --pretty=oneline:
- 功能:將每個提交壓縮為一行顯示,默認格式為 提交哈希 提交信息。
- 替代參數:--pretty=format:"%h %ad | %s%d [%an]":自定義格式(如哈希、日期、提交信息等)。--oneline:--pretty=oneline --abbrev-commit 的簡寫。4. --abbrev-commit:- 功能:將提交哈希值縮寫為最短唯一長度(通常 7 位字符),提高可讀性。- 注意:若不指定該參數,--pretty=oneline 會顯示完整的 40 位哈希值。
[root@MyComputer:gitcode]# git log --graph --pretty=oneline --abbrev-commit
* 2fa65b5 (HEAD -> master) fix over
|\
| * 4935122 (dev1) modify add aaa
* | 0e50368 modify add bbb
|/
最后,不要忘記 dev1 分支使用完畢后就可以刪除了:
[root@MyComputer:gitcode]# git branchdev1
* master
[root@MyComputer:gitcode]# git branch -d dev1
Deleted branch dev1 (was 4935122).
[root@MyComputer:gitcode]# git branch
* master
分支管理策略
通常合并分支時,如果可能,Git 會采用 Fast forward
模式。還記得如果我們采用 Fast forward
模式之后,形成的合并結果是什么呢?回顧一下
在這種 Fast forward 模式下,刪除分支后,查看分支歷史時,會丟掉分支信息,看不出來最新提交到底是 merge 進來的還是正常提交的。
但在合并沖突部分,我們也看到通過解決沖突問題,會再進行一次新的提交,得到的最終狀態為:
那么這就不是 Fast forward 模式了,這樣的好處是,從分支歷史上就可以看出分支信息。例如我們現在已經刪除了在合并沖突部分創建的 dev1 分支,但依舊能看到 master 其實是由其他分支合并得到:
[root@MyComputer:gitcode]# git log --graph --pretty=oneline --abbrev-commit
* 2fa65b5 (HEAD -> master) fix over
|\
| * 4935122 modify add aaa
* | 0e50368 modify add bbb
|/
Git 支持我們強制禁用 Fast forward
模式,那么就會在 merge 時生成一個新的 commit ,這樣,從分支歷史上就可以看出分支信息。
下面我們實戰一下 --no-ff
方式的 git merge
。首先,創建新的分支 dev2 ,并切換至新的分支:
[root@MyComputer:gitcode]# git checkout -b dev2
Switched to a new branch 'dev2'
[root@MyComputer:gitcode]# git branch
* dev2master
修改 ReadMe 文件,并提交一個新的 commit :
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
Hello dev bbb
[root@MyComputer:gitcode]# vim ReadMe
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
Hello dev bbb
TTTTTTTTTTTTTTTT
[root@MyComputer:gitcode]# git add .
[root@MyComputer:gitcode]# git commit -m "add TTTTTT"
[dev2 a3198a4] add TTTTTT1 file changed, 1 insertion(+)
切回 master 分支,開始合并:
[root@MyComputer:gitcode]# git branchdev2
* master
[root@MyComputer:gitcode]# git merge --no-ff -m "merge with no-ff" dev2
Merge made by the 'ort' strategy. # 提示合并已完成,使用了'ort'合并策略(ORT是Git 2.33+的默認策略)
# 顯示合并修改的文件:ReadMe文件被修改
# "1 +"表示該文件新增了1行內容ReadMe | 1 +
# 合并統計:1個文件被修改,新增了1行內容1 file changed, 1 insertion(+)[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
Hello dev bbb
TTTTTTTTTTTTTTTT
請注意 --no-ff
參數,表示禁用 Fast forward
模式。禁用 Fast forward
模式后合并會創建一個新的 commit ,所以加上 -m
參數,把描述寫進去。合并后,查看分支歷史:
* 134ea9a (HEAD -> master) merge with no-ff
|\
| * a3198a4 (dev2) add TTTTTT
|/
可以看到,不使用 Fast forward
模式,merge后就像這樣:
所以在合并分支時,加上 --no-ff
參數就可以用普通模式合并,合并后的歷史有分支,能看出來曾經做過合并,而 fast forward 合并就看不出來曾經做過合并。
分支策略
在實際開發中,我們應該按照幾個基本原則進行分支管理:
首先,master分支應該是非常穩定的,也就是僅用來發布新版本,平時不能在上面干活;
那在哪干活呢?干活都在dev分支上,也就是說,dev分支是不穩定的,到某個時候,比如1.0版本發布時,再把dev分支合并到master上,在master分支發布1.0版本;
你和你的小伙伴們每個人都在dev分支上干活,每個人都有自己的分支,時不時地往dev分支上合并就可以了。
所以,團隊合作的分支看起來就像這樣:
bug 分支
假如我們現在正在 dev2 分支上進行開發,開發到一半,突然發現 master 分支上面有 bug,需要解決。在Git中,每個 bug 都可以通過一個新的臨時分支來修復,修復后,合并分支,然后將臨時分支刪除。
可現在 dev2 的代碼在工作區中開發了一半,還無法提交,怎么辦?例如:
[root@MyComputer:gitcode]# git branchdev2
* master
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
Hello dev bbb
TTTTTTTTTTTTTTTT
[root@MyComputer:gitcode]# git checkout dev2
Switched to branch 'dev2'
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
Hello dev bbb
TTTTTTTTTTTTTTTT
[root@MyComputer:gitcode]# vim ReadMe
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
Hello dev bbb
TTTTTTTTTTTTTTTT
i am coding...
[root@MyComputer:gitcode]# git checkout master
M ReadMe
Switched to branch 'master'
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
Hello dev bbb
TTTTTTTTTTTTTTTT
i am coding...
[root@MyComputer:gitcode]# git status
On branch master
Changes not staged for commit:(use "git add <file>..." to update what will be committed)(use "git restore <file>..." to discard changes in working directory)modified: ReadMeno changes added to commit (use "git add" and/or "git commit -a")
我們驚奇的發現dev2分支中的代碼跑到master分支去了,但是我們還是提交的狀態下,雖然只是在工作區修改了,沒有對本地倉庫有影響,但是我們還是不想讓他出現在master分支上,怎么辦呢?
要切回當前開發的分支上,Git 提供了 git stash
命令,可以將當前的工作區信息進行儲藏,被儲藏的內容可以在將來某個時間恢復出來。
[root@MyComputer:gitcode]# git checkout dev2
M ReadMe
Switched to branch 'dev2'
[root@MyComputer:gitcode]# git stash
Saved working directory and index state WIP on dev2: a3198a4 add TTTTTT
[root@MyComputer:gitcode]# git status
On branch dev2
nothing to commit, working tree clean
用git status
查看工作區,就是干凈的(除非有沒有被 Git 管理的文件),因此可以放心地創建分支來修復bug。
儲藏 dev2 工作區之后,由于我們要基于master分支修復 bug,所以需要切回 master 分支,再新建臨時分支來修復 bug,示例如下:
[root@MyComputer:gitcode]# git branchdev2
* master
[root@MyComputer:gitcode]# git checkout -b fix_bug # 新建并切換到 fix_bug 分支
Switched to a new branch 'fix_bug'
[root@MyComputer:gitcode]# vim ReadMe
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
Hello dev bbb
TTTTTTTTTTTTTTTTYYY # 修復bug--忘記寫YYY了
[root@MyComputer:gitcode]# git add . # 重新add,commit
[root@MyComputer:gitcode]# git commit -m "fix YYY"
[fix_bug dcc0212] fix YYY1 file changed, 1 insertion(+), 1 deletion(-)
修復完成后,切換到 master 分支,并完成合并,最后刪除 fix_bug 分支:
[root@MyComputer:gitcode]# git checkout master
Switched to branch 'master'
[root@MyComputer:gitcode]# git merge --no-ff -m "merge fix_bug YYY" fix_bug
Merge made by the 'ort' strategy.ReadMe | 2 +-1 file changed, 1 insertion(+), 1 deletion(-)
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
Hello dev bbb
TTTTTTTTTTTTTTTTYYY
[root@MyComputer:gitcode]# git branch -d fix_bug
Deleted branch fix_bug (was dcc0212).
至此,bug 的修復工作已經做完了,我們還要繼續回到 dev2 分支進行開發。切換回 dev2 分支:
[root@MyComputer:gitcode]# git checkout dev2
Switched to branch 'dev2'
[root@MyComputer:gitcode]# git status
On branch dev2
nothing to commit, working tree clean
工作區是干凈的,剛才的工作現場存到哪去了?用git stash list
命令看看:
[root@MyComputer:gitcode]# git stash list
stash@{0}: WIP on dev2: a3198a4 add TTTTTT
工作現場還在,Git 把 stash 內容存在某個地方了,但是需要恢復一下,如何恢復現場呢?
我們可以使用 git stash pop
命令,恢復的同時會把 stash 也刪了,示例如下:
[root@MyComputer:gitcode]# git stash pop
On branch dev2
Changes not staged for commit:(use "git add <file>..." to update what will be committed)(use "git restore <file>..." to discard changes in working directory)modified: ReadMeno changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (99f3d6b036650df55ff0fdd8b93f2847e5ae2315)
再次查看的時候,我們已經發現已經沒有現場可以恢復了
[root@MyComputer:gitcode]# git stash list
[root@MyComputer:gitcode]#
另外,恢復現場也可以采用 git stash apply
恢復,但是恢復后,stash內容并不刪除,你需要用 git stash drop
來刪除;
你可以多次stash,恢復的時候,先用 git stash list
查看(1. 查看 stash 列表:顯示當前倉庫中所有 stash 的記錄,包括 stash 的名稱、創建時間、關聯的分支以及簡短描述。2. stash 命名規則:默認格式為 stash@{n},其中 n 是一個數字,表示 stash 的順序(例如 stash@{0} 是最近創建的 stash)。),然后恢復指定的stash,用命令git stash apply stash@{0}
,這部分請自行使用哦。
恢復完代碼之后我們便可以繼續完成開發,開發完成后便可以進行提交,例如:
[root@MyComputer:gitcode]# vim ReadMe
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
Hello dev bbb
TTTTTTTTTTTTTTTT
i am coding... Done!!!!!
[root@MyComputer:gitcode]# git add .
[root@MyComputer:gitcode]# git commit -m "coding Done!!"
git commit -m "coding Donegit add ."
[dev2 91503fd] coding Donegit add .1 file changed, 1 insertion(+)
但我們注意到了,修復 bug 的內容,并沒有在 dev2 上顯示。此時的狀態圖為:
Master 分支目前最新的提交,是要領先于新建 dev2 時基于的 master 分支的提交的,所以我們在 dev2 中當然看不見修復 bug 的相關代碼。
我們的最終目的是要讓 master 合并 dev2 分支的,那么正常情況下我們切回 master 分支直接合并即可,但這樣其實是有一定風險的。
是因為在合并分支時可能會有沖突,而代碼沖突需要我們手動解決(在 master 上解決)。我們無法保證對于沖突問題可以正確地一次性解決掉,因為在實際的項目中,代碼沖突不只一兩行那么簡單,有可能幾十上百行,甚至更多,解決的過程中難免手誤出錯,導致錯誤的代碼被合并到 master 上。
此時的狀態為:
解決這個問題的一個好的建議就是:最好在自己的分支上合并下 master ,再讓 master 去合并dev ,這樣做的目的是有沖突可以在本地分支解決并進行測試,而不影響 master 。
此時的狀態為:
對應的實操演示如下,要說明的是,以下演示的merge操作,沒有使用 --no-ff
,但上述的圖示是禁用 Fast forward
了模式后得出的,主要是為了方便解釋問題。
# dev 合并 master
[root@MyComputer:gitcode]# git branch
* dev2master
[root@MyComputer:gitcode]# git merge master
Auto-merging ReadMe
CONFLICT (content): Merge conflict in ReadMe
Automatic merge failed; fix conflicts and then commit the result.# 發生沖突
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
Hello dev bbb
<<<<<<< HEAD
TTTTTTTTTTTTTTTT
i am coding... Done!!!!!
=======
TTTTTTTTTTTTTTTTYYY
>>>>>>> master
# 解決沖突并重新提交
[root@MyComputer:gitcode]# vim ReadMe
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
Hello dev bbb
TTTTTTTTTTTTTTTTYYY
i am coding... Done!!!!!
[root@MyComputer:gitcode]# git add .
[root@MyComputer:gitcode]# git commit -m "merge master"
[dev2 b7350df] merge master
[root@MyComputer:gitcode]# git status
On branch dev2
nothing to commit, working tree clean# 切回master
[root@MyComputer:gitcode]# git checkout master
Switched to branch 'master'# master 合并 dev2---無需解決沖突問題!!
[root@MyComputer:gitcode]# git merge dev2
Updating c275380..b7350df
Fast-forwardReadMe | 1 +1 file changed, 1 insertion(+)
[root@MyComputer:gitcode]# git status
On branch master
nothing to commit, working tree clean# 刪除dev2分支
[root@MyComputer:gitcode]# git branch -d dev2
Deleted branch dev2 (was b7350df).
刪除臨時分支
軟件開發中,總有無窮無盡的新的功能要不斷添加進來。
添加一個新功能時,你肯定不希望因為一些實驗性質的代碼,把主分支搞亂了,所以,每添加一個新功能,最好新建一個分支,我們可以將其稱之為 feature 分支,在上面開發,完成后,合并,最后,刪除該 feature 分支。
可是,如果我們今天正在某個 feature 分支上開發了一半,被產品經理突然叫停,說是要停止新功能的開發。雖然白干了,但是這個 feature 分支還是必須就地銷毀,留著無用了。這時使用傳統的 git branch -d
命令刪除分支的方法是不行的。
演示如下:
# 新增并切換到dev3分支
[root@MyComputer:gitcode]# git branch
* master
[root@MyComputer:gitcode]# git checkout -b dev3
Switched to a new branch 'dev3'# 開始開發新功能并提交
[root@MyComputer:gitcode]# vim ReadMe
[root@MyComputer:gitcode]# cat ReadMe
Hello lwz
Hello lwz
Hello world!!!!
Hello Git
Hello version1
Hello version2
Hello version3
Hello dev bbb
TTTTTTTTTTTTTTTTYYY
i am coding... Done!!!!!long long long
[root@MyComputer:gitcode]# git add .
[root@MyComputer:gitcode]# git commit -m "add long"
[dev3 41fbfec] add long1 file changed, 2 insertions(+)# 此時新功能叫停# 切回master準備刪除dev3
[root@MyComputer:gitcode]# git checkout master
Switched to branch 'master'# 常規刪除dev3分支失敗
[root@MyComputer:gitcode]# git branch -d dev3
error: The branch 'dev3' is not fully merged.
If you are sure you want to delete it, run 'git branch -D dev3'.
直接使用傳統的刪除分支的方法不行,按照提示,有了如下方式:
[root@MyComputer:gitcode]# git branch -D dev3
Deleted branch dev3 (was 41fbfec).
[root@MyComputer:gitcode]# git branch
* master
done!
小結
分支在實際中有什么用呢?
假設你準備開發一個新功能,但是需要兩周才能完成,第一周你寫了50%的代碼,如果立刻提交,由于代碼還沒寫完,不完整的代碼庫會導致別人不能干活了。如果等代碼全部寫完再一次提交,又存在丟失每天進度的巨大風險。
現在有了分支,就不用怕了。你創建了一個屬于你自己的分支,別人看不到,還繼續在原來的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到開發完畢后,再一次性合并到原來的分支上,這樣,既安全,又不影響別人工作。
并且 Git 無論創建、切換和刪除分支,Git在1秒鐘之內就能完成!無論你的版本庫是1個無件還是1萬個文件。