关于版本控制
- 什么是版本控制
- 版本控制(Version Control Systems)版本控制(Revision control)是一种软件工程技巧
- 在开发的过程中,确保由不同人所编辑的同一档案都得到更新
- 举例
- 我们通常都是手动的重命名一个文件进行备份的 hello.java改成hello1.java或者hello.java.bak等形式
- 然后这种方式对于单个文件我们还能够管理,但是对于整个项目而言,就会成为噩梦了!!!
- 文件版本常见问题
- 合并代码:两个人写的代码如何合并到一起
- 版本回退:在写代码过程当中, 代码出现错误,如如何才能加回到以前没有错误的代码
版本管理工具
集中式管理
特点:
- 集中式版本控制系统,版本库是集中存放在中央服务器的 而干活的时候,用的都是自己的电脑
- 所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器 中央服务器就好比是一个图书馆
- 你要改一本书,必须先从图书馆借出来,然后回到家自己改,改完了,再放回图书馆
缺点:
集中式版本控制系统最大的毛病就是必须联网才能工作 所有的版本都在一个服务器上面 如果服务挂了, 所有记录的版本都没了
分布式管理
特点:
- 分布式版本控制系统,则不需要中央服务器
- 每个协同开发者都拥有一个完整的版本库
- 这么一来,任何协同开发者用的服务器发生故障
- 事后都可以用其它协同开发者本地仓库恢复
结构:
使用方式:
- 在实际使用分布式版本控制系统的时候,其实很少在两人之间的电脑上推送版本库的修改,
- 因为可能你们俩不在一个局域网内,两台电脑互相访问不了,也可能今天你的同事病了,他的电脑压根没有开机。
- 因此,分布式版本控制系统通常也有一台充当“中央服务器”的电脑,
- 但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。
git版本管理
git介绍
- git是一款开源的分布式版本管理工具,作者Linux之父-Linus
- 当初Linus 仅仅是为了辅助Linux内核的开发才一并开发了这个至今为止世界上最快的、最简单的版本管理工具
软件安装
安装步骤:点击exe文件,一直下一步
安装完成效果
Git工作状态
- Git 管理项目时,文件流转分为三个工作区域
Git 的工作目录, 暂存区域, 以及本地仓库
- 对于任何一个文件,在 Git 内都只有三种状态
1.已修改(modified) 已修改表示修改了某个文件,但还没有提交保存
2.已暂存(staged) 已暂存表示把已修改的文件放在下次提交时要保存的清单中
3.已提交(committed) 已提交表示该文件已经被安全地保存在本地数据库中了
原理流程步骤
- 工作目录
- 从项目中取出某个版本的所有文件和目录,用以开始后续工作的叫做工作目录
- 这些文件实际上都是从 Git 目录中的压缩对象数据库中提取出来的
- 接下来就可以在工作目录中对这些文件进行编辑
- 暂存区域
只不过是个简单的文件 .git目录之下,名为index,它一般很小,一般不超过1KB左右 一般都放在 Git 目录中
有时候人们会把这个文件叫做索引文件
暂存区这个索引文件里面包含的是文件的目录树,像一个虚拟的工作区,在这个虚拟工作区的目录树中,记录了文件名、文件的时间戳、文件长度、文件类型以及最重要的SHA-1值,文件的内容并没有存储在其中
暂存区的作用:除非是绕过暂存区直接提交,否则Git想把修改提交上去,就必须将修改存入暂存区最后才能commit。每次提交的是暂存区所对应的文件快照
- git目录(本地仓库)
- 当我们在某个目录下运行git init命令后,在该目录下便会生成一个.git的子目录,这个目录是隐藏的。
- 它是 Git 用来保存元数据和对象数据库的地方,这个目录可以说是Git的核心
- 每次克隆镜像仓库时,实际上拷贝的这个目录里的内容而已
- 工作流程
1、在工作目录中修改文件。
2、暂存文件,将文件的快照放入暂存区域。
3、提交更新,找到暂存区域的文件,将快照永久性存储到Git仓库目录。 示图
git基本操作
- 初始化用户名和邮箱
git config --global user.name "自已的名字"
git config --global user.email "自已的邮箱地址"
# 查看配置的信息 git config --list
- 创建一个空的文件夹
- 在空的工程中通过git base here命令窗口初始化仓库
- 在空的项目当中创建添加一些文件
- 查看这些文件在git当中的状态 命令:git status
发现文件和文件夹的颜色都是红色 ,当出现这种情况的时候, 说明这些文件还没有添加到git仓库当中 - 把文件添加git仓库中
执行git add *命令后, 再查看状态
此时全部变成绿色, 文件已经添加到git暂存区当中,还没有提交 - 提交 执行git commit
在执行commit的时候 ,会进入一个vi编辑器界面, 提示让输入信息, 输入本次做了哪些操作, 保存并退出即可
在查看状态,已经没有任何需要提交的数据了
- 查看历史: git log 查看提交日志
对文件进行修改
- 打开index.txt对文件的内容添加进行修改
- 修改之后再查看状态时,会出现modified状态
此时需要再次提交到暂存区并提交
执行 git add * 和 git commit
- 通过git log查看日志,可以看到,有一条新的sha记录
- 恢复历史
第一个sha就是一个版本记录, 可能使用reset命令恢复到指定的版本
命令:git reset --hard sha值
分支
- 分支概念:
- 使用分支意味着你可以把你的工作从开发主线上分离开来,以免影响开发主线
- 几乎所有的版本控制系统都以某种形式支持分支。
- 创建分支:
命令:git branch 分支名称
- 查看分支
命令:git branch
绿色为当前所在分支,默认有一个master主分支 - 切换分支
命令:git checkout 分支名称
- 在newBranch分支上添加一些新的代码
在次查看状态
提交
再次切换到master分支上,查看日志,里面并没有在newBranch中添加的代码
- 合并分支
命令:git merge 分支名称
- 删除分支
命令:git branch -d 分支名称
共享仓库
- 用户clone项目
在当中目录下,clone用户1项目
命令:git clone 要复制的项目路径和名称 复制之后的项目路径和名称
- 共享仓库创建
共享仓库特点:
- 以项目名称.git结尾
- 看不到工作区
- 它只用来共享, 不能够进行修改添加等操作
- 从共享仓库当中clone的代码是可以看到工作的
创建共享仓库:
命令:
两种方式:
- git init --bare 仓库名称
- git clone --bare 要clone的项目路径和名称
共享仓库上传代码
- 在本地仓库当中添加文件, 添加加到本地仓库
- 先提交到本地仓库,再推送到远程仓库
推送命令:git push 远程仓库地址 分支名称
从共享仓库下拉代码
命令:git pull 仓库地址 分支名称
新建goods1文件夹 并初始化
解决冲突
- 什么是冲突
两个人共同协作开发时, 改了相同的文件,都做了提交
- 什么情况下会产生冲突
- 两人同时更改了相同的代码,并且都提交到了本地.
- 先提交到远程仓库的人不会有任何问题
- 后提交的人,需要先pull下来,在pull的时候,就会产生冲突
- 这时就需要先解决冲突,解决冲突完毕后,提交到本地, 再提交到远程仓库
操作:
用户1更改代码,提交代码,用户2做同样的操作
用户2提交远程的时候会报错
解决冲突
先从远程仓库下拉代码,但是也会出现报错
解决方案:
打开下拉的文件,进行手动修改,保留最终数据
删除<<<<<<head ======== >>>>>>>sha值
保留最终代码
在进行提交远程
gitLab操作
得现有gitLab账号,登陆上去 gitLab官方地址
- 创建一个新的仓库
- 填写相关信息
创建完成
配置ssh密钥
- 点击add an SSH key
- 在本地电脑当中添加生成密钥
命令:ssh-keygen -t rsa --在客户端上生成一对密钥,-t 指定加密类型
在电脑C盘用户当中查看生成的密钥:
- 把id_rsq.pub的内容复制到gitlab当中
- clone远程的仓库到本地当中
- 本地文件push到远程仓库
gitHub操作 和gitLab大同小异
开发工具中git使用
- 从gitHub上Clone代码
- 在IEDA里配置git执行程序的路径:选择 【File】→ 【Settings】→ 【Vwesion Control】→ 【Git】
- 在远程git服务器上创建仓库
- 打开IDEA,选择菜单上的 VCS(版本控制工具),选择【Checkout from Version Control】→【Git】
然后将上边复制的 git仓库地址粘贴到URL中,选择一个本地一个空的目录作为工作区
提交文件
- 添加文件到暂存区
在每创建一个文件的时候, 都会提示添加到暂存区
如果没有添加到暂存区当中, 也可以手动添加
- 提交到本地仓库
完成代码的开发后,需要将修改和添加的代码或文件提交到本地仓库上(文件已添加至暂存区,受git追踪)
选择【VCS】→ 【Commit】
- 推送到远程仓库
把代码推送到远程服务器上,点击项目右键,【Git】→【 Repositry 】→【Push】
分支开发
假如,现在项目开发完成,需发布1.0版本,然后添加一个1.0的分支
- 创建分支
- 打开git分支的面板,点击【New Branch】
切换回主分支
合并分支
把主分支(master分支)与1.0分支进行合并
冲突解决
- 在newbranch分支上c.txt编写代码并提交
- 在master分支上c.txt编写代码并提交
日志查看
版本查看
版本回退
当你误删了一段代码(方法),但又提交了,可以使用下面的操作来进行回退 打开文件的历史提交记录
对比不同版本
- 对单个代码文件的比较,点击文件,右键弹出的菜单选项 → 【Git 】→ 【compare with...】
- Compare with the Same Repository Version 当前文件与服务器同一分支上该文件版本的内容进行比较
- Compare with 当前文件与文件各次提交的版本做比较
- Compare with Branch 当前文件与其他分支上该文件版本进行比较
GitworkFlow
workFlow
概念:
- WorkFlow 的字面意思,工作流,即工作流程
- 项目开发中,多人协作,分支很多,虽然各自在分支上互不干扰,但是我们总归需要把分支合并到一起
- 而且真实项目中涉及到很多问题,例如版本迭代,版本发布,bug 修复等
- 为了更好的管理代码,需要制定一个工作流程,这就是我们说的工作流,分支管理策略
- 工作流不涉及任何命令,因为它就是一个规则,完全由开发者自定义,并且自遵守
常用工作流形式:
- Git Flow:Git Flow 出现的最早
- GitHub Flow:GitHub Flow 在 Git Flow 的基础上,做了一些优化,适用于持续版本的发布
- GitLab Flow:GitLab Flow 出现的时间比较晚,所以综合前面两种工作流的优点,制定而成的一个工作流
Git Flow:
特点:采用 Git Flow 工作流的项目中,代码的中央仓库会一直存在以下两个长期分支
主要分支:
- master:分支上的最新代码永远是版本发布状态
- develop:分支则是最新的开发进度
协助分支:
Feature Branch:
- Feature 分支用来做分模块功能开发
- 模块完成之后,会合并到 develop 分支,然后删除自己。
Release Branch:
- Release 分支用来做版本发布的预发布分支,建议命名为 release-xxx
例如:
在软件 1.0.0 版本的功能全部开发完成,提交测试之后,从 develop 检出release-1.0.0
测试中出现的小问题,在 release 分支进行修改提交,测试完毕准备发布的时候,代码会合并到 >master 和 develop,master 分支合并后会打上对应版本标签 v1.0.0, 合并后删除自己Hotfix Branch:
- Hotfix 分支是用来做线上的紧急 bug 修复的分支,建议命名为 hotfix-xxx
- 当线上某个版本出现了问题,将检出对应版本的代码,创建 Hotfix 分支,问题修复后,合并回 master 和 develop ,然后删除自己
Git Flow 示意图:
- master 和 develop 字体被加粗代表主要分支
- master 分支每合并一个分支,无论是 hotfix 还是 release ,都会打一个版本标签
- feature 分支从 develop 开始,最终合并回 develop
- hoxfixes 从 master 检出创建,最后合并回 develop 和 master
GitHub Flow :
概述:
- 是大型程序员交友社区 GitHub 制定并使用的工作流模型
- 因为 Git Flow 对于大部分开发人员和团队来说,稍微有些复杂,而且没有 GUI 图形页面,只能命令行操作, 所以为了更好的解决这些问题,GitHub Flow 应运而生了
特点:
- GitHub Flow 推荐做法是只有一个主分支 master
- 团队成员们的分支代码通过 pull Request 来合并到 master 上
模型说明:
- 只有一个长期分支 master ,而且 master 分支上的代码,永远是可发布状态,一般 master 会设置 protected 分支保护
- 只有有权限的人才能推送代码到 master 分支
- 如果有新功能开发,可以从 master 分支上检出新分支
- 在本地分支提交代码,并且保证按时向远程仓库推送
- 当你需要反馈或者帮助,或者你想合并分支时,可以发起一个 pull request。
- 当 review 或者讨论通过后,代码会合并到目标分支
- 一旦合并到 master 分支,应该立即发布
合并请求特点:
- 可以很好控制分支合并权限
- 分支不是你想合并就合并,需要对方同意
- 代码 Review
issue tracking 问题追踪
开发中,会用到很多第三方库,然后使用过程中,出现了问题,是不是第一个反应是去这个第三方库的 GitHub 仓库去搜索一下 issue
,看没有人遇到过,项目维护者修复了没有,一般未解决的 issue 是 open 状态,已解决的会被标记为 closed。这就是 issue
tracking
GitLab Flow
概述:
GitLab 既支持 Git Flow 的分支策略,也有 GitHub Flow 的 Pull Request( Merge Request
) 和 issue tracking
存在问题:
- 版本的延迟发布(例如 iOS 应用审核到通过中间,可能也要在 master 上推送代码)
- 不同环境的部署 (例如:测试环境,预发环境,正式环境)
- 不同版本发布与修复 (只有一个 master 分支真的不够用)
- GitLab 推荐用生产分支来解决上述问题
- 对于"持续发布"的项目,它建议在master分支以外,再建立不同的环境分支
上游优先原则:
什么是上游优先:
- Gitlab flow 的最大原则叫做"上游优先"(upsteam first)
- 即只存在一个主分支master,它是所有其他分支的"上游"。只有上游分支采纳的代码变化,才能应用到其他分支。
举例:
- "开发环境"的分支是master,"预发环境"的分支是pre-production,"生产环境"的分支是production。
- 开发分支是预发分支的"上游",预发分支又是生产分支的"上游"。代码的变化,必须由"上游"向"下游"发展。production。
- 比如,生产环境出现了bug,这时就要新建一个功能分支,先把它合并到master,
- 确认没有问题,再提交到pre-production,这一步也没有问题,才进入production
版本发布:
- 对于"版本发布"的项目,建议的做法是每一个稳定版本,都要从master分支拉出一个分支
- 比如2-3-stable、2-4-stable等等。
- 以后,只有修补bug,才允许将代码合并到这些分支
- 并且此时要更新小版本号
合并请求
创建团队:
填写信息
邀请成员
分支权限与合并请求
在指定项目上创建分支:
默认主分支是受保护的
当一个分支是一个受保护的分支时,必须要发起合并请求后操作
设置分支权限
设置保存分支入口
展开分支保存按钮
忽略文件
在项目开发中,我们使用git托管项目时往往会忽略一些不必要的文件或文件夹
步骤:在版本库根目录创建.gitignore,修改文件,添加忽略正则
规则:
?:代表任意的一个字符
*:代表任意数目的字符 {!ab}:必须不是此类型 {ab,bb,cx}:代表ab,bb,cx中任一类型即可
[abc]:代表a,b,c中任一字符即可
[ ^abc]:代表必须不是a,b,c中任一字符
示例:
注意事项:
- 添加忽略之后,已经提交到版本库中的文件是无法忽略的,只能clone到本地,删除后,再进行忽略
- gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。