🔥个人主页: 中草药
🔥专栏:【中间件】企业级中间件剖析
基本概念
Git 有三个核心区域,分别是工作区、暂存区和版本库,理解这三个区域是掌握 Git 的基础。
工作区就是我们电脑里能看到的文件目录,比如我们在项目文件夹里写代码,这个文件夹就是工作区。举个例子,我们在 “myproject” 文件夹里编写 Java 代码,这个 “myproject” 文件夹就是工作区,我们所有的代码修改都在这里进行。
暂存区就像一个临时的中转站,它位于.git 目录下的 index 文件中。当我们在工作区完成文件修改后,需要先将这些修改提交到暂存区。比如我们在工作区修改了一个名为 “app.java” 的文件,通过 “git add app.java” 命令,就把这个修改后的文件添加到了暂存区,暂存区会记录这些修改,等待我们进一步确认。
版本库也叫本地仓库,它位于工作区目录下的.git 隐藏文件夹中,里面包含了 Git 管理项目所需的所有信息,包括所有的版本数据、分支信息等。当我们把暂存区的内容提交到版本库后,这些修改就被正式记录下来了,形成一个新的版本。
基本使用
git的功能非常强大,其中,git中我们常见的操作有以下几种
类别 | 命令 | 说明 |
---|---|---|
仓库初始化 | git init |
初始化当前目录为 Git 仓库 |
git clone <url> |
克隆远程仓库到本地 | |
文件操作 | git add <file> |
添加文件到暂存区 |
git rm <file> |
删除工作区文件并暂存操作 | |
git mv <old> <new> |
移动/重命名文件并暂存 | |
提交更改 | git commit -m "消息" |
提交暂存区的更改并添加描述 |
git commit --amend |
修改最新一次提交(可追加更改或修改提交信息) | |
状态查看 | git status |
查看工作区与暂存区状态 |
git log |
显示提交历史 | |
git diff |
比较工作区与暂存区的差异 |
下面对部分操作进行一个详细介绍
创建仓库
以下操作均在Ubuntu界面呈现
初始化仓库
要使用 Git 管理项目,首先需要初始化一个仓库。在命令行中进入项目所在的目录,例如我们的项目在 “D:\myproject” 文件夹下,输入 “cd D:\myproject” 进入该目录,然后输入 “git init” 命令。
执行这个命令后,会在当前目录下生成一个隐藏的.git 文件夹,这个文件夹就是 Git 的版本库,里面包含了 Git 进行版本控制所需的各种文件和配置信息(不允许在.git目录下手动修改)。此时,我们就可以使用 Git 来管理这个项目了。
配置本地仓库
使用git config 实现 git config --global 配置全局配置(一台服务器可以实现多个本地仓库)
添加文件
在工作区创建或修改文件后,需要将这些文件添加到暂存区。使用 “git add” 命令,其格式为 “git add < 文件名 >”。
如果要添加当前目录下的所有文件,可以使用 “git add .” 命令。例如,我们在工作区新建了 “index.html” 和 “style.css” 两个文件,输入 “git add index.html style.css” 可以将这两个文件添加到暂存区;如果想添加所有修改的文件,输入 “git add .” 即可。
添加文件到暂存区的作用是告诉 Git,这些文件的修改是我们想要提交到版本库的。
将暂存区的文件提交到版本库,需要使用 “git commit” 命令,格式为 “git commit -m "提交说明"”。其中,“-m” 后面的字符串是对本次提交的描述,方便我们日后查看提交记录时了解本次修改的内容。
例如,我们将暂存区的文件提交到版本库,输入 “git commit -m "初次提交项目文件"”,执行后,版本库就会记录下这次提交的所有修改,形成一个新的版本。
每次提交都会生成一个唯一的 commit ID,用于标识这个版本,我们可以通过这个 ID 回退到相应的版本。
可以通过git log查找日志
git reflog 用于查看本地的每一次提交命令
git status 查看工作区和缓存区的状态
版本回退
git能够维护版本的重要原因,便是它能够灵活的回退版本
git reset [--soft | --mixed | --hard] [HEAD]
选项 | 工作区 | 暂存区 | 版本库 |
(原本状态) | A B | A B | A B |
--soft | A B | A B | A |
--mixed(默认) | A B | A | A |
--hard(慎用) | A | A | A |
撤销修改
工作区 | 暂存区 | 版本库 | 解决方式 |
A B | A | A | 1、手动撤销(不推荐,容易出错) 2、git checkout -- [filename](推荐使用,--不能省略) |
A B | A B | A | git reset --mixed |
A B | A B | A B | git reset --hard HEAD^(前提条件:commit之后没有push) |
命令别名
举例:如给 git status 命令起一个别名可以用命令
git config --global alias.st status
分支管理
基础
分支是 Git 的核心功能,允许多线并行开发。
分支 = 指向提交的指针
每个分支都是一个指向某个提交(commit)的轻量级指针,默认分支通常为 main
或 master
。
HEAD 指针:指向当前所在分支的指针(即工作目录的状态来源)。
常见操作
命令 | 作用 | 示例 |
---|---|---|
git branch |
查看本地分支(-a 包含远程分支,-v 显示最近提交) |
git branch -av |
git branch <name> |
创建新分支(不切换) | git branch feature/payment |
git checkout <branch> |
切换到已有分支 | git checkout dev |
git checkout -b <new-branch> |
创建并切换到新分支(常用!) | git checkout -b fix/issue-123 |
git merge <branch> |
合并指定分支到当前分支 | git checkout main git merge dev |
git branch -d <branch> |
删除已合并的分支 | git branch -d feature/old |
git branch -D <branch> |
强制删除未合并的分支(谨慎!) | git branch -D experiment |
git push origin <branch> |
推送分支到远程仓库 | git push origin feature/login |
git push origin --delete <branch> |
删除远程分支 | git push origin --delete temp-branch |
与远程分支建立连接
git checkout -b [dev] [origin/dev]
git branch --set-upstream-to=origin/dev dev
合并冲突
当两个分支修改了同一文件的同一区域时,合并会触发冲突:
此时需要手动解决并进行一次提交操作
冲突标记
<<<<<<< HEAD # 当前分支的修改
当前分支的内容
=======
要合并分支的内容
>>>>>>> feature
可以通过
git log --graph --abbrev-commit 以试图的方式查看分支
分支管理策略
1、快进合并(Fast-Forward)
条件:目标分支是当前分支的直接祖先(无分叉)。
效果:移动分支指针,不生成新提交(历史线性)。
在这种 Fast forward 模式下,删除分支后,查看分支历史时,会丢掉分支信息,看不出来最新提交到底是 merge 进来的还是正常提交的。
git支持我们强制禁用fast forward模式,在merge的时候会产生一个新的commit,这样可以便于我们更好地去追溯这个改动是merge进来的还是commit的
git merge -no-ff -m ' ' dev
Bug分支
假如我们现在正在 dev2 分支上进行开发,开发到一半,突然发现 master 分支上面有 bug,需要解决。在Git中,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。
举例说明场景
此时,为了保存dev2中开发到一半的代码
Git 提供了 git stash 命令,可以将当前的工作区信息进行储藏,被储藏的内容可以在将来某个时间恢复出来。
储藏 dev2 工作区之后,由于我们要基于master分支修复 bug,所以需要切回 master 分支,再新建临时分支来修复 bug
修复完成后,切换到 master分支,并完成合并,最后删除fix_bug 分支:(假设情况如下图)
先使用git stash pop去恢复现场 此时状态图为
Master 分支目前最新的提交,是要领先于新建 dev2 时基于的 master 分支的提交的,所以我们在 dev2 中当然看不见修复 bug 的相关代码。
我们的最终目的是要让 master 合并 dev2 分支的,那么正常情况下我们切回 master 分支直接合并即可,但这样其实是有一定风险的。
是因为在合并分支时可能会有冲突,而代码冲突需要我们手动解决(在 master 上解决)。我们无法保证对于冲突问题可以正确地一次性解决掉,因为在实际的项目中,代码冲突不只一两行那么简单,有可能几十上百行,甚至更多,解决的过程中难免手误出错,导致错误的代码被合并到 master上。此时的状态为:
此时的解决办法是在当前分支合并master,解决冲突之后,再去使用master合并dev
这只是某一种bug情况的提醒,实际的业务场景可能比这复杂的多
远程操作
Git 的远程操作是连接本地仓库与远程仓库(如 GitHub、GitLab 等)的桥梁,用于实现多人协作和代码同步。虽然 Git 是分布式系统,本地可以独立工作,但实际开发中几乎都需要通过远程操作与他人共享代码。
创建远程仓库-去往gitee去操作
clone 仓库
git clone https://gitee.com/……
克隆后,本地会自动关联远程仓库,别名为 origin
SSH 协议和 HTTPS 协议是 Git 最常使用的两种数据传输协议。SSH 协议使用了公钥加密和公钥登陆机制,体现了其实用性和安全性,使用此协议需要将我们的公钥放上服务器,由Git服务器进行管理。使用 HTTPS 方式时,没有要求,可以直接克隆下来。
SSH
使用 SSH方式克隆仓库,由于我们没有添加公钥到远端库中,服务器拒绝了我们的clone 链接。需要我们设置一下:
第一步:创建SSHKey。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa 和 id_rsa.pub 这两个文件,如果已经有了,可直接跳到下一步。如果没有,需要创建SSH Key:
ssh-keygen -t rsa -C "123456@qq.com"
此时,顺利的话,可以在用户主目录里找到.ssh 目录,里面有id_rsa和 id_rsa.pub 两个文件,这两个就是SSH Key的秘钥对,id_rsa 是私钥,不能泄露出去,id_rsa.pub 是公钥,可以放心地告
诉任何人
从远程仓库拉取代码
pull操作实际上是pull + merge
拉取远程仓库的最新代码到本地,并合并到当前分支:
# 拉取 origin 远程的默认分支(通常是 main/master)并合并到本地当前分支
git pull origin
# 拉取指定远程分支(如 dev)并合并到本地当前分支
git pull origin dev
# 首次拉取时可能需要指定本地分支与远程分支的关联
git pull origin dev:dev # 拉取远程 dev 到本地 dev 分支
注意:
git pull
=git fetch
(获取远程更新) +git merge
(合并到本地)
向远程仓库推送代码
push操作是分支与分支的操作
将本地仓库的提交推送到远程仓库:
# 推送本地当前分支到 origin 远程的对应分支(首次推送需要 -u 关联)
git push -u origin main # -u 表示设置默认关联,后续可直接用 git push
# 推送指定本地分支到远程指定分支
git push origin dev:dev # 本地 dev → 远程 dev
忽略特殊文件
.gitignore
并不是所有文件都需要推送到远程仓库,比如本地的数据库的配置信息,包含在.gitignore 的文件不会进行推送(可以使用git add -f 强制进行add)
上述的.gitignore文件配置了以下规则
忽略所有.so(Linux 共享库)和.ini(配置文件)类型的文件
特殊排除 c.so 文件,使其能被 Git 追踪
查看指定文件被哪些 .gitignore
规则匹配而被忽略,帮助排查「为什么某个文件没被 Git 追踪」的问题。
git check-ignore -v 文件名
-v
(或 --verbose
):显示详细信息,包括 匹配的规则来源(哪个 .gitignore
文件)和 具体规则内容。
解决 git branch -a打印已被删除的远程分支的方法
git remote prune origin
标签管理
基础
在 Git 中,标签(tag)是指向某个提交对象的固定指针,常用于标记特定版本,比如发布版本、里程碑版本等,方便快速定位到对应的代码状态。Git 的标签分为轻量级标签(lightweight tag)和附注标签(annotated tag),以下是关于标签管理的详细介绍:
轻量级标签实际上就是一个保存着对应提交对象的校验和(哈希值)的文件,创建轻量级标签非常简单,命令格式如下:
git tag <tagname> [<commit>]
其中,<tagname>
是你要创建的标签名,<commit>
是可选参数,用于指定标签要指向的提交对象,若不指定,默认指向当前所在的提交对象。例如,在当前提交上创建一个名为 v1.0
的轻量级标签:
git tag v1.0
附注标签是存储在 Git 数据库中的一个完整对象,包含标签名、打标签者的名字和电子邮件地址、日期时间、标签说明等信息。创建附注标签使用 -a
选项,命令格式如下:
git tag -a <tagname> -m "<tag message>" [<commit>]
其中,-m
选项用于指定标签的说明信息,<tag message>
就是标签说明内容。比如,创建一个名为 v2.0
的附注标签,并添加说明信息:
git tag -a v2.0 -m "这是项目的第二个正式发布版本"
查看标签
列出所有标签
使用以下命令可以列出当前仓库中的所有标签:
git tag
默认情况下,标签会按字母顺序列出。如果想按照创建时间顺序列出标签,可以使用 sort -V
命令进行排序:
git tag | sort -V
查看标签详细信息
要查看某个特定标签的详细信息,对于附注标签,可以使用 git show
命令:
git show <tagname>
例如,查看 v2.0
标签的详细信息:
git show v2.0
对于轻量级标签,git show
命令会显示标签指向的提交对象的详细信息。
推送标签
默认情况下,git push
不会推送标签到远程仓库。要推送某个标签到远程仓库,可以使用以下命令:
git push origin <tagname>
如果要一次性推送所有本地标签到远程仓库,可以使用:
git push origin --tags
拉取远程标签
当远程仓库新增了标签,你可以使用以下命令拉取远程标签到本地:
git fetch origin tag <tagname> # 拉取单个标签
git fetch origin --tags # 拉取所有标签
删除标签
可以直接在仓库管理界面删除
删除本地标签
要删除本地的某个标签,可以使用 -d
选项,命令格式如下:
git tag -d <tagname>
例如,删除名为 v1.0
的本地标签:
git tag -d v1.0
删除远程标签
删除远程标签需要先删除本地标签,然后通过 git push
命令将删除操作同步到远程仓库,命令格式如下:
git push origin :<tagname>
例如,删除远程仓库中的 v2.0
标签:
git push origin :refs/tags/v2.0
使用标签
在实际开发中,当需要切换到某个标签对应的版本时,可以使用 git checkout
命令。不过,由于标签是只读的,直接 checkout
标签会让你处于 “分离 HEAD” 状态(即 HEAD 指针直接指向某个提交对象,而不是指向某个分支 )。如果要基于标签创建一个新分支进行开发,可以使用:
git checkout -b <branchname> <tagname>
例如,基于 v2.0
标签创建一个名为 feature/v2.0-dev
的新分支:
git checkout -b feature/v2.0-dev v2.0
标签管理是 Git 中一个非常有用的功能,能够帮助开发者更方便地管理项目版本,追踪重要的代码状态。
Git Flow模型
一般根据不同的环境来设计分支
Git Flow 是一种常用的 Git 分支管理模型,由 Vincent Driessen 提出,适用于大型项目或多人协作的项目,它定义了一系列分支及其使用规则,以规范代码管理和版本发布流程 ,以下是 Git Flow 模型中主要分支及其作用:
分支 | 名称 | 适用环境 |
---|---|---|
master | 主分支 | 生产环境 |
release | 预发布分支 | 预发布 / 测试环境 |
develop | 开发分支 | 开发环境 |
feature | 需求开发分支 | 本地 |
hotfix | 紧急修复分支 | 本地 |
master 分支
- master 为主分支,该分支为只读且唯一分支。用于部署到正式发布环境,一般由合并 release 分支得到。
- 主分支作为稳定的唯一代码库,任何情况下不允许直接在 master 分支上修改代码。
- 产品的功能全部实现后,最终在 master 分支对外发布,另外所有在 master 分支的推送应该打标签(tag)做记录,方便追溯。
- 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 分支。
- 一旦该需求发布上线,便将其删除。
hotfix 分支
- hotfix 分支为线上 bug 修复分支或叫补丁分支,主要用于对线上的版本进行 bug 修复。当线上出现紧急问题需要马上修复时,需要基于 master 分支创建 hotfix 分支。
- 命名以 hotfix/ 开头,建议的命名规则: hotfix/user_createtime_hotfix
- 当问题修复完成后,需要合并到 master 分支和 develop 分支并推送远程。一旦修复上线,便将其删除。
先相信你自己,然后别人才会相信你。 —— 屠格涅夫
🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀
以上,就是本期的全部内容啦,若有错误疏忽希望各位大佬及时指出💐
制作不易,希望能对各位提供微小的帮助,可否留下你免费的赞呢🌸