1.序

上一节 我们了解到gitlab和github的初使用,下面我们就git进行一个详细的讲解,让大家不再为git 而烦恼。

2.git详解

2.0 git历史

2.1版本控制

让我们先了解一下什么是版本控制。
1)协同修改
多人并行修改服务器端的同一个文件

2)数据备份
不仅保存目录和文件的当前状态,还能保存每一个提交过的历史状态。

3)版本管理
在保存每一个版本的文件信息的时候要做到不保存重复数据,以节约存储空间,提高运行效率。
这方面SVN采用的是增量式管理方式,而Git采取了文件系统快照的方式
4)权限控制
对团队中参与开发的人员进行权限控制 对团队外开发者贡献的代码进行审核 — Git独有

在公司中我们作为实习生或者刚入职的员工来说是没有大多数权限的,每次提交代码或者发版都需要leader审批的。这样可以避免很多线上的错误。
5)历史记录
查看修改人、修改时间、修改内容、日志信息。 将本地文件恢复到某一个历史状态。
6)分支管理
允许开发团队在工作过程中多条生产线同时推进任务,进一步提高效率。

2.2 git svn 区别

我前面提到过我之前项目中用到过svn以及git.其中svn是当时我们几个师兄师弟们天天坐在一起,所以采取了svn,速度更快一些。然后前半年由于疫情导致大家不能坐一起开发,所以我们采用了git,实现分布式开发。下面就讲讲它们之间的区别。

1)最核心的区别Git是分布式的,而Svn不是分布的。
Git跟Svn一样有自己的集中式版本库和Server端,但Git更倾向于分布式开发,因为每一个开发人员的电脑上都有一个Local Repository,所以即使没有网络也一样可以Commit,查看历史版本记录,创建项 目分支等操作,等网络再次连接上Push到Server端。
2)Git把内容按元数据方式存储,而SVN是按文件
因为.git目录是处于你的机器上的一个克隆版的版本库,它拥有中心版本库上所有的东西,例如标签,分支,版本记录等。
3)Git的内容的完整性要优于SVN: GIT的内容存储使用的是SHA-1哈希算法。???
这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。
4) 版本库(repository):SVN只能有一个指定中央版本库。
当这个中央版本库有问题时,所有工作成员都一起瘫痪直到版本库维修完毕或者新的版本库设立完成。而 Git可以有无限个版本库。或者,更正确的说法,每一个Git都是一个版本库,区别是它们是否拥有活跃目录(Git Working Tree)。如果主要版本库(例如:置於GitHub的版本库)发生了什麼事,工作成员仍然可以在自己的本地版本库(local repository)提交,等待主要版本库恢复即可。工作成员也可以提交到其他的版本库!
5)git 没有一个全局的版本号,而 SVN 有。 ???
目前为止这是跟 SVN 相比 Git 缺少的最大的一个特征。

2.3 git工作区域

当我们add 完就会进入暂存区
当我们commit完就会进入本地仓库区
当我们 push完就会进入远程仓库区

2.4 配置git

其实这一节和gitlab类似,但是还是有点出入,具体详解可以看这个博客。这里不再阐述。

2.5 git常用的命令

2.5.1 status 查看状态


未追踪的

已经提交到暂存区了

从暂存区删除了

2.5.2 log

1.git log

2.Head是当前的指针

3.每次只显示一行

4.多屏显示控制方式:
空格向下翻页
b 向上翻页
q 退出
5.前进或者后退历史版

基于索引值操作
使用 ^ 符合 使用~符合

2.5.3 git reflog

可以查看所有分支的所有操作记录(包括(包括commit和reset的操作),包括已经被删除的commit记录,
git log则不能察看已经删除了的commit记录,而且跟进结果可以回退道某一个修改:

2.5.4 回退

Git reset –hard 9a9ebe0
回退到哪个版本

1基于索引值操作
Git reset --hard[局部索引值]
2 使用^符合 ,只能后退
Git reset --hard HEAD^
一个^表示后退一步,n个表示后退n步
3 使用~符合;只能后退
Git reset --hard HEAD~n

2.5.5 强制提交

2.5.6 hard mixed soft对比

–soft 仅仅在本地库移动HEAD指针
–mixed 在本地库移动HEAD指针
重置暂存区
–hard参数 在本地库中移动HEAD指针
重置暂存区
重置工作区

删除文件找回

前提:删除前,文件存在时的状态提交到了本地库。
操作:git reset --hard[指针位置]

删除操作尚未提交到本地库:指针位置使用HEAD
删除操作已经提交到本地库:指针位置使用历史记录
git reset HEAD 是将咱暂存区和HEAD的提交保持一致
git reset --hard HEAD 是将工作区、暂存取和HEAD保持一致

2.5.7 比较文件

git diff: 对比工作区(未 git add)和暂存区(git add 后)
git diff --cache: 对比暂存区(git add 后)和版本库(git commit 后)
git diff HEAD: 对比工作区(未 git add)和版本库(git commit 后)

2.5.8 冲突

为什么会产生冲突?(可参考git发生冲突的实例)
因为在合并分支的时候,master分支和dev分支恰好有人都修改了同一个文件,GIT不知道应该以哪一个人的文件为准,所以就产生了冲突了。 两个分支相同文件相同位置的的不同操作!

如何解决?
发生冲突,在IDE里面一般都是对比本地文件和远程分支的文件,然后把远程分支上文件的内容手工修改到本地文件,然后再提交冲突的文件使其保证与远程分支的文件一致,这样才会消除冲突,然后再提交自己修改的部分。特别要注意下,修改本地冲突文件使其与远程仓库的文件保持一致后,需要提交后才能消除冲突,否则无法继续提交。必要时可与同事交流,消除冲突。
发生冲突,也可以使用命令。

此时说明本地修改与远程库有冲突,先add commit完再进行pull .

Head 当前分支的内容

====到master为另一个的内容

解决完冲突然后再提交。

如果遇到此时正在编辑的代码还不能提交到本地库。所以只能用git stash

2.5.9 stash

通过git stash命令,把工作区的修改提交到栈区,目的是保存工作区的修改;
通过git pull命令,拉取远程分支上的代码并合并到本地分支,目的是消除冲突;
通过git stash pop命令,把保存在栈区的修改部分合并到最新的工作空间中;

2.5.10 更改git url


查看更改后的

2.5.11 拉取指定分支代码解决方案

以拉取develop分支的代码为例, 要拉取其余分支代码类似操作
1.使用git命令拉取
命令:git clone -b develop XXX
其中develop就是分支的名称

2.6本地库和远程库交互方式


2.7 分支

同时并行推进多个功能开发,提高开发效率。
各个分支在开发过程中,如果一个分支开发失败,不会对其它分支有任何影响。失败的分支删除重新开始即可。
2.7.0 分支定义

Master
长期分支,存在与整个项目开发过程。
由项目主要技术负责人管理该分支。

release/xxx
release/test 和 release/prod
既可以为长期分支也可以为短期分支,可能存在于一个或者多个版本之间.
由测试负责人负责人管理该分支。

feature/fixbug/hotfix
临时分支
用于开发的具体功能特性和修复bug的分支,功能完成后删除.
格式为:feature_KaTeX parse error: Expected group after '_' at position 5: date_̲name_KaTeX parse error: Expected group after '_' at position 19: …cription fixbug_̲date_KaTeX parse error: Expected group after '_' at position 5: name_̲description
hotfix_KaTeX parse error: Expected group after '_' at position 5: date_̲name_$description

2.7.1查看有多少分支

2.7.2创建分支

1现在,你已经决定要解决你的公司使用的问题追踪系统中的 #53 问题。 想要新建一个分支并同时切换到那个分支上,你可以运行一个带有 -b 参数的 git checkout 命令:
$ git checkout -b iss53
Switched to a new branch “iss53”

2然后在新的分支上进行操作

3合并到主支
1 切换到主分支
2 Merge到主分支了

合并冲突解决

2.7.3 分支策略

规则1
开始工作前,从主干创建特性分支

每当开始一件新的工作项(比如新的功能或是bug)的时候,从最新已发布版本的主干Master上创建一个以feature(bugfix)/前缀命名的特性分支,然后在这个分支上提交代码修改。

每个工作项(可以是一个人完成,或是多个人协作完成)对应一个特性分支,所有的修改都不允许直接提交到主干。

规则2
通过合并特性分支,形成发布分支

从主干上拉出一条新分支,将所有本次要集成或发布的特性分支依次合并过去,从而得到发布分支。发布分支通常以release/前缀命名。

每条发布分支与具体的环境相对应,比如release/test分支对应部署测试环境,release/prod分支对应线上正式环境等等,并与流水线工具相结合,串联各个环境上的代码质量扫描和自动化测试关卡,将产出的部署包直接发布到相应环境上。

release/prod从master上拉取的时候master可能已经有其他更新上线了,此时从master拉取拉取的release/prod合并相关feature分支后需要进行回归测试。

规则3
发布到线上正式环境后,合并相应的发布分支到主干,在主干添加标签,同时删除该发布分支关联的特性分支

完成了线上正式环境的部署,就意味着相应的功能真正地发布了,此时应该将这条发布分支合并到主干。

为了避免在代码仓库里堆积大量历史上的特性分支,还应该清理掉已经上线部分特性分支。
主干分支上的最新版本始终与线上版本一致,如果要回溯历史版本,只需在主干分支上找到相应的版本标签即可。

其他

对于hotfix,可以创建一条新的发布分支对应线上环境(相当于hotfix分支),同时为这个分支创建临时流水线,以保障必要的发布前检查和冒烟测试能够自动执行。

如果非得修一个历史版本的Bug,在主干分支找到版本标签位置,然后从那个位置创建hotfix分支,这种情况比较少见

2.7.4开发流程

  • 新功能开发时,开发人员从Master拉取代码生成特性分支。
  • 单元测试完成后等待测试负责人拉取release/test分支,然后提交Pull Request
  • 开发负责人或者其他开发人员对Pull Request进行代码Review
  • 代码Review完成后,测试负责人合并Pull Request到release/test,如果遇到合并冲突,则让相应的开发人员把feature/bug/hotfix分支重新以master为基准进行提交以及让相应的开发人员协助解决。
  • 测试人员使用流水线工具进行代码质量扫描和自动化测试
  • 测试人员进行测试
  • 完成测试后,查看Master是否比拉取release/test时有更新,如果没有直接使用release/test上线,否则从最新Master拉取分支release/prod分支合并相关PR并进行回归测试
  • 提交上线申请上线
    示例:

开发人员A从Master拉取代码生成feature_20190818_A_get_users
开发人员B从Master拉取代码生成feature_20190819_B_login

测试负责人Y从Master拉取release/test
开发人员A提交Pull Request PR1
开发人员B提交Pull Request PR2

开发负责人F和开发人员C评审PR1 PR2,评审通过
测试负责人Y合并代码到release/test
测试人员X进行测试,完成后发现Master和拉取release/test时一样,直接使用release/test进行构建申请发布

2.7.5推送的时候设定推送地址

拉取操作

Pull = fetch + merge
Git fetch[远程库地址别名][远程分支名称]
Git merge[远程库地址别名/远程分支名称]

2.8 git 原理





最右边就是提交时的各个文件,中间就是文件树,左边就是提交对象

2.9忽略文件

我们再git 管理的项目中经常看到.gitignore。它就是忽略文件。在项目中,我们经常会有很多与开发代码没有直接关系的文件,可以直接忽略。

Gitignor文件需要设置的东西
#.gitignore常用格式
# .a 忽略所有 .a 结尾的文件
# !lib.a 但 lib.a 除外
# /TODO 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
# build/ 忽略 build/ 目录下的所有文件
# doc/
.txt 会忽略 doc tes.txt 但不包括 doc rver/arch.txt

2.10 Gitlab搭建过程

https://blog.csdn.net/weixin_41563161/article/details/106255300?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522160911844816780276326867%252522%25252C%252522scm%252522%25253A%25252220140713.130102334.pc%25255Fblog.%252522%25257D&request_id=160911844816780276326867&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_v1~rank_blog_v1-3-106255300.pc_v1_rank_blog_v1&utm_term=git

3.总结

Git 是 一个伟大的发明。它不在使我们电脑上有无数个版本,不再使我们一起坐在那里熬夜拷贝合并代码。一定要学会使用它,成为你的一把利刃。祝梦想成真!!!

4.个人推广

博客地址
https://blog.csdn.net/weixin_41563161
掘金https://juejin.cn/user/2814360172369271

知乎https://www.zhihu.com/people/hai-kuo-tian-kong-63-38-21