一、分支介绍
分支是git的特性之一,它使得代码可以有多中不同的方向和代码路线,协作过程中彼此之间互不影响,大大增加了代码库的灵活性。
一般来说,项目的开发模型为:给定主分支master用于统筹所有代码,其他的功能拆散在子分支上开发,最后都合并到master。例如一个用于用户登录功能的代码库,用户A开启分支完成账户注册,用户B开启分支完成用户授权,两者在开发期间互不影响,开发完成后合并到主分支上合并完成总功能。
中间蓝色的表示主分支,上下两条表示子分支,子分支在初始时分离,最后都合并于主分支。
git中和分支相关的操作使用branch
命令完成,最简单的用法就是git branch
,它用于查看当前所在分支,加上-v选项显示详细信息。
显示的分支中默认只显示本地分支,如需显示远程分支要加上-a选项。
一个要注意的是:远程分支和本地分支即使名字相同也不是一个分支,彼此独立,git远程仓库相关可以参考git remote用法。
一个大型项目往往会有许多分支,例如openssl
的分支:
[ma@ma openssl]$ git branch -va
* master 2de108d Save and restore the Windows error around TlsGetValue.
# ... 省略
remotes/origin/OpenSSL_0_9_6-stable 645a865 Fixes so alerts are sent properly in s3_pkt.c
remotes/origin/OpenSSL_0_9_7-stable 9cbf440 Fix incorrect command for assember file generation on IA64
remotes/origin/OpenSSL_0_9_8-stable 7474341 Prepare for 0.9.8zi-dev
remotes/origin/OpenSSL_0_9_8fg-stable bfa33c7 Release OpenSSL 0.9.8g with various fixes to issues introduced with 0.9.8f
remotes/origin/OpenSSL_1_0_0-stable 2700723 ms/uplink-x86.pl: make it work.
remotes/origin/OpenSSL_1_0_1-stable 4675a56 apps/speed.c: Fix crash when config loading fails
remotes/origin/OpenSSL_1_0_2-stable d8908c3 Fix a bogus warning about an uninitialised var
remotes/origin/OpenSSL_1_1_0-stable 6d3cfd1 Skip CN DNS name constraint checks when not needed
remotes/origin/SSLeay dfeab06 Import of old SSLeay release: SSLeay 0.9.1b (unreleased)
remotes/origin/master 2de108d Save and restore the Windows error around TlsGetValue.
remotes/origin/tls1.3-draft-18 669c623 Update PR#3925
remotes/origin/tls1.3-draft-19 d4d9864 Update PR#3925
我们还可以通过git log --graph
命令以图形化形式来查看分支演变:
最左边的两条线即显示了一个分支从创建到合并的过程。
二、创建分支
创建分支命令:git branch 分支名
,例如git branch feature-login-auth-maqian
。同时还可以使用git checkout -b 分支名
创建分支,checkout
用于切换分支,加上-b
选项后会先创建该分支。
首先先从github上拉取一个代码库:
[work@localhost git]$ git clone git@github.com:maqianos/gitstudy.git
Cloning into ''gitstudy''...
[work@localhost git]$ cd gitstudy/
> ll
total 8
-rw-r--r--. 1 work root 17 May 24 16:02 master.md
-rw-r--r--. 1 work root 39 May 24 17:38 README.md
此时代码的分支信息为:
> git branch # 当前分支
* master
> git branch -a # 所有分支
* master # 本地分支
remotes/origin/master # 远程分支
创建分支:
> git branch feature-login-auth-maqian # 创建分支
> git branch -a # 查看当前所有分支
feature-login-auth-maqian
* master
remotes/origin/master
> git checkout feature-login-auth-maqian # 切换到分支
Switched to branch ''feature-login-auth-maqian''
> git branch # 查看当前本地所有分支
* feature-login-auth-maqian
master
三、合并分支
在子分支生成修改并提交:
> touch feature-login-auth-maqian.md
> git status -s
?? feature-login-auth-maqian.md
> git add feature-login-auth-maqian.md
> git commit -m ''[ADD] featre: auth''
推送到远程分支:
# 注意写上分支名,默认是master,不要推到master上去了
> git push origin feature-login-auth-maqian
Counting objects: 3, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 337 bytes | 6.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:maqianos/gitstudy.git
* [new branch] feature-login-auth-maqian -> feature-login-auth-maqian
子分支推到远程分支后,切换到主分支合并它:
> git checkout master # 切换到主分支
Switched to branch ''master''
Your branch is up to date with ''origin/master''.
> git fetch # 获取更新,由于分支是在本地推送过去的,所以本地就是最新
> ll # 没合并之前没有子分支创建的文件
total 8
-rw-r--r--. 1 work root 17 May 24 16:02 master.md
-rw-r--r--. 1 work root 39 May 24 17:38 README.md
> git merge feature-login-auth-maqian # 合并分支
Updating 0fc1fe3..3871204
Fast-forward
feature-login-auth-maqian.md | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 feature-login-auth-maqian.md
> ll # 合并后出现子分支的文件
total 8
-rw-r--r--. 1 work root 0 May 24 17:56 feature-login-auth-maqian.md # **
-rw-r--r--. 1 work root 17 May 24 16:02 master.md
-rw-r--r--. 1 work root 39 May 24 17:38 README.md
四、解决冲突
上面的合并是一种最理想的合并,即A分支中的修改在B分支中没有被修改(两个分支修改的内容不重复),对于这种情况,git能自动识别出来并自动合并内容。但是对于两个不同分支同时修改了代码的同一行,合并时就会出现冲突。因为git无法判定哪个修改是有效的,此时需要手动解决冲突。
在feature-login-auth-maqian
分支中对代码进行修改:
> git co feature-login-auth-maqian # 切换分支
Switched to branch ''feature-login-auth-maqian''
> echo "HelloWorld-feature" > feature-login-auth-maqian.md # 添加更改
## 提交代码
> git add *
> git commit -m ''[UPDATE] auth''
[feature-login-auth-maqian 8d49ce2] [UPDATE] auth
1 file changed, 1 insertion(+)
> git push origin feature-login-auth-maqian # 提交到远程分支
Counting objects: 3, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 357 bytes | 357.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:maqianos/gitstudy.git
3871204..8d49ce2 feature-login-auth-maqian -> feature-login-auth-maqian
切换到master
也更改代码:
> git co master
Switched to branch ''master''
Your branch is ahead of ''origin/master'' by 1 commit.
(use "git push" to publish your local commits)
> git fetch
> echo "HelloWorld-master" > feature-login-auth-maqian.md
> git add *
> git commit -m ''[UPDATE] atuh''
[master aac14dd] [UPDATE] atuh
1 file changed, 1 insertion(+)
合并代码:
> git merge origin/feature-login-auth-maqian
Auto-merging feature-login-auth-maqian.md
CONFLICT (content): Merge conflict in feature-login-auth-maqian.md
Automatic merge failed; fix conflicts and then commit the result.
此时就提示两个文件有冲突了,因为两个文件都修改了同一处代码,git无法判断以哪个为准,所以合并失败。
看一下代码文件:
<<<<<<< HEAD
HelloWorld-master
=======
HelloWorld-feature
>>>>>>> origin/feature-login-auth-maqian
一个有趣的现象是,当我正在使用vscode编辑这篇文章的时候,我把上面这段冲突的代码复制进来之后,vscode自动帮我处理了成了下面的样子:
简单明了的演示免去了我一顿口舌。
所以现在要做的就是删掉无用代码,然后选择想要的版本手动更新:
# 修改后的代码
> cat feature-login-auth-maqian.md
HelloWorld-master
HelloWorld-feature
重复之前的步骤add commit push
即可解决冲突。
此处评论已关闭