一、创建与合并分支
创建分支:Git创建一个分支很快,因为除了增加一个指针,改改HEAD的指向,工作区的文件都没有任何变化。
合并分支:就是直接把master(其中一条分支)指向dev(另一条分支)的当前提交,就完成了合并。Git合并分支也很快!就改改指针,工作区内容也不变。合并完分支后,甚至可以删除dev分支,内容也不会发生变化。
因为创建、合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master分支上工作效果是一样的,但过程更安全。
1、创建分支
(1)命令git checkout -b dev(新分支名称)
创建分支dev,且切换到分支dev(自定义新分支名称)。
$ git checkout -b dev #创建并切换到分支dev
Switched to a new branch 'dev'
相当于:
$ git branch dev #创建新分支dev
$ git checkout dev #切换到分支dev
(2)命令git switch -c dev(新分支名称)
创建分支并切换到分支,作用与git checkout -b dev相同,是新版本的Git提供了新的命令来切换分支,相比较不容易与撤销修改的git checkout -- <file>命令弄混。
(3)命令git branch dev(新分支名称)
创建新分支
(4)命令git checkout dev(分支名称)
切换到分支dev
(5)命令 git switch dev(分支名称)
作用同git checkout dev,切换到分支dev,相对更好理解。
(6)命令 git branch
查看当前分支,列出所有分支,当前分支前面会标一个*号。
$ git branch
* dev
master
2、合并分支
解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。
(1)命令git merge dev(指定分支)
用于合并指定分支到当前分支。例如,把dev分支的工作成果合并到master分支上
$ git merge dev #将dev分支合并到master分支上
Updating 53e89d7..ea4444f
Fast-forward
readme.txt | 1 +
test.txt | 0
2 files changed, 1 insertion(+)
create mode 100644 test.txt
上面的Fast-forward信息是指这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。也不是每次合并都能Fast-forward。
3、删除分支
(1)命令git branch -d dev(指定分支)
删除指定的分支。可在合并完成分支后,就可以放心地删除dev分支。
$ git branch -d dev
Deleted branch dev (was ea4444f).
在查看分支会发现,dev分支已被删除。
$ git branch
* master
二、解决冲突
当两个不同分支各自分别都有新的提交的时候,Git无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突,结果如下:
$ git merge feature1
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.
Git告诉我们,readme.txt文件存在冲突,必须手动解决冲突后再提交。
1、查看分支冲突方法如下:
(1)查看状态Git status,能够发现冲突的文件。
$ 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: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
(2)命令 cat readme.txt(文件名)
直接查看该冲突文件(readme.txt)的内容.
$ cat readme.txt #查看文件内容
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick.
Creating a new branch is quick AND simple.
>>>>>>> feature1
Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容。
2、解决分支冲突
(1)命令vi readme.txt
——用vi 文件路径或者文件名,打开文件,如果文件存在则打开现有文件,如果文件不存在则新建文件,并在终端最下面一行显示打开的是一个新文件。
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick.
Creating a new branch is quick AND simple.
>>>>>>> feature1
~
~
~
~
~
~
~
~
~
~
~
~
readme.txt [dos] (22:58 07/03/2023) 1,1 All
"readme.txt" [dos] 10L, 324B
——键盘输入字母 “i”或“Insert”键进入最常用的插入编辑模式。
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick.
Creating a new branch is quick AND simple.
>>>>>>> feature1
~
~
~
~
~
readme.txt[+] [dos] (22:58 07/03/2023) 1,1 All
-- INSERT --
——按下 “ESC” 键,退出编辑模式,切换到命令模式。
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
Creating a new branch is quick and simple.
~
~
~
~
readme.txt [dos] (23:27 07/03/2023)
——在命令模式下键入"ZZ"或者":wq"保存修改并且退出 vi 。终端会回到命令行
li***@LAPTOP-MUI**V M**** ~/learngit (master|MERGING)
$ vi readme.txt
(2)修改readme.txt文件的内容。
修改如下后保存:
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
Creating a new branch is quick and simple.
~
~
~
readme.txt[+] [dos] (22:58 07/03/2023) 5,43 All
-- INSERT --
再使用git add <file> 和 git commit -m "***"命令将修改的结果传递到版本库。
(3)命令 git log --graph --pretty=oneline --abbrev-commit
用带参数的git log也可以看到分支的合并情况。可以看见两个分支已经合并在一起。
$ git log --graph --pretty=oneline --abbrev-commit
* 47e9b49 (HEAD -> master) conflict fixed
|\
| * cd8fa2d (feature1) AND simple
* | 6f306dd &simple
|/
* ea4444f branch text
* 53e89d7 remove test.txt
* ed0dc67 add test.txt
* e87225d git tracks changes 1
* fe8a3cb git tracks changes
* 52edc0e understand how stage works
* 9178f48 append GPL
* 84cca88 add distributed
* bdcbe49 wrote a readme file
(4)删除feature1分支
$ git branch -d feature1
Deleted branch feature1 (was cd8fa2d).
(5)命令git log --graph
可以看到分支合并图
$ git log --graph
* commit 47e9b49ea475102cdd81144b2cb7f424974f7962 (HEAD -> master)
|\ Merge: 6f306dd cd8fa2d
| | Author: Li*** <85077**5@qq.com>
| | Date: Tue Mar 7 23:34:39 2023 +0800
| |
| | conflict fixed
| |
| * commit cd8fa2dfc14b5fb4a198335a3b58d5c86f939e11
| | Author: Li** <8507**5@qq.com>
| | Date: Tue Mar 7 22:56:24 2023 +0800
| |
| | AND simple
| |
* | commit 6f306dd4b51387d266750c48db4cf962e2021f61
|/ Author: Li** <8507***@qq.com>
| Date: Tue Mar 7 22:58:03 2023 +0800
|
| &simple
|
* commit ea4444f2e72b57d5b2711e770304c9aced4de436
| Author: Li** <8507***@qq.com>
| Date: Tue Mar 7 17:25:26 2023 +0800
|
:
注意:终端不会自动退出graph命令,需要手动输入q,才能结束。
三、分支管理策略
1、强制禁止用Fast forward模式合并分支
因为Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。
(1)命令git merge --no-ff -m "merge with no-ff" dev
合并dev分支,其中--no-ff参数,表示禁用Fast forward合并。本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。
$ git merge --no-ff -m"merge with no-ff" dev
Merge made by the 'ort' strategy.
readme.txt | 1 +
1 file changed, 1 insertion(+)
使用命令git log --graph --pretty=oneline --abbrev-commit 查看分支记录
不用Fast forward模式合并分支,得到的分支合并如下图:
2、分支策略
在实际开发中,我们应该按照几个基本原则进行分支管理:
(1)master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
(2)平时的工作都在新建的dev上修改,再合并到master分支上。
(3)另外每个项目小伙伴又有自己的分支,时不时的合并到分支dev上。
四、Bug分支
每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。
1、暂时存储还未完成的工作
工作只进行到一半,还没法提交,预计完成还需1天时间。但是,必须在两个小时内修复该bug。
(1)命令git stash
把当前工作现场“储藏”起来,等以后恢复现场后继续工作
$ git stash
Saved working directory and index state WIP on dev: f52c633 add merge
(2)命令 git stash list
查看保存的工作现场
$ git stash list
stash@{0}: WIP on dev: f52c633 add merge
当看不到stash@{0}: WIP on dev: f52c633 add merge时,说明stash被删除。
(3)命令git stash pop
恢复工作现场,恢复的同时把stash内容也删了。
$ git stash pop
On branch dev
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: hello.py
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: readme.txt
Dropped refs/stash@{0} (5d677e2ee266f39ea296182fb2354265b91b3b2a)
(4)命令git stash apply stash@{0}(指定的stash)
恢复指定的stash,可以通过命令git stash list命令查看stash内容。
$ git stash apply stash@{0}
(5)命令git stash drop
删除stash的内容。
2、修复其他分支的Bug
(1)git cherry-pick commit_id
复制4c805e2 fix bug 101这个提交所做的修改,并不是把整个master分支merge过来。可以不用单独在另一个分支再做一次bug修改。
$ git cherry-pick 91a4683
[dev c2e6bc1] fix bug 101
Date: Wed Mar 8 17:13:16 2023 +0800
1 file changed, 1 insertion(+), 1 deletion(-)
小结
修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;
当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场;
在master分支上修复的bug,想要合并到当前dev分支,可以用git cherry-pick <commit>命令,把bug提交的修改“复制”到当前分支,避免重复劳动。
五、Feature分支-删除未合并的分支
添加一个新功能时,你肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合并,最后,删除该feature分支。
(1)常规删除未合并的分支
使用git branch -d 分支名,无法删除分支
$ git branch -d feature-vulcan
error: The branch 'feature-vulcan' is not fully merged.
If you are sure you want to delete it, run 'git branch -D feature-vulcan'.
(2)命令git branch -D 分支名
feature-vulcan分支还没有被合并,如果删除,将丢失掉修改,如果要强行删除,需要使用大写的-D参数。
$ git branch -D feature-vulcan #删除未合并的分支
Deleted branch feature-vulcan (was f4c738d).
六、多人协作
1、抓取分支
多人协作时,大家都会往master和dev分支上推送各自的修改。
$ git clone git@github.com:lily-wang0524/learngit.git
Cloning into 'learngit'...
remote: Enumerating objects: 44, done.
remote: Counting objects: 100% (44/44), done.
remote: Compressing objects: 100% (26/26), done.
remote: Total 44 (delta 14), reused 43 (delta 13), pack-reused 0
Receiving objects: 100% (44/44), done.
Resolving deltas: 100% (14/14), done.
$ git branch
* main
当你的小伙伴从远程库clone时,默认情况下,你的小伙伴只能看到本地的master分支。
(1)命令git checkout -b dev origin/dev
创建远程origin的dev分支到本地,才能在dev分支上开发。
(2)命令 git branch --set-upstream-to=origin/dev dev
指定本地dev分支与远程origin/dev分支的链接。
(3)命令git pull
把最新的提交从分支上抓下来,然后本地合并。
多人协作总结:
多人协作的工作模式:
(1)首先,可以试图用git push origin <branch-name>推送自己的修改。
(2)如果推送失败,则因为远程分支比你的本地更新,需要先用git pull从分支上把最新提交的内容抓取下来并试图本地合并;
(3)如果合并有冲突,则解决冲突,并在本地提交;
(4)没有冲突或者解决掉冲突后,再用git push origin <branch-name>推送就能成功!
(5)如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>。
七、分支合并-rebase
(1)命令git rebase
rebase命令也是合并分支的一种方式,但其与merge有所不同,rebase操作可以把本地未push的分叉提交历史整理成直线,使得我们在查看历史提交的变化时更容易,但是无法跟踪在目标分支上合并的时间和方式。而merge的记录是完整的。
1)下图为使用rebase命令
2)下图为使用merge命令