Git
# 1. 概述
# 1.1 什么是版本控制
版本控制是一种在开发过程中用于管理我们对文件、目录等工程内容修改历史,方便查看更改历史记录,备份以便恢复以前的版本的软件工程技术
你可以把一个版本控制系统(缩写VCS)理解为一个“数据库”,在需要的时候,它可以帮你完整地保存一个项目的快照。当你需要查看一个之前的快照(称之为“版本”)时,版本控制系统可以显示出当前版本与上一个版本之间的所有改动的细节。
版本控制系统会记录所有对项目文件的更改。这就是版本控制,听起来很简单。
最简单的版本控制就是保存项目内容的一个备份,编号为"A",然后基于原始项目进行修改,修改后保存为版本"B",保留软件不同状态的数份copy,并且适当编号。许多大型开发案都是使用这种简单技巧。虽然这种方法能用,但是很没效率。一是因为保存的数份copy几乎完全一样,也因为这种方法要高度依靠开发者的自我纪律,从而导致错误。
# 1.1.1 为什么使用版本控制
# 1.1.1.1 版本存储
常见的版本存储方式就是在本地多次备份不同版本的文件,即使按照通用的命名格式保存后,还需要花费大量的时间来分析整理这些备份文件,而且这种操作很容易出错,而且经常性的不知道为什么保存,保存了什么变动的内容,因为我们很少花更多的时间去记录和观察每一个重要的变化
版本控制系统就完美的解决了我们的问题,每当你提交一次对项目新的改动时,他会基于最原始的文件,保存每一个细节的变化到一个版本中,可以帮助我们很好地了解相邻版本间的变动关系。
而且版本控制系统有撤销的功能,我们可以基于某个版本号,撤销所有/部分的变动信息,回到当时的文件状态。在项目的每一个重要阶段,认识和正确地使用撤销功能会让我们的工作变得非常轻松。
# 1.1.1.2 协同合作
基于传统方式修改项目代码的时候,必须告知团队中的其他人,我在干什么,防止他们和我冲突,而这不可能的,所以当我好不容易编辑完文件后,发现该文件被人删了,感觉很不舒服。
有了版本控制系统,团队每一个成员都可以自由的修改代码文件,进行团队的协同工作,版本控制系统可以帮我们将所有改动内容合并保存为一个版本,即使某些功能代码意外丢失,也可以通过版本系统找回。
# 1.2 版本控制系统分类
随着互联网的发展,软件产品的更新迭代越来越快,软件产品代码的版本控制系统也发生了千变万化,既有开源的,也有商用的,而且都是针对各种不同的应用环境设计的。目前市场上出现比例较高的版本控制系统主要有三类:本地版本控制系统,集中式版本控制系统和分布式版本控制系统。
# 1.2.1 本地版本控制系统(RCS)
许多人习惯用复制整个项目目录的方式来保存不同的版本,或许还会改名加上备份时间以示区别,这么做唯一的好处就是简单,但是特别容易犯错, 有时候会混淆所在的工作目录,一不小心会写错文件或者覆盖意想外的文件。
为了解决这个问题,人们很久以前就开发了许多种本地版本控制系统,大多都是采用某种简单的数据库来记录文件的历次更新差异。
其中最流行的一种叫做 RCS,现今许多计算机系统上都还看得到它的踪影。 RCS的工作原理是在硬盘上保存补丁集(补丁是指文件修订前后的变化);通过应用所有的补丁,可以重新计算出各个版本的文件内容。
# 1.2.2 集中化的版本控制系统
接下来人们又遇到一个问题,如何让在不同系统上的开发者协同工作?
于是,集中化的版本控制系统(Centralized Version Control Systems,简称 CVCS)应运而生。 这类系统,诸如 CVS、Subversion 以及 Perforce 等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。 多年以来,这已成为版本控制系统的标准做法。
这种做法带来了许多好处,特别是相较于老式的本地 VCS 来说。 现在,每个人都可以在一定程度上看到项目中的其他人正在做些什么。 而管理员也可以轻松掌控每个开发者的权限,并且管理一个 CVCS 要远比在各个客户端上维护本地数据库来得轻松容易。
事分两面,有好有坏。 这么做最显而易见的缺点是中央服务器的单点故障。 如果宕机一小时,那么在这一小时内,谁都无法提交更新,也就无法协同工作。
如果中心数据库所在的磁盘发生损坏,又没有做恰当备份,毫无疑问你将丢失所有数据——包括项目的整个变更历史,只剩下人们在各自机器上保留的单独快照。 本地版本控制系统也存在类似问题,只要整个项目的历史记录被保存在单一位置,就有丢失所有历史更新记录的风险。
# 1.2.3 分布式版本控制系统
于是分布式版本控制系统(Distributed Version Control System,简称 DVCS)面世了。
在这类系统中,像 Git、Mercurial、Bazaar 以及 Darcs 等,客户端并不只提取最新版本的文件快照, 而是把代码仓库完整地镜像下来,包括完整的历史记录。 这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。 因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份。
更进一步,许多这类系统都可以指定和若干不同的远端代码仓库进行交互。籍此,你就可以在同一个项目中,分别和不同工作小组的人相互协作。 你可以根据需要设定不同的协作流程,比如层次模型式的工作流,而这在以前的集中式系统中是无法实现的。
# 1.2.4 集中式VS分布式
先说集中式版本控制系统,版本库是集中存放在中央服务器的,而干活的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始干活,干完活了,再把自己的活推送给中央服务器,中央服务器就好比是一个图书馆,你要改一本书,必须先从图书馆借出来,然后回到家自己改,改完了,再放回图书馆。
集中式版本控制系统最大的毛病就是必须联网才能工作,如果在局域网内还好,带宽够大,速度够快,可如果在互联网上,遇到网速慢的话,可能提交一个10M的文件就需要5分钟,这还不得把人给憋死啊。
那分布式版本控制系统与集中式版本控制系统有何不同呢?首先,分布式版本控制系统根本没有“中央服务器”,每个人的电脑上都是一个完整的版本库,这样,你工作的时候,就不需要联网了,因为版本库就在你自己的电脑上,既然每个人电脑上都有一个完整的版本库,那多个人如何协作呢?比方说你在自己电脑上改了文件A,你的同事也在他的电脑上改了文件A,这时,你们俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。
和集中式版本控制系统相比,分布式版本控制系统的安全性要高很多,因为每个人电脑里都有完整的版本库,某一个人的电脑坏掉了不要紧,随便从其他人那里复制一个就可以了,而集中式版本控制系统的中央服务器要是出了问题,所有人都没法干活了。
在实际使用分布式版本控制系统的时候,其实很少在两人之间的电脑上推送版本库的修改,因为可能你们俩不在一个局域网内,两台电脑互相访问不了,也可能今天你的同事病了,他的电脑压根没有开机。因此,分布式版本控制系统通常也有一台充当“中央服务器”的电脑,但这个服务器的作用仅仅是用来方便“交换”大家的修改,没有它大家也一样干活,只是交换修改不方便而已。
# 1.3 Git是什么
Git是目前世界上最先进的分布式版本控制系统
git是一个和svn一样的版本控制软件,但是与svn不同的是,git是一个分布式的高效版本控制系统。
其实现原理跟svn也大相径庭,采取了一种以空间换时间的理论,为什么是使用分布式呢,因为git会在每个开发者的本地中都保留了一份仓库副本,即使在断网的时候,也能提交代码到各自的仓库中,等联网后,再提交到中央仓库,每个开发者的仓库都是互相不可见的。
# 1.3.1 Git历史
Git 诞生于 Linux 内核社区对可用的 VCSs(版本控制系统)的挫败感
Linux 内核的发展在当时是相当不寻常的:项目中有大量的贡献者而且贡献者的参与程度和对代码知识库的了解有很大的差异。由于 Linux 内核不寻常的发展状况,开发人员很难找到适合他们需求的 VCSs(版本控制系统)。于是他们选择了 BitKeeper 和并发修订系统(CVS),每个系统有一组核心开发人员去负责管理内核的开发。BitKeeper 提供分布式版本控制,而 CVS 是一个客户端-服务端版本控制系统,它可以让开发人员“签出”项目的副本,进行更改,然后将他们的改变“签入”到服务端。
在 2005 年初期,BitKeeper 的版权持有人 Larry McVoy 宣布撤销允许免费使用 BitKeeper 软件的许可。他声称,正在创建与 BitKeeper 反向交互软件的澳大利亚程序设计师 Andrew Tridgell 反向设计了 BitKeeper 的源代码,这样违背了它的许可。许多依赖 BitKeeper 免费软件去开发 Linux 内核的 Linux 核心开发者现在已经无法继续使用它了。
Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!一个月之内,Linux系统的源码已经由Git管理了!牛是怎么定义的呢?大家可以体会一下。
Git迅速成为最流行的分布式版本控制系统,尤其是2008年,GitHub网站上线了,它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery,PHP,Ruby等等。
# 1.3.2 Git和SVN区别
# 1.3.2.1 直接记录快照,而非差异比较
Git 和其它版本控制系统(包括 Subversion 和近似工具)的主要差别在于 Git 对待数据的方式。
从概念上来说,其它大部分系统以文件变更列表的方式存储信息,这类系统(CVS、Subversion、Perforce、Bazaar 等等) 将它们存储的信息看作是一组基本文件和每个文件随时间逐步累积的差异 (它们通常称作 基于差异(delta-based) 的版本控制)。
Git 不按照以上方式对待或保存数据,反之,Git 更像是把数据看作是对小型文件系统的一系列快照。 在 Git 中,每当你提交更新或保存项目状态时,它基本上就会对当时的全部文件创建一个快照并保存这个快照的索引。 为了效率,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件, Git 对待数据更像是一个 快照流。
这是 Git 与几乎所有其它版本控制系统的重要区别, 因此 Git 重新考虑了以前每一代版本控制系统延续下来的诸多方面, Git 更像是一个小型的文件系统,提供了许多以此为基础构建的超强工具,而不只是一个简单的 VCS。
# 1.3.2.2 近乎所有操作都是本地执行
在 Git 中的绝大多数操作都只需要访问本地文件和资源,一般不需要来自网络上其它计算机的信息。
如果你习惯于所有操作都有网络延时开销的集中式版本控制系统,Git 在这方面会让你感到速度之神赐给了 Git 超凡的能量, 因为你在本地磁盘上就有项目的完整历史,所以大部分操作看起来瞬间完成。
# 1.3.2.3 小结
- svn是集中式的,而git是分布式的,如果svn的中央仓库代码被删除了,那么可能代码真的就找不回来了,而git因为是分布式的,本地都有着所有代码的副本,所以即便中央仓库代码丢失,也可能通过本地代码重新恢复回来。
- svn每次提交记录,都是将提交的数据之间的差异数据进行保存,而git则是对有修改的文件使用另一个新的文件来保存,即使用了更多的资源,但是现在的社会,最不缺的就是空间资源了。
- svn服务器中使用了全局版本号,每次提交都会产生一个唯一的全局id,且是由顺序的。而git则是根据sha1来进行盐值加密算法获取,没有什么先后区分
- 分支管理的不同,svn的开辟新分支,则是将原有的分支的文件全部拷贝一份到新分支中,如果项目比较大,该过程可能会消耗点时间。而git则是通过指针的方式,非常的快速
- 操作的不同。svn中一般提交代码和拉取代码两步骤,而git则有一个暂存区的概念,先add,然后commit。
- 学习曲线的不同。svn相对简单,git学习曲线相对陡峭
# 1.3.3 为什么要用Git
- 首先git是一个比svn更加优秀的代码管理工具,已经可以说取代了svn,其区别如上
- 目前的很多程序中,都需要有git的支持,可能在使用一款工具时,会先检测是否安装了git,否则必须要求先安装git,可见其活跃度
- 由于github和码云的兴起,拉去代码都是通过git来操作完成
# 1.3.4 Git,GitHub与GitLab的区别
- Git是一种版本控制系统,是一种工具,用于代码的存储和版本控制。
- GitHub是一个基于Git实现的在线代码仓库,是目前全球最大的代码托管平台,可以帮助程序员之间互相交流和学习。
- GitLab是一个基于Git实现的在线代码仓库软件,你可以用GitLab自己搭建一个类似于GitHub一样的仓库,但是GitLab有完善的管理界面和权限控制,一般用于在企业、学校等内部网络搭建Git私服。
- GitHub和GiLlab两个都是基于Web的Git远程仓库,它们都提供了分享开源项目的平台,为开发团队提供了存储、分享、发布和合作开发项目的中心化云存储的场所。从代码的私有性上来看,GitLab 是一个更好的选择。但是对于开源项目而言,GitHub 依然是代码托管的首选。
# 1.3.5 安装Git
可以登录官网
https://git-scm.com/
下载相应版本的Git进行安装
安装好Git之后在控制台输入Git 出现以下就是安装成功了
其他版本安装参考
https://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%AE%89%E8%A3%85-Git
# 1.3.6 配置 Git
安装完成Git后还需要进行一些配置
# 1.3.6.1 用户信息
安装完 Git 之后,要做的第一件事就是设置你的用户名和邮件地址。
这一点很重要,因为每一个 Git 提交都会使用这些信息,它们会写入到你的每一次提交中,并且不可更改
git config --global user.name "John Doe"
git config --global user.email johndoe@example.com
如果使用了 --global
选项,那么该命令只需要运行一次,因为之后无论你在该系统上做任何事情, Git 都会使用那些信息,当你想针对特定项目使用不同的用户名称与邮件地址时,可以在那个项目目录下运行没有 --global
选项的命令来配置
git config user.name "John Doe"
git config user.email johndoe@example.com
# 1.3.6.2 文本编辑器
设置完成用户信息后,接下来就可以设置文本编辑器了,如果git需要输入相关信息就会调用该编辑器,如果未配置,Git 会使用操作系统默认的文本编辑器
在 Windows 系统上,如果你想要使用别的文本编辑器,那么必须指定可执行文件的完整路径
下面是配置Git的默认编辑器是notepad++
git config --global core.editor "'C:/Program Files/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin"
# 1.3.6.3 查看配置信息
如果想要检查你的配置,可以使用
git config --list
命令来列出所有 Git 的相关配置
git config --list
# 1.4 安装GitLab
# 1.4.1 GitLab是什么
GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的Web服务,可通过Web界面进行访问公开的或者私人项目,它拥有与Github类似的功能,能够浏览源代码,管理缺陷和注释。
维基百科:https://zh.m.wikipedia.org/zh-hans/GitLab
about.gitLab:https://about.gitlab.com/
# 1.4.2 搭建GitLab
该安装使用的是centos7来进行安装的
参看:https://about.gitlab.com/install/#centos-7 在线安装
离线安装:https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/
# 1.4.2.1 环境确认
uname -a
cat /etc/system-release
(1)CentOS 6或者7 (此处使用7)
(2)2G内存(实验)生产(至少4G),不然会很卡
(3)安装包:gitlab-ce-13.7.3-ce.0.el7.x86_64.rpm (或者按照下面的步骤在线安装)
(4)禁用防火墙,关闭selinux
# 1.4.2.2 安装依赖
安装GitLab需要一些依赖环境
sudo yum install -y curl policycoreutils-python openssh-server postfix
# 1.4.2.3 在线安装(外网)
使用外网方式进行安装,需要到外网现在仓库,有一些镜像是在国内速度稍慢可能需要重试几次
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash
如果出现
The repository is setup! You can now install packages.
表示仓库已经安装成功
仓库下载成功后就可以通过yum进行安装了
sudo yum install -y gitlab-ce
因为网络原因可能会切换到不同的镜像进行多次尝试,如果出现如下界面表示已经安装成功
# 1.4.3 初始化配置
# 1.4.3.1 配置目录介绍
GitLab默认的配置文件路径:
/etc/gitlab/
- /etc/gitlab/gitlab.rb:主配置文件,包含外部URL、仓库目录、备份目录等
- /etc/gitlab/gitlab-secrets.json:(执行gitlab-ctl reconfigure命令行后生成),包含各类密钥的加密信息
# 1.4.3.2 初始化配置
配置首页地址(需将设置的域名DNS解析到服务器IP,或者修改本地host将域名指向服务器IP)
# 查看external_url参数配置
cat /etc/gitlab/gitlab.rb |grep -v "#" |grep -Ev "^$"
external_url 'http://gitlab.example.com'
# 编辑将该gitlab.rb的该配置改为宿主机地址
vi /etc/gitlab/gitlab.rb
# 需要修改成自己的ip
external_url 'http://192.168.200.200:8888'
tips:不改配置,需要通过 http://gitlab.example.com 访问,为了快速学习,改成支持IP访问,生产建议域名访问
# 1.4.3.3 重新应用配置文件
在这一阶段花费时间会比较长
gitlab-ctl reconfigure
如果出现以下界面说明已经配置成功
# 1.4.3.4 查看Gitlab运行状态
可以通过以下命令查看Gitlab的运行状态
gitlab-ctl status
# 1.4.4 登录测试
通过:http://192.168.200.200:8888/ 地址访问Gitlab服务,查看服务是否正常启动,注意这个地址就是上面配置的
external_url
# 1.4.5 Docker安装
参考:https://docs.gitlab.com/ee/install/docker.html
采用compose安装启动
version: '3.6'
services:
web:
image: 'gitlab/gitlab-ce:latest'
restart: always
hostname: 'gitlab.example.com'
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://192.168.200.200:8929' #根据情况自己修改一下
gitlab_rails['gitlab_shell_ssh_port'] = 2224
ports:
- '8929:8929'
- '2224:22'
volumes:
- '$GITLAB_HOME/config:/etc/gitlab'
- '$GITLAB_HOME/logs:/var/log/gitlab'
- '$GITLAB_HOME/data:/var/opt/gitlab'
shm_size: '256m'
# 1.5 Gitlab配置
安装完成Gitlab后就需要对Gitlab进行一系列的配置
# 1.5.1 修改管理员密码
gitlab默认的管理员账号是:root
# 1.5.1.1 查看root密码
gitlab-ce初装以后,把密码放在了一个临时文件中了,文件路径是
/etc/gitlab/initial_root_password
cat /etc/gitlab/initial_root_password
其中红框中的就是密码,注意:这个文件将在首次执行reconfigure后24小时自动删除
# 1.5.1.2 登录后并修改密码
拿到这个密码后需要尽快登录web界面进行密码修改
将文件中的密码复制到密码框后进行登录
登录完成后就需要进行密码修改了,选择用户下的
Edit profile
进行属性设置
在弹出的页面选择
password
,在下面页面进行密码设置
# 1.5.2 偏好设置
gitlab是我们国内非常好用的git工具,有很多偏好设置可以进行设置
# 1.5.2.1 操作步骤
选择用户下的
Preferences
进入偏好设置
# 1.5.2.2 导航栏主题
者第一个
Navigation theme
选项可以选择对应的导航栏主题
# 1.5.2.3 代码主题设置
在Idea中可能习惯了一些代码的主题设置,而在gitlab中也可以设置代码预览的主题,这里可以进行设置
# 1.5.2.4 设置中文
Gitlab默认是英文的,很多小伙伴看起来比较麻烦,我们可以设置为简体中文模式
这里简体中文的翻译度达到了95%,基本上够日常使用了,注意需要重新登陆后才会生效
# 1.5.3 添加账号
在Gitlab添加账号是需要管理员进行审核的
# 1.5.3.1 注册账号
可以点击
Register now
进行账号注册
点击后进入有账号注册页面,可以填写用户名密码进行账号的注册
这里:需要注册两个账号:zs , ls
# 1.5.3.2 审核账号
新注册的账号是不可以直接进行登录的,需要管理员进行审核,通过
菜单-管理员
来进行设置
在新打开的页面选择用户,在打开的页面选择批准相关注册的账号
对于需要进行注册的账号选择批准即可
审核通过的账号可以进行登录
# 1.5.3.3 新增账号
除了可以进行手动注册,管理员还可以进行批量新增用户,在管理员的用户管理,管理员可以进行手动新增
点击新增用户后就可以进行手动新增了
# 1.6 连接Gitlab
一般情况下我们连接Gitlab都是使用的
ssh key
进行连接的,下面我们看下如何进行配置
# 1.6.1配置用户信息
参考上文的配置Git
# 1.6.2 查看配置的用户信息
可以通过一下命令查看配置的用户信息
git config user.name
git config user.email
# 1.6.3 生成SSH key
通过以下命令可以生成相应的
ssh key
# 注意这里的xxx@qq.com要替换为git配置的邮箱名称
ssh-keygen -t rsa -b 2048 -C "zx@itcast.cn"
tips:在201机器上演示zs
具体生成过程如下
# 1.6.4 获取SSH key
通过如下命令可以获取对应的
ssh key
cat ~/.ssh/id_rsa.pub
# 1.6.4.1 Gitlab的sshkey配置
1,可以通过编辑用户资料来配置来进行配置
ssh key
2,每个用户需要自己单独配置一下个性化,比如中文
接下来打开ssh key配置页面将我们配置的
ssh key
配置到我们的gitlab中
点击完成就可以完成配置了
# 1.6.5 验证测试
我们配置完成后还需要进行验证测试
# ssh -T git@192.168.200.201 #ssh -T git@192.168.200.201 -p 2224 #容器部署时映射的是2224端口
The authenticity of host '192.168.200.201 (192.168.200.201)' can't be established.
ECDSA key fingerprint is SHA256:4Ze/q+QQ5942NjyhwQiGLZCceB9mcbC759CiyjWzHYU.
ECDSA key fingerprint is MD5:61:8b:1a:f7:db:19:a8:17:bb:70:e8:f7:62:f3:a1:2d.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.200.201' (ECDSA) to the list of known hosts.
Welcome to GitLab, @zs!
出现如下界面就表示我们配置成功了
# 2. Git使用流程
# 2.1 Git基本概念
Git学习最困难的原因之一就是概念非常多,如果使用SVN的方式去学习Git就会感觉Git非常的难以理解
# 2.1.1 四个工作区域
Git本地有四个工作区域
# 2.1.1.1 工作区
工作区,就是本地电脑存放代码的地方
# 2.1.1.2 暂存区
用于临时存放你的改动,事实上它只是一个文件,保存即将提交到文件列表信息
英文叫 stage 或 index,一般存放在 .git 目录下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)
# 2.1.1.3 版本库
工作区中有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
版本库就是安全存放数据的位置,这里面有你提交到所有版本的数据,其中HEAD指向最新放入仓库的版本,之所以说git 快,是因为它是分布式版本控制系统,大部分提交都是对本地仓库而言的,不依赖网络,最后一次会推送的到远程仓库
# 2.1.1.4 远程仓库
托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换,比如GitHub,Gitee等
# 2.1.2 最小配置+基本操作
# 2.1.2.1 最小配置:
git config --global user.name 'tans'
git config --global user.email 'tans@itcast.cn'
git config --list
config作用域
git config --local #针对当前仓库有效 缺省值
git config --global # 对当前用户所有仓库有效
git config --system #对系统所有登录的用户有效
展示 : --list
git config --local --list
git config --global --list
git config --system --list
# 2.1.2.2 基本操作
在201节点上操作,模拟不同用户在不同机器上的行为
1,已有项目纳入git管理
[root@k8-controller demo]# mkdir -p /root/git/demo
[root@k8-controller demo]# git init
[root@k8-controller demo]# ll -a
total 0
drwxr-xr-x. 3 root root 18 Jun 28 23:23 .
drwxr-xr-x. 3 root root 19 Jun 28 23:04 ..
drwxr-xr-x. 7 root root 119 Jun 28 23:23 .git
创建一个新项目并纳入git管理
git init your_project
cd your_project
2,创建local 用户
[root@k8-controller demo]# git config --local user.name 'zs'
[root@k8-controller demo]# git config --local user.email 'zs@itcast.cn'
[root@k8-controller demo]# git config --local --list
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
user.name=ts
user.email=ts@itcast.cn
3,创建readme
[root@k8-controller demo]# touch readme
4,提交
[root@k8-controller demo]# git commit -m 'add reademe'
# On branch master
#
# Initial commit
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# readme
nothing added to commit but untracked files present (use "git add" to track)
5,添加到暂存区查看状态
[root@k8-controller demo]# git add readme
[root@k8-controller demo]# git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: readme
#
6,提交
[root@k8-controller demo]# git commit -m 'add reademe'
[master (root-commit) 0b75d17] add reademe
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 readme
7,查看日志
[root@k8-controller demo]# git log
commit 0b75d17d3692f96909f1b58605000dbde8c19e82
Author: zs <zs@itcast.cn>
Date: Tue Jun 28 23:28:31 2022 -0400
add reademe
结论:优先使用local级别的配置
# 2.2 远程仓库创建项目
一般我们不会在本地使用git创建项目,而是直接在远程仓库(gitlab,github)创建项目然后克隆到本地进行开发的
# 2.2.1 GitLab新建项目
我们可以通过选择
项目
-->新建项目
来创建一个新的项目
在这里选择一个空的项目
# 2.2.2 配置项目
我们还需要对项目做一些配置,比如项目名称等
然后点击
新建项目
就可以创建项目了
# 2.2.3 添加项目成员
直接邀请成员,把 zs ,ls 添加进去
# 2.2.3 找到项目地址
我们可以点击克隆复制项目的克隆地址
# 2.3 下载项目到本地
一般开发需要将项目先克隆到本地然后进行修改等操作,通过如下命令就可以将项目克隆到本地
# 2.3.1 idea直接下载新项目
Idea是可以直接拉取项目的,比较简单,通过新建项目就可以完成,选择通过版本控制新建项目
然后输入刚刚复制的git地址即可
# 2.3.2 git clone 新项目
在200节点上用ls用户进行操作,模拟不同用户在不同机器上的行为。
有时候我们还是需要通过命令进行clone的
我们一般需要创建一个项目相关的文件夹将项目克隆到本地,windows我们可以在对应的文件夹中通过右键
-git bash here
来打开git bash
进行操作,然后执行如下命令
首先ls用户需要生产ssh key
[root@k8-controller git]# ssh-keygen -t rsa -C "ls@itcast.cn"
[root@k8-controller git]# cat ~/.ssh/id_rsa.pub
然后ls用户登录,添加SSH key,
接下来执行如下命令:
[root@work-node1 demo]# cd /root/git
[root@work-node1 demo]# git clone git@192.168.200.200:gitlab-instance-faefd22f/git-test.git
[root@work-node1 demo]# cd git-test/
[root@work-node1 demo]# git config --local user.name 'ls'
[root@work-node1 demo]# git config --local user.email 'ls@itcast.cn'
[root@work-node1 demo]# git config --list --local
# 2.3.3 和本地仓库关联
用201节点上自己初始化的项目去关联远程项目
[root@work-node1 demo]# cd /root/git/demo/
[root@work-node1 demo]# git remote add origin git@192.168.200.200:gitlab-instance-faefd22f/git-test.git
[root@work-node1 demo]# git remote -v
origin git@192.168.200.200:gitlab-instance-faefd22f/git-test.git (fetch)
origin git@192.168.200.200:gitlab-instance-faefd22f/git-test.git (push)
# 2.4 常规操作
接下来就是Git的一些常规操作
在200节点上使用ls账号操作
# 2.4.1 本地文件修改
在clone下来的项目中修改。
克隆下来项目后,我们就可以对项目进行修改,这里我们简单创建几个文件
[root@work-node1 ~]# cd /root/git/git-test
[root@work-node1 git-test]# echo "hello world" > a
[root@work-node1 git-test]# echo "king of juan" > b
[root@work-node1 git-test]# ll
total 16
-rw-r--r--. 1 root root 12 Jun 29 09:33 a
-rw-r--r--. 1 root root 13 Jun 29 09:33 b
-rw-r--r--. 1 root root 6251 Jun 29 06:48 README.md
# 2.4.2 添加修改文件
我们接下来就需要将修改的文件添加到暂存区
# 2.4.2.1 添加命令
add有多种形式,可以add某个文件,某个文件夹,或直接add当前仓库下所有文件
git add 单个文件
git add 文件夹1/ 文件夹2/ ……多个文件夹之间空格隔开
git add .
# 2.4.2 执行添加并查看状态
[root@work-node1 git-test]# git add a b
[root@work-node1 git-test]# git status
# On branch main
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: a
# new file: b
#
# 2.4.3 拉取远程仓库
在每次提交之前需要先拉取远程仓库的内容,防止冲突
# 2.4.3.1 拉取命令
git fetch 命令用于从远程获取版本库。该命令执行完后需要执行 git merge 远程分支到你当前所在的分支。
git fetch [alias]
git merge [alias]/[branch]
tips:示例如下:
[root@work-node1 git-test]# git fetch origin [root@work-node1 git-test]# git branch -v * main 9f2a4f7 Initial commit [root@work-node1 git-test]# git merge origin/main Already up-to-date.
另外;
git pull 命令用于从远程获取代码并合并本地的版本。
git pull 其实就是 git fetch 和 git merge FETCH_HEAD 的简写
git pull 命令用于从远程获取代码并合并本地的版本。
git pull <远程主机名> <远程分支名>:<本地分支名>
如果本地分支和远程分支一样的话
:
后面的内容可以忽略
git pull <远程主机名> <远程分支名>
# 2.4.3.2 拉取变更
1,首先在远端直接提交一个变更
然后提交:
然后我们在拉取变更
下面我们就是用命令拉取以下远程变更,因为gitlab默认的主分支是
main
[root@work-node1 git-test]# git pull origin main
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From 192.168.200.200:gitlab-instance-faefd22f/git-test
* branch main -> FETCH_HEAD
Updating 9f2a4f7..1d14d36
Fast-forward
test | 1 +
1 file changed, 1 insertion(+)
create mode 100644 test
[root@work-node1 git-test]# ll
total 20
-rw-r--r--. 1 root root 12 Jun 29 09:33 a
-rw-r--r--. 1 root root 13 Jun 29 09:33 b
-rw-r--r--. 1 root root 6251 Jun 29 06:48 README.md
-rw-r--r--. 1 root root 14 Jun 29 09:59 test
# 2.4.4 提交修改
完成操作后就可以进行提交修改了到仓库了,这样仓库就可以进行永久变更了
# 2.4.4.1 提交命令
可以通过如下的命令进行提交变更
git commit -m "注释"
具体注释的格式每一个公司都是不一样的,可以按照公司规范来做
# 2.4.4.2 提交修改
[root@work-node1 git-test]# git commit -m 'add a and b'
[main 300089b] add a and b
2 files changed, 2 insertions(+)
create mode 100644 a
create mode 100644 b
# 2.4.5 推送远程仓库
因为
git
是分布式的版本管理工具,我们要让变更让其他的同事看到就需要推送到远程仓库
# 2.4.5.1 推送命令
推送远程仓库的命令如下
git push <远程主机名> <本地分支名>:<远程分支名>
如果本地分支名与远程分支名相同,则可以省略冒号
git push <远程主机名> <本地分支名>
# 2.4.5.2 查看远程仓库
有的时候如果忘记远程仓库地址可以使用如下命令查看远程仓库地址
git remote -v
通过该命令可以打印出来我们远程仓库的地址,这里的
orgin
是默认的远程仓库地址,如果推送到这里的远程仓库,我们可以使用orgin
来代替远程仓库
# 2.4.5.3 推送提交
下面我们就将修改推送到
gitlab
[root@k8-controller git-test]# git push origin main
Counting objects: 5, done.
Delta compression using up to 6 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 340 bytes | 0 bytes/s, done.
Total 4 (delta 0), reused 0 (delta 0)
remote: GitLab: You are not allowed to push code to protected branches on this project.To git@192.168.200.200:gitlab-instance-faefd22f/git-test.git
! [remote rejected] main -> main (pre-receive hook declined)
error: failed to push some refs to 'git@192.168.200.200:gitlab-instance-faefd22f/git-test.git'
gitlab的main分支(master分支)默认是处于被保护状态下的,develop 角色是没有权限提交到 master 分支的,有两种解决办法:
1,联系管理员分配Maintainer角色权限
2,临时解决的方式是 Setting中 => Protected branches 启用 master 分支可被 develop 角色提交即可
选择2,如下:
然后再次尝试
[root@k8-controller git-test]# git push origin main
Counting objects: 5, done.
Delta compression using up to 6 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 340 bytes | 0 bytes/s, done.
Total 4 (delta 0), reused 0 (delta 0)
To git@192.168.200.200:gitlab-instance-faefd22f/git-test.git
e602b65..98bb81d main -> main
# 2.4.6 其他人拉取变更
回到201节点,用zs用户从远程拉取变更
[root@work-node1 demo]# git remote -v
origin git@192.168.200.200:gitlab-instance-faefd22f/git-test.git (fetch)
origin git@192.168.200.200:gitlab-instance-faefd22f/git-test.git (push)
[root@work-node1 demo]# git pull origin main:master
From 192.168.200.200:gitlab-instance-faefd22f/git-test
! [rejected] main -> master (non-fast-forward)
采用fetch + merge
[root@work-node1 demo]# git fetch origin
[root@work-node1 demo]# git branch -a
* master
remotes/origin/main
# 将远程main分支内容合并到当前master分支
[root@work-node1 demo]# git merge origin/main
Merge made by the 'recursive' strategy.
README.md | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
a | 1 +
b | 1 +
test | 1 +
4 files changed, 95 insertions(+)
create mode 100644 README.md
create mode 100644 a
create mode 100644 b
create mode 100644 test
[root@work-node1 demo]# ll
total 20
-rw-r--r--. 1 root root 12 Jun 30 00:43 a
-rw-r--r--. 1 root root 13 Jun 30 00:43 b
-rw-r--r--. 1 root root 0 Jun 29 11:06 readme
-rw-r--r--. 1 root root 6251 Jun 30 00:43 README.md
-rw-r--r--. 1 root root 18 Jun 30 00:43 test
同时将本地master分支上的变更推送到远程main分支
[root@work-node1 demo]# git push origin master:main
Counting objects: 6, done.
Delta compression using up to 6 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (5/5), 480 bytes | 0 bytes/s, done.
Total 5 (delta 1), reused 0 (delta 0)
To git@192.168.200.200:gitlab-instance-faefd22f/git-test.git
98bb81d..e8ef10e master -> main
# 2.5 分支操作
https://www.runoob.com/git/git-branch.html
在200节点上使用ls
# 2.5.1 创建分支
一般我们很少从头开始做一个项目,都是中途接手的,这个时候我们一般开发一个功能就需要新建分支了,并且分支也是我们最重要的一个功能
# 2.5.1.1 查看分支
我们要查看本地分支列表,可以通过如下命令进行查询
[root@k8-controller git-test]# git branch
* main
我们发现这里面现在只有一个main分支
这里
main
分支有一个*
标识是当前活动分支
# 2.5.1.2 创建分支
我们一般开发一个功能是需要创建分支的,创建分支命令也非常简单,执行
git branch (branchname)
即可
[root@k8-controller git-test]# git branch master
[root@k8-controller git-test]# git branch
* main
master
我们创建一个master分支,并查看当前分支列表
# 2.5.1.3 切换分支
1,我们可以通过git checkout (branch)
进行切换分支
[root@k8-controller git-test]# git checkout master
Switched to branch 'master'
[root@k8-controller git-test]# git branch
main
* master
切换分支后我们发现活动分支已经变成了master
2,我们在当前分支做一些变更,当我们还原回到原来的分支后就会被还原回去
[root@k8-controller git-test]# echo 'hello master' > master
[root@k8-controller git-test]# git add .
[root@k8-controller git-test]# git commit -m 'add master'
[master acd81b3] add master
1 file changed, 1 insertion(+)
create mode 100644 master
[root@k8-controller git-test]# ll
total 24
-rw-r--r--. 1 root root 12 Jun 29 10:24 a
-rw-r--r--. 1 root root 13 Jun 29 10:24 b
-rw-r--r--. 1 root root 13 Jun 29 11:18 master
-rw-r--r--. 1 root root 6251 Jun 29 10:23 README.md
-rw-r--r--. 1 root root 18 Jun 29 10:23 test
3,我们切换回到main
分支查看下效果
[root@k8-controller git-test]# git checkout main
Switched to branch 'main'
[root@k8-controller git-test]# ll
total 20
-rw-r--r--. 1 root root 12 Jun 29 10:24 a
-rw-r--r--. 1 root root 13 Jun 29 10:24 b
-rw-r--r--. 1 root root 6251 Jun 29 10:23 README.md
-rw-r--r--. 1 root root 18 Jun 29 10:23 test
我们发现刚才创建的文件已经看不到了,已经被移除了
# 2.5.1.4 删除分支
当某个分支完成功能,一行不需要的时候可以选择删除分支,可以通过
git branch -D (branchname)
删除
注意不能够删除当前活动分支
[root@k8-controller git-test]# git checkout main
[root@k8-controller git-test]# git branch -d master
error: The branch 'master' is not fully merged.
If you are sure you want to delete it, run 'git branch -D master'.
[root@k8-controller git-test]# git branch -D master
Deleted branch master (was acd81b3).
[root@k8-controller git-test]# git branch
* main
# 2.5.2 分支合并-merge
如果我们已经将一个功能分支开发完成后,一般需要将该分支合并到
master
主分支,下面我们说下分支合并
继续在200节点上用ls操作
# 2.5.2.1 创建分支
我们先创建几个用于合并的分支,然后再来合并
[root@k8-controller git-test]# git checkout -b master
Switched to a new branch 'master'
[root@k8-controller git-test]# git branch
main
* master
# 2.5.2.2 提交文件
1,现我们在各个不同的分支提交文件,这里我们都是只创建文件
echo "master" > master
git add .
git commit -m 'add master'
这里我们在master分支提交了文件
2,基于master 创建一个feature分支,然后后继续提交文件
git checkout -b feature
echo "feature" > feature
git add .
git commit -m "add feature"
3,现在已经有了两个不同的分支,并且两个不同的分支提交的文件也是不同的,但是并没有冲突,查看两个分支内容
[root@k8-controller git-test]# ll
total 28
-rw-r--r--. 1 root root 12 Jun 29 10:24 a
-rw-r--r--. 1 root root 13 Jun 29 10:24 b
-rw-r--r--. 1 root root 8 Jun 29 12:02 feature
-rw-r--r--. 1 root root 7 Jun 29 11:49 index
-rw-r--r--. 1 root root 6251 Jun 29 10:23 README.md
-rw-r--r--. 1 root root 18 Jun 29 10:23 test
[root@k8-controller git-test]# git checkout master
Switched to branch 'master'
[root@k8-controller git-test]# ll
total 24
-rw-r--r--. 1 root root 12 Jun 29 10:24 a
-rw-r--r--. 1 root root 13 Jun 29 10:24 b
-rw-r--r--. 1 root root 7 Jun 29 11:49 index
-rw-r--r--. 1 root root 6251 Jun 29 10:23 README.md
-rw-r--r--. 1 root root 18 Jun 29 10:23 test
# 2.5.2.3 分支合并
下面我们操作下无冲突情况下和分支合并,这种情况下合并可以使用如下命令进行合并
git merge 分支名
该命令是将一个分支合并到当前分支,如果我们要将
feature
合并到master
分支,需要执行以下命令
[root@k8-controller git-test]# git checkout master
[root@k8-controller git-test]# git merge feature
Updating e097f5b..a685b10
Fast-forward
feature | 1 +
1 file changed, 1 insertion(+)
create mode 100644 feature
[root@k8-controller git-test]# ll
total 28
-rw-r--r--. 1 root root 12 Jun 29 10:24 a
-rw-r--r--. 1 root root 13 Jun 29 10:24 b
-rw-r--r--. 1 root root 8 Jun 29 12:04 feature
-rw-r--r--. 1 root root 7 Jun 29 11:49 index
-rw-r--r--. 1 root root 6251 Jun 29 10:23 README.md
-rw-r--r--. 1 root root 18 Jun 29 10:23 test
可以看到feature分支上的文件已经过来了,目前来说没有冲突比较简单。
# 2.5.2.4 查看提交日志
我们可以通过日志来查看合并的信息
[root@k8-controller git-test]# git log -2
commit a685b10e90a8f44b50565500421e0bb75973d9e9
Author: ls <ls@itcast.cn>
Date: Wed Jun 29 11:55:39 2022 -0400
add feature
commit e097f5bb904914cc3b848b078799b020e4184ebd
Author: ls <ls@itcast.cn>
Date: Wed Jun 29 11:49:27 2022 -0400
add index
这样看起来不是特别容易看懂,我们可以通过图形化工具来查看
# 2.5.2.5 制造冲突并查看
1,切换回feature分支,来制造一些冲突
git checkout feature
2,我们在该分支做一些变更,将master.txt
的内容做一些变更并且提交
echo "feature-append" >> master
git add .
git commit -m "modify feature branch , add to master"
cat master
3,切换回master分支对文件做一些变更并提交
git checkout master
echo "master-append" >> master
git add .
git commit -m "modify master branch , add to master"
cat master
# 2.5.2.6 合并-产生冲突
现在我们可以切换到master分支,将
feature
分支合并到master
分支
[root@k8-controller git-test]# git checkout master
[root@k8-controller git-test]# git merge feature
Auto-merging master
CONFLICT (content): Merge conflict in master
Automatic merge failed; fix conflicts and then commit the result.
# 2.5.2.7 解决冲突并提交
[root@k8-controller git-test]# cat master
master
<<<<<<< HEAD
master-append
=======
feature-append
>>>>>>> feature
手动解决冲突,留下谁由自己来定
然后提交
[root@k8-controller git-test]# git status
# On branch master
# You have unmerged paths.
# (fix conflicts and run "git commit")
#
# Unmerged paths:
# (use "git add <file>..." to mark resolution)
#
# both modified: master
#
no changes added to commit (use "git add" and/or "git commit -a")
[root@k8-controller git-test]# git add .
[root@k8-controller git-test]# git status
# On branch master
# All conflicts fixed but you are still merging.
# (use "git commit" to conclude merge)
#
# Changes to be committed:
#
# modified: master
#
[root@k8-controller git-test]# git commit -m 'fixed conflic'
[master e57d4d2] fixed conflic
[root@k8-controller git-test]# git status
# On branch master
nothing to commit, working directory clean
[root@k8-controller git-test]# git log -3
commit e57d4d2c531a2d0a7a03cd0c65a2dbcf976fcfeb
Merge: 64ae4e0 366e30f
Author: ls <ls@itcast.cn>
Date: Wed Jun 29 23:22:47 2022 -0400
fixed conflic
commit 64ae4e02d8f82e354cb9e72023c1e5c38d5a1eaf
Author: ls <ls@itcast.cn>
Date: Wed Jun 29 23:14:50 2022 -0400
modify master branch , add to master
commit 366e30f54e825845235f8b33d8017097c7652fe3
Author: ls <ls@itcast.cn>
Date: Wed Jun 29 23:12:14 2022 -0400
modify feature branch , add to master
# 2.5.2.8 查看log
查看log
[root@k8-controller git-test]# git log --graph --decorate --all
* commit e57d4d2c531a2d0a7a03cd0c65a2dbcf976fcfeb (HEAD, master)
|\ Merge: 64ae4e0 366e30f
| | Author: ls <ls@itcast.cn>
| | Date: Wed Jun 29 23:22:47 2022 -0400
| |
| | fixed conflic
| |
| * commit 366e30f54e825845235f8b33d8017097c7652fe3 (feature)
| | Author: ls <ls@itcast.cn>
| | Date: Wed Jun 29 23:12:14 2022 -0400
| |
| | modify feature branch , add to master
| |
* | commit 64ae4e02d8f82e354cb9e72023c1e5c38d5a1eaf
|/ Author: ls <ls@itcast.cn>
| Date: Wed Jun 29 23:14:50 2022 -0400
|
| modify master branch , add to master
|
* commit 787d85bf2c81e7b3808eabaaf2a932d84da38249
| Author: ls <ls@itcast.cn>
| Date: Wed Jun 29 23:10:04 2022 -0400
|
| add feature
|
* commit 4851824c26ce34286bf9af8aab1ff09ea9e83ea3
| Author: ls <ls@itcast.cn>
| Date: Wed Jun 29 23:09:46 2022 -0400
|
| add master
|
* commit 98bb81d264185ca4b4998387229d817ff3877fcf (origin/main, origin/HEAD, main)
--graph:图形展示
--decorate:让git log显示每个commit的引用(如:分支、tag等)
--all :表示显示所有的branch
--oneline :一行显示
# 2.5.3 合并分支-rebase
使用merge合并会产生很多交叉树,如果交叉很多的情况下很不容易看懂,如果想比较简单的方式合并可以选择rebase方式
# 2.5.3.1 创建fixbug分支
继续在200节点上,先准备一些环境,创建一个新分支 fixbug
git checkout master
git branch fixbug
# 2.5.3.2 fixbug上提交文件
[root@k8-controller git-test]# git checkout -b fixbug
[root@k8-controller git-test]# echo "fixbug branch ,fix1604bug" >> master
[root@k8-controller git-test]# git add .
[root@k8-controller git-test]# git commit -m 'on fixbug branch ,fixed master '
[fixbug 3d6704c] on fixbug branch ,fixed master
1 file changed, 1 insertion(+)
# 2.5.3.3 master分支提交
回到master分支,同样做出改动
[root@k8-controller git-test]# git checkout master
Switched to branch 'master'
[root@k8-controller git-test]# echo "master king" >> master
[root@k8-controller git-test]# git add .
[root@k8-controller git-test]# git commit -m 'on master branch ,add master king'
[master 24efd9a] on master branch ,add master king
1 file changed, 1 insertion(+)
[root@k8-controller git-test]# cat master
master
master-append
feature-append
master king
# 2.5.3.4 合并并解决冲突
合并,使用rebase
[root@k8-controller git-test]# git branch
fixbug
main
* master
[root@k8-controller git-test]# git rebase fixbug
First, rewinding head to replay your work on top of it...
Applying: on master branch ,add master king
Using index info to reconstruct a base tree...
M master
Falling back to patching base and 3-way merge...
Auto-merging master
CONFLICT (content): Merge conflict in master
Failed to merge in the changes.
Patch failed at 0001 on master branch ,add master king
The copy of the patch that failed is found in:
/root/git/git-test/.git/rebase-apply/patch
When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".
[root@k8-controller git-test]# ll
total 28
-rw-r--r--. 1 root root 12 Jun 30 00:53 a
-rw-r--r--. 1 root root 13 Jun 30 00:53 b
-rw-r--r--. 1 root root 8 Jun 30 00:58 feature
-rw-r--r--. 1 root root 137 Jun 30 01:12 master
-rw-r--r--. 1 root root 0 Jun 30 00:52 readme
-rw-r--r--. 1 root root 6251 Jun 30 00:52 README.md
-rw-r--r--. 1 root root 18 Jun 30 00:52 test
[root@k8-controller git-test]# cat master
master
master-append
feature-append
<<<<<<< HEAD
fixbug branch ,fix1604bug
=======
master king
>>>>>>> on master branch ,add master king
[root@k8-controller git-test]# vi master
[root@k8-controller git-test]# git add .
[root@k8-controller git-test]# git rebase --continue
master: needs merge
You must edit all merge conflicts and then
mark them as resolved using git add
# 2.5.3.5查看日志
[root@k8-controller git-test]# git log --graph --decorate --all
* commit 2fbcfedb4bb7237eb71ebd07031832fb8ba0cc03 (HEAD, master)
| Author: ls <ls@itcast.cn>
| Date: Thu Jun 30 01:11:07 2022 -0400
|
| on master branch ,add master king
|
* commit 3d6704cf59d410963cad2ff6746dc2b50eb9ddf2 (fixbug)
| Author: ls <ls@itcast.cn>
| Date: Thu Jun 30 01:09:02 2022 -0400
|
| on fixbug branch ,fixed master
|
不会产生新的提交,也没有多余的分叉
# 2.5.4 Merge vs Rebase
https://www.atlassian.com/git/tutorials/merging-vs-rebasing
# 2.5.4.1 Merge
通过命令将 master
分支合并到 feature
分支中:git merge feature master
[简写形式],会在 feature
分支中创建一个新的 merge commit,它将两个分支的历史联系在一起,请看如下所示
使用 merge 是很好的方式,因为它是一种 非破坏性的 操作。现有分支不会以任何方式被更改,
另一方面,这也意味着 feature
分支每次需要合并上游更改时,它都将产生一个额外的合并提交。如果master
提交非常活跃,这可能会严重污染你的 feature 分支历史记录
# 2.5.4.2 rebase
用以下命令将 master
分支合并到 feature
分支上,git checkout feature; git rebase master
。
它会将整个 feature
分支移动到 master
分支的顶端,从而有效地整合了所有 master
分支上的提交。但是,与 merge 提交方式不同,rebase 通过为原始分支中的每个提交创建全新的 commits 来 重写 项目历史记录。
举例:如果你从 master 拉了个feature分支出来,然后你提交了几个 commit,这个时候刚好有人把他开发的东西合并到 master 了,这个时候 master 就比你拉分支的时候多了几个 commit,如果这个时候你 rebase master 的话,就会把你当前的几个 commit,放到那个人 commit 的后面。
rebase 的主要好处是可以获得更清晰的项目历史。首先,它消除了 git merge
所需的不必要的合并提交;其次,正如你在上图中所看到的,rebase 会产生完美线性的项目历史记录,你可以在 feature
分支上没有任何分叉的情况下一直追寻到项目的初始提交。
但是,针对这样的提交历史我们需要权衡其「安全性」和「可追溯性」。
# 2.5.4 .3 注意事项
- 不要在公共分支使用rebase
因为往后放的这些 commit 都是新的,这样其他从这个公共分支拉出去的人,都需要再 rebase,相当于你 rebase 东西进来,就都是新的 commit 了
举例说明
- 1-2-3 是现在的分支状态
- 这个时候从原来的master ,checkout出来一个prod分支
- 然后master提交了4.5,prod提交了6.7
- 这个时候master分支状态就是1-2-3-4-5,prod状态变成1-2-3-6-7
- 如果在prod上用rebase master ,prod分支状态就成了1-2-3-4-5-6-7
- 如果是merge则是 1-2-3-6-7--8 .............. |4-5|
- 会出来一个8,这个8的提交就是把4-5合进来的提交
# 2.5.4 .5 rebase
和 merge
的基本原则
1,下游分支更新上游分支内容的时候使用 rebase
2,上游分支合并下游分支内容的时候使用 merge
例如现有上游分支 master,基于 master 分支拉出来一个开发分支 dev,在 dev 上开发了一段时间后要把 master 分支提交的新内容更新到 dev 分支,此时切换到 dev 分支,使用 git rebase master
等 dev 分支开发完成了之后,要合并到上游分支 master 上的时候,切换到 master 分支,使用 git merge dev
# 3. Git使用规范
团队开发中,遵循一个合理、清晰的 Git 使用流程,是非常重要的
# 3.1 GIT分支管理
GIT远程分支主要包含:master develop feature release fixbug
# 3.1.1 master主分支
整个项目主分支,有且仅有一个,除项目负责人以外的开发人员不能像master分支合并内容
首先,代码库应该有一个、且仅有一个主分支,所有提供给用户使用的正式版本,都在这个主分支上发布。
Git主分支的名字,默认叫做Master,它是自动建立的,版本库初始化以后,默认就是在主分支在进行开发。
# 3.1.2 develop主分支
主分支只用来分布重大版本,日常开发应该在另一条分支上完成,开发用的分支为Develop
这个分支可以用来生成代码的最新隔夜版本(nightly),如果想正式对外发布,就在Master分支上,对Develop分支进行”合并”(merge)。
# 3.1.3 临时分支
前面讲到版本库的两条主要分支:Master和Develop,前者用于正式发布,后者用于日常开发,其实,常设分支只需要这两条就够了,不需要其他了
但是,除了常设分支以外,还有一些临时性分支,用于应对一些特定目的的版本开发,临时性分支主要有三种:
- 功能(feature)分支
- 预发布(release)分支
- 修补bug(fixbug)分支
这三种分支都属于临时性需要,使用完以后,应该删除,使得代码库的常设分支始终只有Master和Develop
# 3.1.3.1 feature(功能分支)
feature是为了开发后续版本的功能,从Develop分支上面分出来的,开发完成稳定后,要再并入Develop
功能分支的名字,可以采用feature-*的形式命名,常见的操作
#创建一个功能分支:
git checkout -b feature-x develop
#开发完成后,将功能分支合并到develop分支:
git checkout develop
git merge –no-ff feature-x
#删除feature分支:
git branch -d feature-x
# 3.1.4 release(预发布分支)
release是发布正式版本之前(即合并到Master分支之前),我们可能需要有一个预发布的版本进行测试。
预发布分支是从Develop分支上面分出来的,预发布结束以后,必须合并进Develop和Master分支。它的命名,可以采用release-*的形式,常见的操作如下
#创建一个预发布分支:
git checkout -b release-1.2 develop
#确认没有问题后,合并到master分支:
git checkout master
git merge –no-ff release-1.2
# 对合并生成的新节点,做一个标签
git tag -a 1.2
#再合并到develop分支:
git checkout develop
git merge –no-ff release-1.2
#最后,删除预发布分支:
git branch -d release-1.2
# 3.1.5 fixbug(修补bug分支)
fixbug分支是从master分支上面分出来的。fix结束以后,再合并进Master和Develop分支。最后,删除"fixbug分支"
修补bug分支是从Master分支上面分出来的。修补结束以后,再合并进Master和Develop分支。它的命名,可以采用fixbug-*的形式,常见的操作如下
#创建一个修补bug分支:
git checkout -b fixbug-0.1 master
#修补结束后,合并到master分支:
git checkout master
git merge –no-ff fixbug-0.1
git tag -a 0.1.1
#再合并到develop分支:
git checkout develop
git merge –no-ff fixbug-0.1
#最后,删除”修补bug分支”:
git branch -d fixbug-0.1
# 3.2 GIT代码提交规则
# 2.2.1 代码提交规范化的目的
- 为了部门提交代码信息格式规范化
- 为了更好的追溯代码、筛选
- 为了更加快速的定位提交代码所涉及的范围和实现功能
- 为了后续代码的Review、自动生成ChangeLog
# 3.2.2 代码提交信息规范模板
该模板修改自《Angular代码提交规范》,分为Header、Body两大块内容,去除Footer,这一部分很少使用
<type>(<scope>): <subject>
// 空一行
<body>
使用样例
[Bug修复](4.27.10):http://jira.xyz.cn/browse/XYZDEV-9043
原因分析:需求内容不完整或错误
# 3.2.3 Header
Header的部分只有一行,包括三个字段: type(必需), scope(可选), subject(必需)
类型 | 描述 | 描述 |
---|---|---|
type(必需) | Type of change | commit类别 |
scope(可选) | Scope of this change | commint影响的范围 |
subject(必需) | Short description | 简短的描述 |
# 3.2.3.1 type(提交类型)
- 【feat-新增功能】-【新的功能点、新的需求】
- 【fix-Bug修复】-【修复的Bug:现网发散Bug、测试阶段的Bug、验收阶段的Bug】
- 【docs-文档修改】-【只是修改了文档:注释、README.md等】.
- 【style-样式修改】-【不影响代码功能的修改:CSS样式、代码格式化等】
- 【refactor-代码重构】-【代码更改既不修复错误也不添加功能】
- 【perf-性能优化】-【代码更改可以提高性能】
- 【test-测试代码】-【添加缺失测试或更正现有测试】
- 【build-编译代码】-【影响构建系统或外部依赖项的更改:build.gradle、package.json、Podfile等】
- 【ci-持续集成】-【我们的CI配置文件和脚本的更改:Jenkinsfile等】
- 【revert-回退更改】-【代码回退提交更改】
- 【other-其他提交】-【除以上所有类型之外的提交更改】
# 3.2.3.1 scope(涉及范围)
scope
用于说明 commit 影响的范围,比如数据层、控制层、视图层等等,视项目不同而不同。
# 3.2.3.3 subject(简要描述)
subject
是 commit 目的的简短描述,不超过50个字符
- 如果提交类型是【Bug修复】,则简要描述直接填写Bug的JIRA或者Sentry链接
- 如果提交类型是【新增功能】,则简要描述填写对应需求的JIRA链接或需求的详细描述,如需求过于庞大,则应拆分成小的功能点提交代码,便于Review人员审核,也有利于Bug的回溯。
- 如果提交类型是其他类型,则简要描述根据你的理解,尽量用简短的文字描述出此次代码提交的目的
# 3.2.4 Body
Body 部分是对本次 commit 的详细描述,可以分成多行
# 3.2.4.1 详细描述
这边的详细描述,力争语句表达清晰此次提交的代码具体涉及的功能点、修改、原因分析等,如功能点很多则应使用序号列出代码所涉及的功能点。
1、顺风车项目完成了打车功能
2、顺风车项目完成了REDIS-GEO功能开发
3、顺风车项目完成积累的BUG修复
# 4,理解Git
# 4.1 理解.git目录
200节点上操作
# 4.1.1 HEAD
指针,指向当前分支
[root@k8-controller git-test]# cd /root/git/git-test/
[root@k8-controller git-test]# ls -al
total 28
drwxr-xr-x. 3 root root 108 Jun 30 01:13 .
drwxr-xr-x. 4 root root 35 Jun 30 00:52 ..
-rw-r--r--. 1 root root 12 Jun 30 00:53 a
-rw-r--r--. 1 root root 13 Jun 30 00:53 b
-rw-r--r--. 1 root root 8 Jun 30 00:58 feature
drwxr-xr-x. 8 root root 220 Jun 30 01:17 .git
-rw-r--r--. 1 root root 74 Jun 30 01:13 master
-rw-r--r--. 1 root root 0 Jun 30 00:52 readme
-rw-r--r--. 1 root root 6251 Jun 30 00:52 README.md
-rw-r--r--. 1 root root 18 Jun 30 00:52 test
查看.git目录
[root@k8-controller git-test]# cd .git/
[root@k8-controller .git]# ll
total 36
drwxr-xr-x. 2 root root 6 Jun 30 00:52 branches
-rw-r--r--. 1 root root 34 Jun 30 01:11 COMMIT_EDITMSG
-rw-r--r--. 1 root root 318 Jun 30 01:05 config
-rw-r--r--. 1 root root 73 Jun 30 00:52 description
-rw-r--r--. 1 root root 109 Jun 30 00:54 FETCH_HEAD
-rw-r--r--. 1 root root 23 Jun 30 01:17 HEAD
drwxr-xr-x. 2 root root 242 Jun 30 00:52 hooks
-rw-r--r--. 1 root root 649 Jun 30 01:17 index
drwxr-xr-x. 2 root root 21 Jun 30 00:52 info
drwxr-xr-x. 3 root root 30 Jun 30 00:52 logs
drwxr-xr-x. 33 root root 4096 Jun 30 01:17 objects
-rw-r--r--. 1 root root 41 Jun 30 01:12 ORIG_HEAD
-rw-r--r--. 1 root root 105 Jun 30 00:52 packed-refs
drwxr-xr-x. 5 root root 46 Jun 30 00:52 refs
[root@k8-controller .git]# cat HEAD
ref: refs/heads/master
指向当前分支,我们尝试切换分支
[root@k8-controller .git]# git checkout fixbug
fatal: This operation must be run in a work tree
[root@k8-controller .git]# cd ..
[root@k8-controller git-test]# git checkout fixbug
Switched to branch 'fixbug'
[root@k8-controller git-test]# git branch
* fixbug
main
master
[root@k8-controller git-test]# cat .git/HEAD
ref: refs/heads/fixbug
# 4.1.2, refs
另外我们直接进入到 refs目录下查看
[root@k8-controller git-test]# cd .git/refs/
[root@k8-controller refs]# ll
total 0
drwxr-xr-x. 2 root root 46 Jun 30 01:17 heads
drwxr-xr-x. 3 root root 20 Jun 30 00:52 remotes
drwxr-xr-x. 2 root root 6 Jun 30 00:52 tags
[root@k8-controller refs]# cd heads/
[root@k8-controller heads]# ll
total 12
-rw-r--r--. 1 root root 41 Jun 30 01:09 fixbug
-rw-r--r--. 1 root root 41 Jun 30 00:52 main
-rw-r--r--. 1 root root 41 Jun 30 01:17 master
查看 fixbug文件,既然跟分支有关系,也再次查看一下分支信息
[root@k8-controller heads]# cat fixbug
3d6704cf59d410963cad2ff6746dc2b50eb9ddf2
[root@k8-controller heads]# git branch -av
* fixbug 3d6704c on fixbug branch ,fixed master
main e8ef10e Merge remote-tracking branch 'origin/main'
master 2fbcfed on master branch ,add master king
remotes/origin/HEAD -> origin/main
remotes/origin/main e8ef10e Merge remote-tracking branch 'origin/main'
发现fixbug 分支后的信息跟我们cat 查看fixbug文件的内容有一定关系
那fixbug文件中的这一串具体是什么呢?通过git提供的一个命令来看
[root@k8-controller heads]# git cat-file -t 3d6704cf59d410963cad2ff6746dc2b50eb9ddf2
commit
[root@k8-controller heads]# git cat-file -p 3d6704cf59d410963cad2ff6746dc2b50eb9ddf2
tree 6cda39293d871875d09ab6c8611bca68f072b6cd
parent 6365649644ebcc6b8a9537eac3eb15ba67cadeef
author ls <ls@itcast.cn> 1656565742 -0400
committer ls <ls@itcast.cn> 1656565742 -0400
on fixbug branch ,fixed master
我们发现这是一个提交,即fuxbug分支指向的是一个commit,同时通过 git cat-file -p 查看这个从commit的内容,
发现它是一个tree,它有parent,它的parent不出意外也是一个commit
[root@k8-controller heads]# git cat-file -t 6365649644ebcc6b8a9537eac3eb15ba67cadeef
commit
当然它还有作者author,committer信息,以及commit时提交的信息
当然最终要是的是看它自身的这个tree信息是什么,通过 -p查看 tree的内容
[root@k8-controller heads]# git cat-file -p 6cda39293d871875d09ab6c8611bca68f072b6cd
100644 blob 6726e5640c19fca4d557baa08bff0ae004e22b83 README.md
100644 blob 3b18e512dba79e4c8300dd08aeb37f8e728b8dad a
100644 blob 6fbb2f5eb5ff166ad4207110dcceeea89ed778a7 b
100644 blob a7453f07505c42ea8d6fdda75fa91710c81c53d6 feature
100644 blob 236947a4ded0db37d1737a3b03c9f3d2901129fa master
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 readme
100644 blob 2b555209af1eb7e76f29f6e1557acaea31c096f7 test
你会发现就是这次提交的一个快照,你会发现是用一个blob对象存储的,我们查看其中一个blob的内容
[root@k8-controller heads]# git cat-file -p 3b18e512dba79e4c8300dd08aeb37f8e728b8dad
hello world
# 4.1.3 objects
https://www.runoob.com/git/git-workspace-index-repo.html
[root@k8-controller objects]# cd /root/git/git-test/.git/objects/
[root@k8-controller objects]# ll
total 0
drwxr-xr-x. 2 root root 52 Jun 30 01:01 02
drwxr-xr-x. 2 root root 52 Jun 30 01:01 13
drwxr-xr-x. 2 root root 52 Jun 30 00:57 1f
drwxr-xr-x. 2 root root 6 Jun 30 00:52 info
drwxr-xr-x. 2 root root 121 Jun 30 00:52 pack
[root@k8-controller objects]# cd 02
[root@k8-controller 02]# ll
total 4
-r--r--r--. 1 root root 32 Jun 30 01:01 0fe8d44289af20d4445f9e3129229b0a898c59
查看对象类型和内容:需要将02和这一长串拼起来
[root@k8-controller 02]# git cat-file -t 020fe8d44289af20d4445f9e3129229b0a898c59
blob
[root@k8-controller 02]# git cat-file -p 020fe8d44289af20d4445f9e3129229b0a898c59
master
master-append
# 4.1.3 config
config文件中保存了当前仓库下的一些配置
[root@k8-controller git-test]# cd .git/
[root@k8-controller .git]# ll
total 36
drwxr-xr-x. 2 root root 6 Jun 30 00:52 branches
-rw-r--r--. 1 root root 34 Jun 30 01:11 COMMIT_EDITMSG
-rw-r--r--. 1 root root 318 Jun 30 01:05 config
-rw-r--r--. 1 root root 73 Jun 30 00:52 description
-rw-r--r--. 1 root root 109 Jun 30 00:54 FETCH_HEAD
-rw-r--r--. 1 root root 23 Jun 30 02:47 HEAD
drwxr-xr-x. 2 root root 242 Jun 30 00:52 hooks
-rw-r--r--. 1 root root 520 Jun 30 02:47 index
drwxr-xr-x. 2 root root 21 Jun 30 00:52 info
drwxr-xr-x. 3 root root 30 Jun 30 00:52 logs
drwxr-xr-x. 33 root root 4096 Jun 30 01:17 objects
-rw-r--r--. 1 root root 41 Jun 30 01:12 ORIG_HEAD
-rw-r--r--. 1 root root 105 Jun 30 00:52 packed-refs
drwxr-xr-x. 5 root root 46 Jun 30 00:52 refs
[root@k8-controller .git]# cat config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = git@192.168.200.200:gitlab-instance-faefd22f/git-test.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
remote = origin
merge = refs/heads/main
[user]
name = ls
email = ls@itcast.cn