目录
在现实中,当我们完成一个文档的初稿后,后面可能还需要对初稿进行反复修改,从而形成不同版本的文档。显然,经过反复修改,当我们发现前面某个版本的文档才是最符合预期的时候,如果我们是直接在原稿的基础上不停修改,我们是很难直接得到那个最符合预期的版本的,因此我们的做法是:每次修改得到一个新版本后,我们就将该版本保存下来,下次如果需要修改,先将该版本备份再修改。但这样又出现了另一个问题:如果版本很多,维护起来就十分困难,例如很难知道每一个版本做出了什么变化,为了解决这些问题,于是人们开发出了一系列的名为版本控制器的软件,它们可以很好地管理文档的每次修改以及版本的迭代,方便我们快速溯源某个特定的版本,而Git就是目前最主流的版本控制器,它可以管理维护所有格式的文件,对于开发者来说,它最主要用于管理维护项目中的各种代码源文件(它会清楚地记录文本文件的哪一行新增修改了什么内容,对于二进制文件如图片视频它也会记录它们大小的变化)。
Linux下Git安装
①查看是否已经安装Git
cpp
git --version
②查看当前的Linux发行版本
cpp
cat /etc/os-release
③Centos下Git安装与卸载
cpp
sudo yum intstall git -y //安装
sudo yum remove git -y //卸载
④Ubuntu下Git安装与卸载
cpp
sudo apt-get intstall git -y //安装
sudo apt-get remove git -y //卸载
Git基本指令
1.创建本地仓库
cpp
git init
该指令用于在当前目录下的创建一个git仓库,只有在git仓库中的文件才可以被追踪管理,创建成功之后会在当前目录下生成一个隐藏的.git文件,该文件Git用于对仓库进行管理的,我们不要随意更改它,否则会破环仓库。
2.为当前仓库配置用户的名称和邮箱
cpp
git config [--global] user.name "用户名"
git config [--global] user.email "用户邮箱"
后续仓库的管理可能需要用户的名称、邮箱,如果不进行配置可能会出错,其中 --global 是可选项。我们的配置文件分为全局的配置文件(~/.gitconfig)和本地的配置文件(.git/config),仓库管理时优先使用本地的配置文件的配置信息,如果找不到本地配置文件的配置信息,就会到全局配置文件中寻找需要的配置信息,如果也找不到就会出错或者要求用户提供相关信息。加上 --global 选项就是对全局配置文件的信息进行配置,否则就只是对当前仓库的本地配置文件进行配置。
除了全局配置外,还有系统配置文件(/etc/gitconfig),它的优先级是最低的,使用时加上 --system 选项即可,可能需要sudo 提权。总结就是:本地配置仅适用于当前仓库,优先级最高。全局配置适用于当前用户的所有 Git 仓库,优先级次于本地配置。系统配置适用于整个系统的所有用户和所有仓库,优先级最低。
3.查看配置是否生效
cpp
git config -l //查看所有配置
git config --local --list //查看本地配置
git config --global --list //查看全局配置
git config --system --list //查看系统配置
git config -l 命令会列出所有配置项,包括系统级、全局级和本地级的配置,它会按优先级顺序列出所有配置项,不会区分来源(系统、全局或本地),例如本地和全局都配置了用户名信息,优先输出优先级更高的本地的用户名配置信息。
4.重置配置
如果用户的配置信息出错了,可以重置配置信息
cpp
git config [--global] --unset user.name //删除配置的用户名
git config [--global] --unset user.email //删除配置的用户邮箱
加上 --global 选项删除的是全局配置文件的位置信息。
我们前面 git init 的目录不是所谓的git仓库,它仅仅只是一个工作区,真正的git仓库是 .git 目录,也被称为版本库(版本库虽然在工作区所在目录下,但它不属于工作区),只有将工作区的文档添加到版本库中才可以对版本进行管理(注意我们不能直接将文档添加到版本库中,我们只需要将文档放入工作区,再使用add指令将其加入版本库即可)
在版本库中还存在一个git对象库,每一次我们修改工作区文档进行一次add之后,就会生成一个Blob 对象(如果有多个文件发生了修改,就会生成多个Blob 对象),它记录了本次的修改,由git对象库管理这些对象,于此同时我们的暂存区也会新增一个指针指向新增的Blob 对象。如果我们又进行commit操作,就会将暂存区的索引加入到分支当中并清除暂存区内容,并生成Tree 对象和Commit 对象(Tree 对象存储目录结构和文件引用。Commit 对象存储提交信息和树引用),此时工作区的文档就真正地提交到了本地仓库中,形成了一个新版本,可以进行版本管理了(通过HEAD指针就可以找到一个个版本,我们打开.git文件看到的index、objects、HEAD、refs/heads/master文件就分别对应暂存区、git对象库、HEAD指针、分支),HEAD指针指向最新一次commit的commit对象ID。
5.将工作区文件添加到暂存区中
cpp
git add "xxx" //将xxx文件添加到暂存区中
git add . //将工作区下所有文件添加到暂存区中
暂存区的意义是允许我们在提交之前对更改进行组织和选择,确保只提交我们需要的更改
6.将暂存区内容提交到本地仓库
cpp
git commit -m "本次提交细节"
每次 git commit 创建一个版本
7.查看当前仓库的提交日志
cpp
git log [--oneline] [--graph]
--oneline:以单行格式显示每个提交,便于快速浏览。
--graph:以图形化的方式显示提交历史,包括分支和合并。
按 q 退出日志浏览
所有对象(Blob、Tree、Commit)都存储在 .git/objects 目录下,git 对象 ID 的前两位是子目录名,剩余部分是文件名。在 git log 时日志中我们会看到一串串的长字符串,这就是 Commit 对象的ID(路径).
我们可以通过git对象ID查看对应 git 对象的信息:
cpp
git cat-file -p "git对象ID"
如果该git对象ID是指向 Blob 对象:我们可以查看到对应文件的修改信息
如果该git对象ID是指向 Commit 对象:我们可以查看到 commit 时的提交细节
如果该git对象ID是指向 Tree 对象:我们可以查看到 commit 时所有add操作生成的Blob 对象ID及对应文件名
8.查看工作区和暂存区状态
cpp
git status
可以查看到哪些文件被修改、哪些文件被暂存(添加到暂存区)以及哪些文件未被版本控制,一般会显示以下内容
常用输出信息:
- On branch [branch_name]:显示当前所在的分支。
- Changes not staged for commit:显示工作区已修改但尚未暂存的文件。
- Changes to be committed:显示已暂存的文件。
- Untracked files:显示未被 Git 跟踪的文件。
9.比较文件差异
可以比较工作目录与暂存区之间的差异、暂存区与最新提交之间的差异,或者两个特定提交之间的差异。
cpp
git diff [file] 命令⽤来显⽰暂存区和⼯作区⽂件的差异
git diff HEAD -- [file] 命令来查看版本库和⼯作区⽂件的区别。
10.版本回退
cpp
git reset [--soft | --mixed | --hard] [HEAD]
- --soft 参数只是将版本库回退到某个指定版本,对于工作区和暂存区的内容都不变。
- --mixed 为默认选项,该参数将版本库和暂存区的内容退回为指定版本,工作区文件内容保持不变。
- --hard 参数将版本库、暂存区与工作区都退回到指定版本。切记工作区有未提交的代码时不要用这个选项,因为一旦工作区会回滚,我们没有提交的代码就再也找不回了,所以这个选项要慎用。
HEAD 说明:
-
①使用^表示
-
- HEAD 表当前版本
-
- HEAD^ 上⼀个版本
-
- HEAD^^ 上上⼀个版本
-
- 以此类推...
-
②使用 ~ 数字表示:
-
- HEAD~0 表示当前版本
-
- HEAD~1 上⼀个版本
-
- HEAD^2 上上⼀个版本
-
- 以此类推...
当然我们也可以直接使用commit对象的ID来替代HEAD,理论上只要我们得到了commit对象的ID,我们就可以返回到该版本上(意味着我们在退回以前的版本后,又可以退回来特定的版本),如果我们不知道某个版本的commit对象ID,可以使用以下指令查到:
cpp
git reflog
但这种办法不是万能的,当版本过多时以前版本的commit对象ID该指令未必可以查到,因此还是要慎用 --hard选项。
Git 的提交历史是一个有向无环图(DAG),每个提交都有一个唯一的 commit ID,我们的版本回退只是将HEAD指针指向commit对象ID对应的顶点而已(例如如果我们从版本10回退到版本3,又提交新增到版本4,我们还可以通过commit ID回退到版本7(版本3顶点有2条出边,即两条分支,一条指向原来的版本4即maser主分支,一条指向现在的版本4但该分支无名字是孤立的分支,而HEAD指针就指向该孤立分支末尾,如果不回退,我们后面新增的版本都会添加到新增的版本4后面,但我们一旦切回master主分支,HEAD指针就会重新指向master主分支最新版本即版本10,由于新增分支是孤立分支没有名字,我们很难让HEAD指针再次切换回新增的版本4,尽管可以通过拿到新增版本4的Commit ID回退,但当版本很多时这种办法不实用))。
11.命令简化
一些命令的可能会比较长使用起来不方便,我们可以对命令起别名以提高效率
cpp
git config --global alias.last 'log -1'
//将命令git log -1简化成 git last
建议初学时不要进行命令简化。
分支管理
我们前面的每一次提交都会被都会像一条时间线一样被串起来,这条分支就是master分支,即主分支,我们还可以基于某个提交点创建其它分支,让分支完成特定任务之后再合并会主分支。
1.查看当前所有分支
cpp
git branch //显示所有本地分支
git branch -a //查看所有分支包括本地分支和远程分支
带 * 的分支就是 HEAD 指向的分支
2.创建分支
cpp
git branch dev //新建分⽀dev
在当前分支( HEAD 指向的分支,通常是 master 或其他分支)的最新提交点上创建一个新的分支 dev,初始时新建分支的工作区、暂存区和版本区与当前分支的最新提交状态是完全一致的,如果当前分支的工作区有未提交的内容分支也会复刻,这样容易导致后面合并时出现问题,因此在分支时应该保证工作区、暂存区是干净的。
如果需要可以使用 git stash 命令临时保存当前工作目录中的更改(包括已修改但未提交的文件、已暂存的文件等),同时将这些更改从工作目录中移除,使工作目录恢复到一个干净的状态(与最近一次提交的状态一致)。这在需要切换分支、解决紧急问题或执行其他需要干净工作目录的操作时非常有用,如果没有添加到暂存区文件是无法保存的。
3.切换分支
cpp
git checkout dev//切换到分支dev上
git checkout -b dev //创建并切换到dev分支
我们在某个分支的修改是不影响其它分支的,例如我们在dev分支上进行了修改,当切回master主分支时工作区、暂存区和版本区就会更新为master分支的最新状态(工作区和暂存区未提交的内容在切换分支后仍然会保留)。
4.合并分支
存在两种模式的合并:
- ①快进合并(Fast-Forward)
cpp
git merge [--ff] dev //将dev分支合并到当前分支
只有在创建分支 dev 之后,当前分支没有任何新的提交,才可以进行快进合并,其实就是将 master 和 HEAD 指针指向 dev 的最新提交点,所以合并速度非常快。

在进行快进合并时当前分支的工作区和暂存区不应有未提交的内容,应该保持和创建dev分支时一致,否则可能快速合并失败。
快进合并是默认的合并模式,因此 --ff 选项可以省略
- ②非快进合并(No Fast-Forward)
会强制创建一个合并提交
cpp
git merge --no-ff -m "提交细节" dev将dev分支合并到当前分支并进行一次提交
如果合并时发生了冲突,就必须采用 No Fast-Forward 的方式合并,合并时产生冲突可能是以下原因:
- 如果两个分支对文件的同一行或相邻行进行了修改,Git 无法自动决定保留哪个版本,此时会标记为冲突(如果两个分支修改的是文件的不同部分,Git 可以自动合并,不会冲突。如果一个分支修改了文件,而另一个分支没有修改,合并时也不会冲突)
- 如果一个分支删除了文件,而另一个分支修改了该文件,合并时也会冲突
当合并发生冲突时,Git会标记发生冲突的内容,类似于下面这样:
cpp
<<<<<<< HEAD
当前分支冲突内容
=======
分支的冲突内容
>>>>>>> dev
我们只能手动调整发生冲突的内容来解决冲突,解决完冲突之后重新进行提交操作形成一个新的提交点之后在进行非快进合并操作。

快进模式模式合并时速度虽然快,但在未来溯源时我们不知道合并的点有没有分支的参与,而非快进模式就很好的记录了合并的点有哪几个分支的参与,因此如果分支是由不同的人员完成的,这里推荐使用非快进模式进行合并一方便未来溯源。
5.删除分支
cpp
git branch -d dev //删除分支dev
git branch -D dev //强制删除分支dev
分支在合并后就可以删除了避免资源占用,分支的提交记录会永久保留在主分支中,即使分支被删除,其所有更改仍可通过主分支的提交历史追溯。
在当前分支上只能删除另一个分支,不能在当前分支上删除当前分支,如果某个分支没有进行合并操作,只能使用强制删除。
因为创建、合并和删除分支非常快,所以Git鼓励我们先使用分支完成某个任务,合并后再删掉分支,这和直接在master分支上工作的效果是一样的,但过程更安全。
在实际开发过程中,要求master分支上的代码是稳定可靠的,因为已经开发的产品会直接依赖于master分支上的代码,如果我们想要添加新的功能,就只能从maser上拉取一个分支,在分支上完成新功能的开发,经过测试确保稳定可靠后再合并到master分支上,从而确保master分支上的代码是稳定可靠的。
如果master分支的代码出现了问题,而现在的分支 dev1 是基于存在问题的代码开发的,此时我们需要新开一个分支 dev2 解决master 分支上的问题,解决完后将dev2 合并到master分支中,再将master合并到dev1 上进行冲突解决,最后将dev1 合并到master分支上。
远程仓库与本地仓库
我们前面所讲的都是本地仓库,如果想要实现多人协作,仅仅只有一个本地仓库是不行的,因此每个成员的电脑上都有一个自己的本地仓库,成员基于自己的本地仓库完成开发后将最新提交推送到其它成员的电脑上,这样所有人都可以看到其他成员的修改,但这种方法管理麻烦安全性不高,因此我们使用一个中央服务器管理所有代码,当要开发新功能时成员从中央服务器拉取代码进行开发,开发完成确定没有问题之后再推送到中央服务器,这样就能保证中央服务器的代码就是稳定可靠的代码,其他成员也可以通过中央服务器的最新提交看到其他成员的修改。
像上面所说的中央服务器我们完全可以自己搭建,不过也有现成的网站可以供我们直接使用,GitHub 就是用于提供 Git 仓库托管服务的,只要注册⼀个GitHub账号,就可以免费获得 Git 远程仓库,由于 GitHub 是国外的网站,速度比较慢,我们一般使用 码云
一般一个仓库管理一个项目系统,码云的一般操作有:仓库创建、设置仓库介绍文档(README)、仓库成员管理及其身份设定、仓库代码问题反馈及处理、分支合并(要申请)
1.将远程仓库克隆到本地
cpp
git clone [仓库克隆地址]
执行该命令就可以将远程仓库克隆到本地当前工作目录下,这时的仓库与我们前面所说的本地仓库没有任何区别,需要注意当前工作目录不能在本地仓库里面。
仓库克隆地址\] 我们一般用 https 或 ssh 类型的地址,如果使用 https ,克隆时没有要求,可以直接克隆下来。而 ssh 协议使用了公钥加密和公钥登陆机制,体现了其使用性和安全性,如果使用 ssh 类型的地址,我们需要确保我们已经将自己的公钥提交给码云(每一个成员都有自己的公钥),我们可以在 设置 - -\> ssh 公钥 中查看自己的公钥是否已经交给码云,如果没有配置公钥,我们就在用户的根目录下找到 .ssh 目录看看里面有没有id_rsa 和 id_rsa.pub 这两个文件,id_rsa 里面存放的是私钥,不能暴露,id_rsa.pub 里面存放的是公钥直接将里面的内容配置到码云上即可,如果这两个文件不存在,就执行以下命令创建这两个文件: ```cpp ssh-keygen -t rsa -C "邮箱" ``` 邮箱必须和码云上的邮箱保持一致,之后一直按回车即可,配置公钥到码云之后就可以使用 ssh 类型的地址克隆远程仓库到本地了。 在将远程仓库克隆到本地之后需要对仓库的用户名和邮箱进行配置(保持和码云的一致,用户名是码云主页2@后面的字符) 在成功将远程仓库克隆到本地之后, Git 本地会为远程仓库设置一个远程引用名称,默认是 origin,我们可以通过以下指令查看: ```cpp git remote //查看远程仓库引用名称 git remote [newName] //修改远程仓库引用名称,不会影响远程仓库的名称 git remote -v //查看一些更详细信息,fetch表示拉取权限,push表示推送权限 ``` 2.将本地修改推送到远程仓库 ```cpp git push [远程仓库引用名称] [要推送的本地分支] : [远程目的分支] git push [远程仓库引用名称] [要推送的本地分支] //[要推送的本地分支] 和 [远程目的分支]一致时可以省略成这样 ``` 如果我们有权限且仓库无特殊限制,可以直接推送。如果仓库有分支保护或团队要求代码审查,可能需要通过 PR 或管理员审批 3.配置 .gitignore 文件 在将本地修改推送到远程仓库时,我们可能希望某些文件(如保存了数据库密码的配置文件)不被推送到远端,这时我们只需要将该文件名添加到 .gitignore 文件中就可以了,.gitignore 文件在创建远程仓库时如果勾选了该选项会自动生成,如果没有勾选也可以直接在本地仓库中创建该文件。加入 .gitignore 文件的文件名不会被Git追踪管理,我们我们想忽略某一类文件,可以在.gitignore 文件中使用\*:如 \*.so表示忽略所有以 .so结尾的文件,如果我们不想忽略a.so文件,只要在.gitignore 文件里加上 !a.so 即可,也可以在在add时这样写:git add -f a.so。如果我们想查看a.so文件是否已经在.gitignore 文件中及其忽略原因,可以执行指令: git check-ignore -v a.so 4.将远程仓库代码拉取到本地 当远程仓库代码比本地仓库代码新时,我们就需要将远程仓库代码拉取到本地 ```cpp git push [远程仓库引用名称] [远程分支] : [本地分支] git push [远程仓库引用名称] [远程分支] //[远程分支] : [本地分支]一致时可以省略成这样 ``` 拉取下来的代码会自动进行分支合并 ## 标签管理 针对某一次的提交,如果我们直接使用Commit Id不仅使用麻烦而且难以辨识,Git允许我们对某一次的提交打上标签,可以理解为Commit Id起别名。 1.创建标签 ```cpp git tag [tagName] [CommitID] git -a tag [tagName] -m ["标签说明"] [CommitID] ``` 如果省略 \[CommitID\] 则默认是为当前分支的最新提交打标签 2.查看标签 ```cpp git tag //查看所有标签 git show [tagName] //查看标签 tagName 的详细信息 ``` 3.删除标签 ```cpp git tag -d [tagName] ``` 4.将本地标签推送到远端 ```cpp git push [远端仓库引用名称] [tagName] //将标签tagName推送到远端仓库 git push [远端仓库引用名称] --tag //将所有标签推送到远端仓库 ``` 5.删除远端标签 想要删除远端标签需要先将本地标签删除,再将修改推送到远端。 ```cpp git tag -d [tagName] //删除本地标签 git push [远端仓库引用名称] : refs/tags/[tagName] //将本地修改推送到远端 ``` ## 多人协作 想要进行代码开发我们就必须获得开发者身份和对应权限,假设此时我们已经将远程仓库克隆到本地。 ### 同一分支下 如果有两个人想在同一远程分支下协作完成完成同一个文件,其协作过程如下: 1.创建远程分支 方法①:直接在远程创建分支,再通过 `git pull` 指令将远程分支拉取到本地 方法②:先 `git pull` 确保本地是最新提交,再在本地创建分支,最后将本地分支推送到远端 ```cpp git checkout -b dev //创建并切换到新分支 dev ...//创建添加开发所需要的文件 git add . git commit -m "xxx" git push -u [远程仓库别名] dev //推送 dev 分支到远程仓库 ``` -u 参数会将本地分支与远程分支关联,之后可以直接使用 git push 和 git pull 操作,无需重复指定分支名,即建立联系后默认是在两个分支上进行交互,一些指令就不需要再指明分支从而简化指令。 2.将远程分支拉取到本地 其中一人创建好远程分支后,其他人直接 `git pull` 拉取远程分支到自己本地即可 3.建立远程分支和本地分支的联系 这一步不是必要的 ```cpp git checkout -b [本地分支] [远程分支] ``` 可以通过以下指令查看远程和本地分支连接是否建立 ```cpp git branch -vv ``` 4.进行代码推送 如果两个人都对同一个文件进行了修改,后一个推送时可能会因合并冲突而推送失败,只能先将远程最新提交拉取到本地进行冲突解决之后再推送到远端分支 5.分支合并 开发完成之后就可以将远程分支 dev 合并到master分支 法一:先拉取远端master最新提交,在本地上将分支合并到本地master分支(有冲突应该在分支上解决),再将本地master分支合并到远端 法二:通过PR提交合并申请,审查人员可以直接查到文件进行了哪些修改,这种保障了远程master分支的稳定性和安全性 6.删除远程分支 可以直接在远程将已经合并的分支删除,有时候尽管远程分支已经删除,但我们在本地查看时依旧可能查看到那些已经删除的远程分支,我们可以通过以下指令查看remote地址,远程分支,还有本地分支与之相对应关系等信息 ```cpp git remote show [远程仓库引用名称] ``` 通过以下指令就可以删除远程仓库不存在的本地分支 ```cpp git remote prune [远程仓库引用名称] ``` ### 不同分支下 在实际中一般一个功能或者需求点一个分支,在开发完成之后再将各个分支合并到master分支上。 1.创建远程远程分支 为每一个功能或者需求创建一个分支 2.将远程分支拉取到本地 3.建立远程分支和本地分支的联系 4.进行代码推送 由于分支之间是互相独立的,因此分支各自的代码提交是互不影响的 5.分支合并 由于我们是基于master的某个提交点创建分支进行开发的,因此再分支合并时需要先将远程的maser的最新提交点拉取到本地,将本地master合并到本地分支上,如果有冲突就解决冲突,没有冲突之后再将该本地分支合并到本地master分支上,最后将本地master分支合并到远程master分支。 6.删除远程分支 ## 企业级开发模型 -- git flow 模型 一个软件从零开始到最终交付,大概包括以下几个阶段:规划、编码、构建、测试、发布、部署和维护。 规划阶段:明确软件的目标、范围和可行性,进行文档设计 编码阶段:根据设计文档将需求转化为可执行的代码。 构建阶段:将代码编译、打包为可部署的软件。 测试阶段:对代码进行测试以确保软件质量,发现并修复缺陷。 发布阶段:将代码打包为可部署的版本进行代码交付。 部署阶段:将代码安装到生产服务器,配置依赖并启动服务 维护阶段:持续优化软件,解决用户反馈的问题。  而系统在开发过程中主要包含以下环境: * 开发环境:开发环境是开发工程师们专门用于日常开发的服务器,为了开发调试方便,⼀般打开全部错误报告和测试工具,是最基础的环境。 * 测试环境:该环境主要用于对开发的代码进行错误测试,该环境是开发环境到生产环境的过渡环境。 * 预发布环境:该环境是为避免因测试环境和生产环境的差异等带来的缺陷漏测而设立的⼀套环境,其配置等基本和⽣产环境⼀致,目的是能让我们发布到正式环境时更有把握!要注意预发布环境服务器不在线上集成服务器范围之内,是单独的⼀些机器。 * 生产环境:正式提供对外服务的线上环境,用户可以进行访问获取服务。在发布到生产环境之前,一些企业可能还会灰度环境(灰度环境),有人群灰度、地域灰度、年龄灰度等等。 一般一个环境对应一套独立的服务器以进行环境隔离,从而确保系统安全。 一个软件的迭代,在我们看来就是对代码进行迭代,那么就需要对代码进行管理,而 Git 就是常用的代码管理的工具,我们可以针对不同的环境设计不同的分支: * develop 分支(开发分支):该分支管理已经开发完成的代码,用于部署到开发环境中进行新需求开发,它是是基于 master 分支创建的,始终保持最新完成以及 bug 修复后的代码,不可以删除该分支。 * master分支(主分支):该分支上的代码用于部署到正式发布环境,即用户访问服务时用的就是该分支上的代码的,该分支一般由合并 release 分支得到,任何情况下都不允许直接在 master 分支上修改代码,该分支也不可删除 * feature 分支(需求开发分支):feature 分支用于开发某个特定的新功能,以 develop 分支为基础创建。新特性开发完成后,开发人员就将其合并到 develop 分支,⼀旦该需求发布上线,便将其删除,由于可能有多个新功能正在同时开发,因此建议该分支命名为: feature/user_createtime_feature 。 * release 分支(预发布分支):release 分支主要用于给测试人员进行功能测试,基于 develop 分支创建。如果在 release 分支测试出问题,需要回归验证 develop 分支是否存在此问题,同时该 release 分支属于临时分支,产品上线后可以删除,建议命名为: release/version_publishtime 。 * hotfix 分支(紧急修复分支):hotfix 分支用于紧急修复 master 分支上的Bug,一般是基于 master 分支创建。当问题修复完成后,需要合并到 master 分支和 develop 分支,之后就可以删除,建议命名为:hotfix/user_createtime_hotfix  当新需要出现时 ①开发人与基于 develop 分支创建 feature 分支,开发完成之后就将 feature 分支合并到 develop 分支,此时可以删除 feature 分支 ②此时测试人员就可以基于 develop 分支创建 release 分支进行代码测试,如果测试发现代码存在问题,则开发人员就需要基于 release 分支创建 hotfix 分支进行代码修复,修复后将 hotfix 分支合并到 release 分支并删除 hotfix 分支,测试人员再次基于 develop 分支创建 release 分支进行代码测试直至代码通过,之后需要将修复后的 release 分支合并到 develop 分支。 ③运维人员将 release 分支上的代码部署到预发布环境中进行仿真测试,如果出现问题开发人员就要继续基于 release 分支创建 hotfix 分支进行代码修复,修复后将 hotfix 分支合并到 release 分支并删除 hotfix 分支,测试人员测试没有问题之后继续进行仿真测试直至代码通过,最后将代码合并到 develop 分支 ④此时就可以将 release 分支合并到 master 分支,此时可以进行灰度测试,让一部分人先使用最新版本,其他人依旧使用旧版本。如果新版本出现问题开发人员就要基于 release 分支创建 hotfix 分支进行代码修复,修复后将 hotfix 分支合并到 release 分支并删除 hotfix 分支,测试人员测试没有问题之后继续进行仿真测试直至代码通过,最后将代码合并到 develop 分支,直至新版本在所有用户上都可以稳定运行,此时就可以将 release 分支删除。 ⑤如果 master 分支上的代码出现了问题,开发人员就需要基于 master 分支创建 hotfix 分支进行代码修复,测试人员直接基于 hotfix 分支测试没有问题之后就进行仿真测试,经过测试没有问题后就合并到 master 分支和 develop 分支,此时可以根据根据修复的风险、影响范围决定是否进行灰度测试,没有问题之后就可以删除该 hotfix 分支。 前面所说的模型就是 git flow 模型,不同企业选择的开发模型不同,开发流程也就不同。 在实际开发中我们一般用 [码云企业版](https://gitee.com/enterprises),它的基本使用与码云差不多,可以自行摸索它的使用,需要注意在一个项目下面可以创建多个仓库以管理项目的各个子系统,同时我们需要先添加成企业成员,才可以添加为项目内部的成员