之前在写一些demo例子的时候, 每个不同的案例都是在同一个工程的不同目录下. 但是由于有些案例其实是不需要相关依赖的, 但是由于添加到了同一个工程中, 会导致依赖不清晰的问题. 解决方法就是, 以master为基本创建不同的分支, 每个分支为不同的案例, 各个分支不需要合并即可!
阅读本文你将学会:
- 什么是Git中的分支? 分支的使用场景?
- 如何创建、查看、切换、删除本地分支?
- 如何合并分支?
- Git版本回退操作
- Git克隆远程仓库的指定分支
- 如何将本地分支推送到远程?
- ……
Git分支相关总结
之前在写一些项目案例的时候, 都是创建一个大工程, 然后创建多个目录分别存放, 各个案例. 但是对于各个案例来说, 由于在同一个工程, 所以依赖也都放在了一起, 时间长就造成了依赖混乱等问题.
之后, 采用Git分支解决了这个问题:
- 首先创建了一个仓库, 处于master分支;
- 然后在master的基础上分别创建不同的分支, feature, feature2, feature3…
- 在不同的分支上创建不同的工程即可!
所以本文主要总结了与Git分支相关的一些知识.
一. Git中分支的使用场景
分支在实际中有什么作用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了,如果等代码全部写完再一次性提交,又存在丢失每天进度的巨大风险。
现在有了分支,就不用怕了,你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。
分支的主要作用有:
- 版本迭代更加清晰
- 开发效率提升
- 利于代码review的实现,从而使整个团队开发更加规范,减少bug率
二. 分支的常规操作
1. 查看分支
1 | git branch -a |
2. 创建、切换分支
创建并切换分支:git checkout -b <分支名称>
这条命令和下面两条命令效果相同:
创建分支:git branch <分支名称>
切换分支:git checkout <分支名称>
1 | zk@jasonkay:~/test$ git branch test |
3. 合并分支
git checkout master 先切换到master分支
git merge test 再将B分支的代码合并到master(在merge合并分支的时候,代码会有冲突,需要自己去解决这些冲突)
语法: (切换到主分支) -> git merge <想要合并的分支名>
3.1 合并冲突分支
有时候合并操作并不会如此顺利, 如果在不同的分支中都修改了同一个文件的同一部分,Git 就无法干净地把两者合到一起(译注:逻辑上说,这种问题只能由人来裁决)
如:
1 | $ git merge iss53 |
Git 作了合并,但没有提交,它会停下来等你解决冲突。要看看哪些文件在合并时发生冲突,可以用 git status 查阅:
1 | $ git status |
任何包含未解决冲突的文件都会以未合并(unmerged)的状态列出, Git 会在有冲突的文件里加入标准的冲突解决标记,可以通过它们来手工定位并解决这些冲突!
可以看到此文件包含类似下面这样的部分:
1 | <<<<<<< HEAD |
可以看到 ======= 隔开的上半部分,是 HEAD(即 master 分支,在运行 merge 命令时所切换到的分支)中的内容,下半部分是在 iss53 分支中的内容.
解决冲突的办法无非是二者选其一或者由你亲自整合到一起
比如你可以通过把这段内容替换为下面这样来解决:
1 | <div id="footer"> |
这个解决方案各采纳了两个分支中的一部分内容,而且我还删除了 <<<<<<<,======= 和 >>>>>>> 这些行.
在解决了所有文件里的所有冲突后,运行 git add 将把它们标记为已解决状态(译注:实际上就是来一次快照保存到暂存区域)
因为一旦暂存,就表示冲突已经解决!
如果你想用一个有图形界面的工具来解决这些问题,不妨运行 git mergetool,它会调用一个可视化的合并工具并引导你解决所有冲突:
1 | $ git mergetool |
如果不想用默认的合并工具(Git 为我默认选择了 opendiff,因为我在 Mac 上运行了该命令),你可以在上方”merge tool candidates”里找到可用的合并工具列表,输入你想用的工具名
退出合并工具以后,Git 会询问你合并是否成功。如果回答是,它会为你把相关文件暂存起来,以表明状态为已解决。
再运行一次 git status 来确认所有冲突都已解决:
1 | $ git status |
如果觉得满意了,并且确认所有冲突都已解决,也就是进入了暂存区,就可以用 git commit 来完成这次合并提交
提交的记录差不多是这样:
1 | Merge branch 'iss53' |
4. 删除分支
当分支已经合并到主分支,并且不再需要接着该分支继续开发(后期也可以从主分支分出来),可以删除该分支
删除不是当前分支: git branch -d <分支名称>
强行删除当前打开分支: git branch -D <分支名称>
1 | zk@jasonkay:~/test$ git branch -d test |
5. 误删分支恢复
Git会自行负责分支的管理,所以当我们删除一个分支时,Git只是删除了指向相关提交的指针,但该提交对象依然会留在版本库中
如果我们知道删除分支时的散列值,就可以将某个删除的分支恢复过来.
在已知提交的散列值的情况下恢复某个分支: git branch <branch_name> <hash_val>
1 | zk@jasonkay:~/test$ git branch test b8eb |
注: 命令创建提交号历史版本的一个分支,分支名称随意
不知道想要恢复的分支的散列值,可以用reflog命令或者log命令将它找出来
如:
1 | zk@jasonkay:~/test$ git reflog |
reflog命令:显示整个本地仓储的commit,包括所有branch的commit,甚至包括已经撤销的commit. 只要HEAD发生了变化, 就会在reflog里面看得到!
或者使用log命令:
1 | zk@jasonkay:~/test$ git log |
log命令: 查看历史提交日志
6. 查看分支图
git log --graph
为了使分支图更加简明,可以加上一些参数: git log --graph --pretty=oneline --abbrev-commit
例如:
1 | zk@jasonkay:~/test$ git log --graph |
7. 重命名分支
git branch –m <当前分支名> <新的分支名>
1 | zk@jasonkay:~/test$ git branch -a |
8. 总结
git与分支相关的说明总结如下表:
| 说明 | 命令 | 备注 |
|---|---|---|
| 查看分支(本地+远程) | git branch -a | |
| 创建分支 | git branch <分支名称> | |
| 切换分支 | git checkout <分支名称> | 也支持 git switch <分支名称> |
| 合并分支 | git merge <被当前分支合并的分支名> | 需要切换其他分支完成合并 |
| 创建+切换分支 | git checkout -b <分支名称> | 或者使用 git switch -c <分支名称> |
| 删除分支 | git branch -d <分支名称> git branch -D <分支名称> |
删除不是当前分支使用-d 强行删除当前打开分支-D |
| 分支恢复 | git branch <分支名称> <删除分支时散列值> | |
| 显示本地仓储的commit | git reflog | 包括所有branch的commit,甚至包括已经撤销的commit. 只要HEAD发生了变化, 就会在reflog里面看得到 |
| 显示历史/分支图 | git log [–graph] [–pretty=oneline] [–abbrev-commit] | 可添加git log的参数做显示优化 |
| 重命名分支 | git branch –m <当前分支名> <新的分支名> |
三. Git分支与远程仓库
1. git克隆远程仓库的指定分支
普通克隆方式:
1 | git clone <远程仓库地址> |
这种克隆方式默认是克隆master主分支, 而且通过命令 git branch –list 能看到克隆后在本地也只有这一个分支, 如果再通过新建分支再拉取指定分支,甚至可能还需要解决冲突,太繁琐.
有效的直接克隆远程指定分支, 只需要一条命令:
1 | git clone -b <指定分支名> <远程仓库地址> |
会自动在克隆该分支在本地,同样克隆后本地只有这一个分支!
2. 本地分支推送远程仓库
对于本地创建的分支, 该如何推送到远程仓库呢?
下面看一个例子:
首先, 创建一个test分支并切换至:
1 | $ git checkout -b test |
然后进行一些添加并提交:
1 | $ vi test.txt |
此时, 新增了一个分支, 并作出了内容的修改, 而远程是没有这个分支的! 所以在新的分支下直接提交将会报错!
错误内容类似下面:
1 | $ git push |
当直接直接git push的时候,就会报错提示没有设置上游的远程仓库,只要按照提示执行即可:
1 | $ git push --set-upstream origin test |
此时Github上会有对应的PR请求, 接受即可!
附录
文章参考: