1.初识Git
2.Linux系统ubuntu平台为例安装git
指令:sudo apt-get remove 软件 -y(sudo是因为得是root权限),卸载软件
指令:sudo apt-get install 软件 -y,安装软件
指令:sudo apt-get install git -y,安装git
指令:git --version,查看版本
3.创建Git本地仓库
仓库是进行版本控制的一个文件目录,如果文件需要git管理,就必须把文件放在git本地仓库中,只有git仓库下的文件才能被git管理。
指令:git init,将所在的目录下初始化Git仓库,创建一个隐藏目录.git,.git是用来追踪管理仓库的
4.为本地仓库新增两个配置项--name,email
当安装
指令:git config,为仓库添加配置项
指令:git config user.name "名字",配置用户名称
指令:git config user.email "Email地址",配置email地址
指令:git config -l,查看本地仓库的配置项
指令:git config --unset user.name/user.email,删除配置项
选项:--global(全局):
在一台服务器上,可以创建多个git本地仓库,--global选项添加的配置项在当前服务器上的所有git本地仓库都生效;
删除--global添加的配置,删除时也需要--global选项。
5.认识工作区、暂存区、版本库
工作区是指用来进行开发和编辑的文件和目录的集合
git本地仓库是指存储在本地计算机上的一个完整Git版本库。它由项目的工作区和一个隐藏的 .git
目录组成(.git不属于工作区)。
版本库(仓库):.git
暂存区(索引):英⽂叫stage或index。⼀般存放在 .git ⽬录下的index⽂件(.git/index)中,我们把暂存区有时也叫作索引(index)
- 左侧是工作区,右侧是版本库
- 在创建Git版本库时,Git自动创建一个唯一的master分支,以及指向master的HEAD指针
- 当工作区进行修改时,进行git add指令,暂存区目录树的文件索引会被更新
- 当执行提交操作git commit指令,master分支会更新,可以理解为暂存区的目录树才会被真正写到版本库中
将工作区的文件添加到仓库中进行管理:
-
使用add操作,将修改内容(新增、修改、删除)添加到暂存区
-
使用commit操作,将暂存区的内容提交到master分支中,这才真正地添加到仓库中进行管理
版本库中还维护着一个模块--对象库(objects),内部存着多个git对象,使用add操作时,修改的工作区内容会写入对象库的一个新的git对象中,从而来维护文件的版本进行版本管理。
版本库中的暂存区(index),内部存着git对象的索引。
commit操作:将暂存区这颗树,写入master分支下,所以master是一颗目录树,存着git对象的索引。
指令:git add 文件 / . ,将文件/当前目录下所有内容的修改添加到暂存区
指令:git commit -m "提交细节" , -m选项是必带的,提交细节要好好描述,记录本次提交细节,是给我们人看的指令:git log,显示按时间从近到远的提交记录,显示id(用于定位每次提交)、提交用户及邮箱、日期、提交细节。(选项参数:--pretty=oneline,显示一行 )
通过上述操作,.git目录的改变:
- index就是暂存区,add操作就是存在index中的
- HEAD是指针,指向master,通过打印master可以发现master存放着最新一次commit的id
- id是一个索引,对应一个git对象,git对象被维护在对象库(objects)中,通过id可以查看修改的内容(id的前两位是文件夹名称,后38位是文件名称 )
- object为Git的对象库,里面包含了创建的各种版本库对象及内容;当执行git add指令时,暂存区的目录树被更新,同时工作区的修改的内容被写入对象库中的一个新的对象中,就位于“.git/objects”目录下
- 指令:git cat-file -p id,通过id查看git对象内容(该类文件经过安全哈希算法sha加密过,需要通过指令查看)
master存放最新一次commit的id,通过该id查看内容:
查看文件树tree:
6.修改文件
修改:对文件的新增、删除、或对文件内容上的新增、修改、删除都是属于修改。 Git追踪管理的其实是修改,而不是文件。
指令:git status,查看git仓库的状态, 查看上一次commit之后,是否进行过修改、哪些文件进行修改(工作区与上一次commit的差异),不能查看文件的具体修改内容
指令:git diff 文件,查看工作区和暂存区中该文件的差异
指令:git diff HEAD 文件,查看工作区和版本库该文件的差异
7.版本回退
指令:git reset [选项] [HEAD],版本回退,回退的本质是将版本库中的内容进行回退,工作区或暂存区是否回退由指令参数决定
版本回退的原理:修改master存储的commit id
- --soft:只回退版本库
- --mixed:为默认选项,使用时可以不带该参数,该参数将暂存区和版本库回退
- --hard:工作区、暂存区、版本库都回退
- [HEAD]可以是某次的commit id,也可以是HEAD表示当前版本,HEAD^表示上一个版本,HEAD^^表示上上一个版本……HEAD~0表示当前版本,HEAD~1表示上一个版本,HEAD~2表示上上一个版本……
指令:git reflog,记录本地的每一次提交命令和回退命令
8.撤销修改
1.情况1:只撤销工作区的修改
指令:git checkout -- 文件,只撤销工作区的修改
2.情况2:撤销工作区和暂存区的修改
指令:git reset --mixed HEAD,将暂存区和版本库回退到当前版本
指令:git checkout -- 文件,撤销工作区的修改
两个操作合并起来就是对工作区和暂存区的修改进行撤销
3.情况3:撤销工作区、暂存区、版本库的修改
这一步撤销有效的前提:commit后没有push操作到远程仓库,若已经push到远程仓库了,那对工作区、暂存区、版本库进行撤销就没有意义了,因为撤销的目的就是为了不影响远程仓库的代码
指令:git reset --hard HEAD^,工作区、暂存区、版本库回退到上一个版本。
HEAD是当前版本,HEAD^是上一个版本,HEAD^^是上上版本
9.删除文件
使用rm指令对工作区的文件进行删除,再add将修改添加到暂存区,再commit提交到版本库。这就完成了工作区、暂存区、版本库的删除文件操作,一共三步。
或者可以使用git的rm: 指令:git rm 文件,将该文件从工作区和暂存区中删除 再commit操作,将版本库中将该文件删除,一共两步
10.分支管理
10.1理解分支
通过查看commit id,可以查看到上一次提交,如果查看上一次提交,就可以查看上上次的提交……这样每一次提交按时间顺序排成一条线,就是分支
10.2创建、切换、合并分支
指令:git branch,显示当前本地仓库的本地分支
HEAD不是只能指向master主分支,还可以指向其他分支,HEAD指向的分支就是当前正在工作的分支。分支前面的*表示该分支当前是工作分支。
指令:git branch 分支名称,用来创建分支
dev(新的分支)创建出来时,存放的commit的id指向最新一次的提交
指令:git checkout 分支名称,切换该分支为工作分支
指令:git checkout -b 分支名称,创建并切换该分支为工作分支
指令:git merge dev,将dev分支合并到当前工作分支
例子:将dev分支合并到master分支上,需要先将工作分支切换到master分支,再进行分支合并
10.3删除分支
指令:git branch -d 分支名称,删除分支,需要再其他分支上才能删除另一个分支
因为创建、合并和删除分支非常快,所以Git鼓励使用分支完成某个任务,合并后再删除掉分支,这和直接在master分支上工作效果是一样的,但在分支上完成过程会更安全
10.4合并冲突
dev合并到master,merge冲突,需要手动解决,并进行一次提交操作。
dev存储在dev分支上的最新commit的id,master存储手动解决后提交的commit的id。
指令:git log --graph --abbrev-commit,--graph用于分支可视化,--abbrev-commit将commit的id缩写
--graph可视化:
10.5合并模式
模式一:Fast-forward(ff)
使用git merge时,默认使用Fast-forward
缺点:dev分支合并到master分支,删除dev分支后,看不出来最新提交到底是merge进来的还是正常提交的
模式二:no-Fast-forward(no-ff)
使用指令:git merge --no-ff -m "提交细节" 分支名称
dev分支合并到master分支,删除dev分支后,可以看出来最新提交是merge进来的
10.6分支策略
10.7bug分支
新建一个分支用来处理bug,虽然可以使用dev2来debug,但dev2是用来开发的不是解决bug的。
指令:git stash,用来存储工作区的修改(使用前提:该文件必须是已经被git追踪管理过的,否则没办法使用stash将工作区的修改存储)
指令:git stash pop,恢复存在stash的内容
指令:git stash list,显示之前使用
git stash
命令保存的所有工作状态,包括更改的文件和提交信息。
新建分支-->改bug-->add、commit-->切换到master-->改bug分支合并到master-->切换到dev2开发分支-->恢复stash(开发内容)-->继续开发-->add、commit-->合并(有可能合并冲突)(手动解决bug可能会产生其他bug,所以一般不直接合并到master,而是将master合并到dev2开发分支,master还是原来那个版本,dev2可以查看合并后会出现什么问题,master此时不受影响,可以在dev2分支上解决问题,后面再将解决好问题的dev2合并到master)
10.8强制删除分支
指令:git branch -D 分支名称,强制删除分支
指令:git branch -d 分支名称,这个是该分支被merge过才能用这个直接删除
分支在没有被merge或者在该分支有一些提交时,该分支会被保护,删除需要强制删除(git branch -D 分支名称)
11.Git远程操作
分布式版本控制系统(DVCS):
Git就是一种分布式版本控制系统,它允许多个开发人员在不同的地点对同一个项目进行协作,且每个开发人员都拥有整个项目的完整版本历史。与集中式版本控制系统相比,DVCS 的主要优点在于:
- 离线工作:开发者可以在没有网络连接的情况下进行提交和版本控制,因为他们的本地仓库包含了完整的历史记录。
- 分支和合并:DVCS 通常实现了高效的分支和合并功能,开发者可以轻松创建新分支以进行实验或开发新功能,之后再将其合并回主分支。
- 数据完整性:通过使用哈希算法(例如 SHA-1),分布式版本控制系统可以确保数据的完整性,从而避免数据损坏或丢失。
- 历史追踪:每次提交都会记录更改的详细信息,包括作者、时间戳和更改内容,便于追踪和审查历史记录。
远程仓库:
远程仓库是指存储在网络上(如互联网上)的代码存储库,通常用于版本控制系统(如Git)的操作。与本地仓库相比,远程仓库可以让多个开发者共享和协作开发项目,便于代码的备份、版本管理和团队协作。常见的远程仓库服务包括Gitee、GitHub、GitLab、Bitbucket等。
在使用远程仓库时,开发者通常会执行以下操作:
- 克隆(clone):将远程仓库的代码复制到本地。
- 推送(push):将本地的修改提交到远程仓库。
- 拉取(pull):从远程仓库获取更新的代码,并合并到本地。
- 分支(branch)管理:可以在远程仓库中创建、删除和管理分支,以便于不同特性的开发和任务分配。
11.1 创建远程仓库(gitee为例)
仓库名称:一般围绕项目系统来命名
仓库地址:用于访问远程仓库
- Readme文件:用于介绍
- Issue模板文件--为团队成员提供一个预定义的格式,以便于创建和提交问题(Issues)。
- Pull Request模板文件:合并申请单,开发成员一般都不能直接将开发用的分支直接merge到master分支,需要填写合并申请单,然后交给管理员同意,在merge到master分支
11.2 克隆远程仓库 HTTPS
使用HTTPS协议: 指令:git clone https协议,将远程仓库克隆到本地,但git clone不能克隆在任意一个本地仓库中
克隆下来的仓库状态:
指令:git remote,显示远程仓库的名称(origin是远程仓库默认名字)
指令:git remote -v,显示远程仓库的详细信息
11.3 克隆远程仓库 SSH
使用SSH协议: SSH使用了公钥加密和公钥登录的机制,使用SSH协议链接进行克隆操作,必须将本地服务器的公钥放到服务器上进行管理,才可以克隆成功
第一步:添加公钥到远端库中:
创建SSH Key,在用户主目录下(不是本地仓库下),看看是否有.ssh目录,如果有.ssh看该目录下有没有id_rsa和id_rsa.pub这两个文件,有这两个文件就可以跳过下一步;如果没有.ssh,需要创建.ssh目录。
第二步:指令ssh-keygen -t rsa -C "gitee绑定的邮箱",生成公钥id_rsa.pub和密钥id_rsa
生成的密钥对,id_rsa是密钥,不能泄漏;id_rsa.pub是公钥,可以告诉任何人。
第三步:添加公钥到gitee:
然后就可以使用SSH来进行clone了
11.4 向远程仓库推送(push)
指令:git push origin 本地分支:远程分支,将本地分支推送到远程仓库的远程分支(本地分支与远程分支名称一致,可以省略:远程仓库),使用该指令本地分支与远程分支不需要建立连接(对于本地仓库的master和远程仓库的master,第一次clone时git会自动建立这两个分支的联系,所以可以直接进行推拉操作,其他分支需要手动建立连接)
11.5 拉取远程仓库(pull)
指令:git pull origin 远程分支:本地分支,pull操作进行了拉取+合并操作。(远程分支与本地分支名称一致,:本地分支 可省略)
11.6忽略特殊文件
git工作区的根目录下创建一个特殊的.gitignore文件,把要忽略的文件名或者文件后缀填进去,git就会自动忽略这些文件了,git就不会对这些文件进行追踪管理。
在.gitignore中
- *文件/后缀,表示忽略的文件
- 若要特殊的不排除某个文件,可以写入 !文件名
指令:git add -f 被忽略的文件,强制add添加被忽略的文件
指令:git check-ignore -v 被忽略的文件,显示被忽略的原因
11.7 配置命令别名
指令:git config --global alias.别名 原名,用于取别名,--global表示在所有仓库生效,去掉--global表示只在当前仓库生效。
例如:给status起别名为st git config --global alias.st status
给 log --pretty=oneline --abbrev-commit起别名为lpa
git config --global alias.lpa 'log --pretty=oneline --abbrev-commit'
注意用: ' '
作用:方便
12.Git标签管理
标签 tag ,可以简单的理解为是对某次commit的标识,相当于起一个别名,例如:在项目发布某一个版本的时候,针对最后一次commit起一个v1.0这样的标签来标识里程碑的意义。
作用:commit id难以记住,tag标签可以代替commit id,且便于记住且有意义。
12.1创建标签
指令:git tag 标签名称,默认给最新一次commit的id起别名
指令:git tag 标签名称 commit_id,指定commit的id起别名
指令:git tag,查看标签
指令:git tag -a 标签名称 -m "对标签描述" commit_id,添加该标签的描述
指令:git show 标签名称,查看标签的描述和其他详细信息
12.2删除标签
指令:git tag -d 标签名称,删除标签
12.3推送标签
本地仓库的标签推送到远程仓库的标签:
指令:git push origin 标签名称,单个标签推送
指令:git push origin --tags,全部标签推送
删除远程仓库的标签:
指令:git push orgin :标签名称,在远程仓库删除对应标签,但本地仓库没有删除
13.Git实战场景
13.1多人协作一
指令:git branch,只能查看本地分支
指令:git branch -r,可以查看远程分支(如:origin/master,origin/dev)
指令:git branch -a,显示本地和远程的分支(远程仓库新创建的分支要在本地查看,需要先进行git pull拉取操作 )
题外话:
对于pull和push操作:都是基于本地和远程仓库的分支进行操作的,进行pull/push时,
如果指明哪两个分支进行操作,那么这两个分支是不需要建立远程连接的;
当直接git push/pull时,那么分支就需要建立远程连接,这样才知道是哪个分支操作到哪个分支。
创建远程连接:
指令:git checkout -b dev origin/dev,在本地创建dev分支并切换到dev分支,同时本地dev与远程仓库的origin/dev分支建立连接
指令:git branch --set-upstream-to=origin/远程分支 本地分支,直接将远程分支与本地分支创建连接
指令:git branch -vv,查看本地分支与远程分支的连接关系
1.前期准备:
使用Linux和Windows两个系统来模拟两个开发者:
Windows下:
2.分别在本地dev分支进行操作:
开发者1进行操作: 在dev分支,对file.txt进行修改,然后add,commit,推送到远程仓库的dev分支
开发者2进行操作: 由于开发者1已经进行操作,且推送到远程仓库,此时开发者2进行修改,add、commit后,直接push会有冲突,直接拒绝push。所以需要先pull拉到本地仓库,再解决冲突,然后add、commit、push。
3.合并到master分支:
方案一(本地操作):pull拉到本地(同时要保证本地master是最新的,因为远端master可以有所更改,本地master也要保留更改,再去与dev合并),在本地将dev合并到master(前面讲过的,先将master合并到dev,在dev解决冲突后,再将dev合并到master),再push推送到远程
方案二(远程操作,推荐):创建Pull Request->填写申请单->审查人员进行审查->合并
总结:
- 首先试图push推送自己的修改
- 如果推送失败,则是因为远程分支比本地分支更新,需要先用git pull试图合并
- 如果合并有冲突,解决冲突,本地提交,再push推送
- 功能开发完毕,将分支merge进master,再删除分支
13.2多人协作二
1.准备工作:
创建分支:
方案一:远程创建分支--优势:远程保证master最新且稳定,在远程创建分支后直接git pull拉到本地,本地创建分支并与该远程创建的分支进行连接(git pull有两种效果:1、拉取分支的内容,需要分支之间创建连接;2、拉取仓库的内容,例如上面远程新创建的分支拉取到本地,不需要创建连接)。
方案二:本地创建分支--本地创建分支,并将该分支直接推送到远端(指令:git push origin 分支名称),此时远端会有一个同名的分支;-- 劣势:无法保证master是最新且稳定的,需要先pull本地,再进行操作。
2.在两个分支分别开发(互不冲突)
3.将两个分支合并到master分支:
在远端创建Pull Request申请将feature-2合并到master -> 经过审查同意并进行合并;
将feature-1合并到master时可能会有冲突,在本地仓库先将master合并到feature-1中解决冲突后,再add、commit、push,再提交Pull Request申请合并到master
4.删除远程分支: 删除feature-1和feature-2
解决git branch -a打印已被删除的远程分支的方法:
指令:git remote show origin,显示远程仓库的状态
指令:git remote prune origin,在本地删除已在远程仓库删除的分支
14.Git分支设计规范
了解常见的系统开发环境:
- 在系统开发过程中,通常会涉及多个不同的环境,每个环境都有其不同的用途和特点。以下是一些常见的开发环境:
- 开发环境:开发人员在自己的计算机上搭建的环境,通常用于编写和测试代码。常见的工具包括集成开发环境(IDE)、文本编辑器和本地服务器。
- 测试环境:用于功能测试和集成测试的环境,通常与生产环境相似,用于验证系统的各个部分是否能够正常工作。
- 预生产环境(或称为Staging环境):这个环境模拟生产环境,通常用于最终测试,确保在部署到生产环境之前,所有功能和性能都符合要求。
- 生产环境:最终用户使用的环境,所有的功能和服务都在此环境中运行。生产环境通常要求高可用性和稳定性。
- 还有仿真/灰度环境……
常见的分支和环境的搭配(可视情况而定不同的策略):
分支 | 名称 | 适用环境 |
---|---|---|
master | 主分支 | 生产环境 |
release | 预发布分支 | 预发布/测试环境 |
develop | 开发分支 | 开发环境 |
feature | 需求开发分支 | 本地 |
hotfix | 紧急修复分支 | 本地 |
常用模型之一:Git Flow
master分支
- master为主分支,只读且唯一分支。用于部署到正式发布环境,一般由合并release分支得到
- 主分支作为稳定的唯一代码库,任何情况下不允许直接在master分支上修改代码
- 产品的功能全部实现后,最终在master分支对外发布,另外所有在master分支的推送应该打标签做记录,方便追溯
- master分支不可删除
release分支
- release 为预发布分支,基于本次上线所有的 feature 分支合并到 develop 分支之后,基
- 于 develop 分支创建。可以部署到测试或预发布集群。
- 命名以 release/开头,建议的命名规则:release/version_publishtime。
- release 分支主要用于提交给测试人员进行功能测试。发布提测阶段,会以release 分支代码
- 为基准进行提测。
- 如果在 release 分支测试出问题,需要回归验证 develop 分支看否存在此问题。
- release 分支属于临时分支,产品上线后可选删除。
develop 分支
- develop 为开发分支,基于master分支创建的只读且唯一分支,始终保持最新完成以及 bug修复后的代码。可部署到开发环境对应集群。
- 可根据需求大小程度确定是由 feature 分支合并,还是直接在上面开发(非常不建议)
feature 分支
- feature 分支通常为新功能或新特性开发分支,以 develop 分支为基础创建 feature 分支
- 命名以 feature/ 开头,建议的命名规则:feature/user_createtime_feature。
- 新特性或新功能开发完成后,开发人员需合到 develop 分支。
- 一旦该需求发布上线,便将其删除。
标签:git,--,仓库,Git,master,指令,分支 From: https://blog.csdn.net/cookies_s_/article/details/142835048hotfix 分支
- hotfix 分支为线上 bug 修复分支或叫补丁分支,主要用于对线上的版本进行 bug 修复。当线上出现紧急问题需要马上修复时,需要基于 master分支创建 hotfix 分支。
- 命名以 hotfix/ 开头,建议的命名规则:hotfix/user_createtime_hotfix
- 当问题修复完成后,需要合并到 master 分支和 develop 分支并推送远程。一旦修复上线,便将其删除。