Git原理与用法系统总结

news2024/9/9 1:29:13

目录

  • Reference
  • 前言
  • 版本控制系统
  • Git的诞生
  • 配置Git
    • 配置用户名和邮件
    • 配置颜色
    • 配置`.gitignore`文件
  • Git的基础用法
    • 初始化仓库
    • 克隆现有的仓库
    • 添加暂存文件
    • 提交变动到仓库
    • 比较变动
    • 查看日志
    • Git回退
    • Git重置
    • 暂存区
  • Git版本管理
    • 重新提交
    • 取消暂存
    • 撤销对文件的修改
  • Git分支
    • Git分支的优势
    • Git的数据结构
    • 分支本质
    • 基础指令
    • 保留分支历史
    • 分支的应用策略
      • 开发策略
      • bug分支
      • feature分支
    • 解决冲突
  • Git多人协作
    • 远程仓库
    • 推送分支
    • 抓取分支
    • git rebase变基
  • Git标签
    • 标签的意义
    • 创建标签
    • 删除标签
    • 推送标签到远程

Reference

简介 - Git教程 - 廖雪峰的官方网站 (liaoxuefeng.com)

前言

为什么突然对Git这么感兴趣?可能是因为在一次面试中,被问到了一个我答不上来的Git相关问题,那一刻我觉得,这技术债得还一还了。

用了这么久的GitHub和Gitee,我才意识到我对Git的理解还只是停留在表层。每天的pushpull,似乎成了例行公事,却很少深入思考它们背后的原理。

为什么要这么深入地研究Git?真相是,不论你是在日常开发中还是在技术面试中,一旦展示出对Git原理和操作的娴熟掌握,总能让你鹤立鸡群。想想看,当别人还在用图形界面点来点去时,你已经在终端里飞速敲出命令,这不仅仅是效率的提升,更是一种极客精神的体现

而学习Git的过程,确实也让我发现,这不仅仅是一项技术,更像是一门艺术🎨,什么样的天才能够设计出这么巧妙的工具?原来是Linus啊,那没事了😇

版本控制系统

版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。 有了它你就可以将选定的文件回溯到之前的状态,甚至将整个项目都回退到过去某个时间点的状态,你可以比较文件的变化细节,查出最后是谁修改了哪个地方,从而找出导致怪异问题出现的原因,又是谁在何时报告了某个功能缺陷等等。

版本控制系统发展可以分为三个阶段:

  • 本地版本控制系统
  • 集中式版本控制系统
  • 分布式版本控制系统

Git属于分布式版本控制系统,客户端并不只提取最新版本的文件快照, 而是把代码仓库完整地镜像下来,包括完整的历史记录。 这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。 因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份。

请添加图片描述

Git的诞生

到 2002 年,Linux 系统已经发展了十年了,代码库之大让 Linus 很难继续通过手工方式管理了,整个项目组开始启用一个专有的分布式版本控制系统 BitKeeper 来管理和维护代码,BitKeeper 的东家 BitMover 公司也免费授权 Linux 社区使用这个版本控制系统。后来 BitMover 公司发现社区有人试图破解 BitKeeper 的协议,于是 BitMover 公司收了回 Linux 社区的免费使用权。

所以Linus 花了两周时间自己用 C 写了一个分布式版本控制系统,也就是 Git。

不由得佩服人家的灵感和效率🫢

配置Git

配置用户名和邮件

安装完 Git 之后,要做的第一件事就是设置你的用户名和邮件地址。 这一点很重要,因为每一个 Git 提交都会使用这些信息,它们会写入到你的每一次提交中,不可更改:

$ git config --global user.name "R1ck"
$ git config --global user.email xxx@gmail.com

配置颜色

下面的命令让 Git 显示颜色,会让命令输出看起来更醒目:

$ git config --global color.ui true

配置.gitignore文件

有些时候,你必须把某些文件放到 Git 工作目录中,但又不能提交它们,比如保存了数据库密码的配置文件等等,就可以使用忽略特殊文件 .gitignore 来很方便的解决这个问题。

各种现成的种配置文件: https://github.com/github/gitignore

下面是一些例子

假设你在 Windows 下进行 Python 开发,Windows 会自动在有图片的目录下生成隐藏的缩略图文件,如果有自定义目录,目录下就会有Desktop.ini文件,因此你需要忽略 Windows 自动生成的垃圾文件:

# Windows:
Thumbs.db
ehthumbs.db
Desktop.ini

Python编译产生的.pyc、.pyo、dist等文件或目录也可以被忽略掉

# Python:
*.py[cod]
*.so
*.egg
*.egg-info
dist
build

当然我们也可以编写例外规则,例如避免.*这个规则把.gitignore也排除了

# 排除所有.开头的隐藏文件:
.*
# 排除所有.class文件:
*.class

# 不排除.gitignore和App.class:
!.gitignore
!App.class

Git的基础用法

初始化仓库

通过git init命令可以把目录变成 Git 可以管理的仓库:

$ git init

同时在当前目录下多了一个.git的目录,这个目录是 Git 来跟踪管理版本库的

克隆现有的仓库

当你执行 git clone 命令的时候,默认配置下远程 Git 仓库中的每一个文件的每一个版本都将被拉取下来。

克隆仓库的命令是 git clone <url>

如果你想在克隆远程仓库的时候,自定义本地仓库的名字,可以通过额外的参数指定新的目录名:

例如下面这条命令,把目标目录名变成了mydocs

$ git clone https://github.com/xxx/xxx mydocs

添加暂存文件

用命令git add可以告诉 Git,把指定文件添加到暂存区域

$ git add readme.txt

我们可以通过git add .将当前目录下的所有文件添加到暂存区域

提交变动到仓库

用命令git commit告诉 Git,把文件提交到仓库:

$ git commit -m "wrote a readme file"

-m后面输入的是本次提交的说明,最好是有意义的

我们可以通过git add命令分多次暂存不同的文件,然后通过git commit一次性整合提交到仓库

在git commit之前,git add并不会向仓库中添加对象

git commit只会提交所有暂存区中的文件

比较变动

git status命令可以让我们时刻掌握仓库当前的状态,显示仓库中距离上一次提交后被修改过的文件

而使用git diff 文件名则可以查看该文件中的具体修改

一般来说我们在add完所有文件后,可以通过git status来确保仓库的状态、查看是否有修改错的文件

查看日志

git log会显示出每一个commit版本、作者以及说明
git log --pretty=oneline则会显示得更简洁和整齐,只包含commit版本和说明

Git回退

在 Git 中,用HEAD表示当前版本,也就是最新的提交
上一个版本就是HEAD,上上一个版本就是HEAD^
往上n个版本可以写作HEAD~n

当我们希望将版本回退到上一个版本,则可以使用git reset命令:

$ git reset --hard HEAD^

Git重置

git reflog用来记录我们的每一次命令
当我们不希望再回退到上一个版本时,可以通过git reflog命令找到回退之前的的commit id,并使用git reset --hard 具体的id来恢复

请添加图片描述

暂存区

请添加图片描述

工作区有一个隐藏目录.git,其中存放了暂存区stage,以及版本库

git add命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit就可以一次性把暂存区的所有修改提交到分支。

Git版本管理

重新提交

如果你在最后一次提交后意识到忘记添加了某些更改,git commit --amend 允许你修正这个错误。这个命令会重新提交暂存区中的文件,更新上一次的提交。

新的提交将代替之前提交的内容

旧有的提交在git log分支提交历史中会被删除,不过仍然可以在 git reflog 中找到,方便撤销

取消暂存

git reset HEAD <file>可以用于取消暂存,将上一次通过add提交到暂存区的该文件撤销,这对你想进行独立的commit提交非常有用

撤销对文件的修改

git checkout -- <file>会将对文件在本地的任何修改都消除掉,即使该文件的修改还没有提交到暂存区

请添加图片描述

我们可以理解为该操作是将版本库中的对应文件覆盖到本地

所以该命令也可以被用于恢复本地被错删的文件

Git分支

Git分支的优势

分支用于将工作从开发主线上分离开来,以免影响开发主线。在很多版本控制系统中,这是一个略微低效的过程——常常需要完全创建一个源代码目录的副本。

Git 处理分支的方式可谓是难以置信的轻量,创建新分支这一操作几乎能在瞬间完成,并且在不同分支之间的切换操作也是一样便捷。 与许多其它版本控制系统不同,Git 鼓励在工作流程中频繁地使用分支与合并,哪怕一天之内进行许多次。

Git的数据结构

Git在处理分支时之所以能做到轻量,与保存数据的方式有关。

在进行add暂存操作时,会为每一个文件计算校验和。然后会把当前版本的文件快照会blob对象的形式保存到 Git 仓库中,而校验和则加入到暂存区域等待提交。

在进行commit提交操作时,Git会为每一个子目录生成树对象,该对象负责记录目录结构,并保存着指向各文件快照
(blob对象)的索引。

请添加图片描述

接下来生成一个提交对象(commit object),并保存指向根目录树对象的指针,当然,该提交对象还包含了作者的姓名和邮箱、提交时输入的信息以及指向它的父对象的指针。

请添加图片描述

这个父对象,指的就是上一次提交时产生的提交对象。下面这张图会比较直观,每一次提交产生的提交对象串成了一个链表,或者说一条时间线。

请添加图片描述

分支本质

Git 的分支,其实本质上仅仅是指向提交对象的可变指针

Git 的默认分支名字是 mastermaster分支会在每次提交时自动向前移动。

一开始的时候,master分支是一条线,Git 用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点

当我们创建新的分支,例如v1.0时,Git 新建了一个指针叫v1.0,指向master相同的提交,再把HEAD指向v1.0,就表示当前分支在v1.0上

请添加图片描述

此时我们也可以看出,Git在创建分支时并不需要拷贝原本分支的文件,仅仅是添加了一个指针,工作区的文件没有任何变化

删除分支时,我们也只需要将指针给删掉就行

如果我们不考虑复杂的合并冲突问题,当两个分支在一条时间线上时,合并这两个分支要做的仅仅是将分支指针沿时间线移动

基础指令

我的git中的默认分支从master改为了main,所以后文中的默认分支均用main指代

我们可以使用git branch 分支名来创建分支
并使用git checkout 分支名来切换到指定分支

或者在checkout命令后使用-b参数,同时执行创建和切换

git checkout -b dev

请添加图片描述

使用git branch我们还能查看一共存在哪些分支,以及当前处在哪个分支,当前分支前面会标一个*号

我们在dev分支上进行文件修改后,如果想将dev上的修改合并到main分支,可以先切回main分支,并使用git merge指令
git merge指令用于合并指定分支到当前分支

git checkout main
git merge dev

请添加图片描述

合并完后如果不再需要dev分支,在git branch后加上-d参数即可删除指定分支

git branch -d dev

请添加图片描述

当然,如果我们容易将git checkout 分支名(切换分支)和git checkout -- <file>(撤销修改)弄混,也可以用git switch来切换分支

git switch也可以通过-c参数来同时完成创建和切换的操作

请添加图片描述

保留分支历史

当我们直接用Fast forward模式合并分支后,如果删除分支,则会丢掉分支信息

我们可以通过--no-ff参数,在合并时生成一个新的commit

这样相当于被合并的分支的指针会留在该分支的最后一个commit,而Head则会执行新的commit

此时当我们使用git log --graph展示分支和合并历史时,就能直观地看到时间线上有一个合并的点

请添加图片描述

分支的应用策略

开发策略

再日常开发中,分支管理的基本原则如下:

  • master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;

  • 开发和更新代码都在dev分支上进行,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,并在master分支发布1.0版本;

  • 团队成员每个人都可以从dev分支上创建属于自己的分支,并将自己的修改合并到dev分支上。

请添加图片描述

bug分支

当我们需要修复bug时,也可以开一个临时的分支,修复完在合并并删除临时分支

当然如果手头分支的开发还没做完,我们可以使用git stash将当前的工作进度存起来

等我们在主分支修完bug,可以再回到自己的分支

使用git stash apply可以将工作区恢复到之前保存的工作进度,当然stash里的内容还需要使用git stash drop来删除;或者使用git stash pop,恢复的同时把stash内容也删了

而如果我们想将主分支修复的bug补丁复制到当前分支(通常自己的分支也存在同样的bug),那么可以使用git cherry-pick bug分支名将修bug所做的补丁复制到当前分支,而不需要merge整个主分支

当然我们也可以在自己的分支修完bug再将改动复制到主分支

feature分支

添加新功能时,也可以新建一个feature分支

如果这个功能分支开发到一半,不想要了,可以使用git branch -D强制删除分支,而不需要像-d参数只能在合并后删除分支

解决冲突

请添加图片描述

在工作中,经常会出现团队成员与自己修改了dev分支的同一处文件,并且改动不一致。

请添加图片描述

而且如果此时团队成员开发更快,已经提前合并到dev分支上,那么自己再进行合并时就会出现冲突

请添加图片描述

此时我们需要手动解决冲突后才能提交
使用git status查看出现冲突的文件

请添加图片描述

查看具体冲突文件,会发现git已经自动将冲突位置标出,以及冲突分支间的差异

请添加图片描述

修改完冲突即可使用commit提交并合并

请添加图片描述

当我们使用git cherry-pick命令复制提交时,也可能出现代码冲突

当我们解决完冲突,可以使用--continue参数让Cherry pick 过程继续执行

git cherry-pick --continue

Git多人协作

远程仓库

我们使用到最多的Gir远程仓库即github,它不仅仅是开源社区,也通过远程仓库功能连接起不同团队成员的本地Git,让团队协作变得方便

一般来说远程仓库的默认名称是origin

使用git remote -v可以查看自己绑定的远程仓库的详细信息

推送分支

推送分支使用git push指令,先指定远程分支,然后是被merged的本地分支

例如git push origin master

抓取分支

当我们进行推送时,如果发现远程仓库已经有最新提交,且存在冲突,则需要先用git pull把最新的提交抓取下来,在本地合并

在本地解决完冲突,再使用git push origin <branch-name>推送
即可成功

git rebase变基

git base能通过挪动提交的位置,使得分叉的提交历史整理成一条直线

Git标签

标签的意义

发布一个版本时,通常先在版本库中打一个标签(tag)

标签与分支类似,就是指向某个commit的指针

而标签的引入则是给某个commit设置一个有意义的别名,方便人们根据版本快速查询commit

创建标签

首先切换到要打标签的分支上

使用git tag <name>就可以打一个新标签,默认该标签是打在最新提交的commit上的

当然一个可以在最后指定commit id,将标签打在指定commit上
例如

git tag v0.9 fb8b190

用命令git tag可以查看所有标签

删除标签

使用-d参数可以删除指定标签

git tag -d <name>

推送标签到远程

要将特定的标签推送到远程仓库,使用命令 git push origin <tagname>。如果你想一次性推送所有本地标签,可以使用 git push origin --tags

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1959111.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024年中小企业为何更需要找百度竞价托管代运营公司

企业间的竞争日益激烈&#xff0c;网络营销已成为企业获取市场份额、提升品牌知名度的关键途径。而在众多网络营销手段中&#xff0c;百度竞价推广因其高效、精准的特点&#xff0c;成为众多企业的首选。然而&#xff0c;随着市场竞争的加剧和百度竞价规则的不断调整&#xff0…

值得细读的8个视觉大模型生成式预训练方法

大语言模型的进展催生出了ChatGPT这样的应用&#xff0c;让大家对“第四次工业革命”和“AGI”的来临有了一些期待&#xff0c;也作为部分原因共同造就了美股2023年的繁荣。LLM和视觉的结合也越来越多&#xff1a;比如把LLM作为一种通用的接口&#xff0c;把视觉特征序列作为文…

年化27.9%,最大回撤-13.6%的可转债因子策略,结合机器学习特征筛选(附python代码)

原创文章第603篇&#xff0c;专注“AI量化投资、世界运行的规律、个人成长与财富自由"。 我们重新更新了可转债的全量数据&#xff0c;包含全量已经退市的转债。 ——这是与股票市场不一样的地方&#xff0c;股票退市相对少&#xff0c;而转债本身就有退出周期。 因此&…

喝奶 (全脂 抵脂肪 脱脂 )

鲜牛奶就是全脂的. 婴儿配方奶粉, 脂肪含量就高 全脂牛奶通常口感更浓郁&#xff0c;适合许多人的口味偏好, 全脂牛奶含有较高的脂肪含量&#xff0c;这有助于提供能量和饱腹感,从而减少总体热量的摄入, 有研究指出&#xff0c;喝全脂牛奶的儿童超重或肥胖的风险可能比喝低脂…

80端口被system占用 ,system进程是4!!!亲测-----解决

最近需要使用nginx&#xff0c;发现80端口北占用 正常情况下&#xff0c;查看那个进程占用&#xff0c;然后找到对应的程序&#xff0c;关闭对应的就可了。 使用 netstat 命令&#xff1a; 打开命令提示符&#xff08;以管理员身份&#xff09;。输入命令 netstat -ano | fi…

昇思25天学习打卡营第18天|ResNet50 迁移学习实战:从数据准备到模型构建

目录 环境配置 加载数据集 数据集可视化 构建Resnet50网络 固定特征进行训练 训练和评估 可视化模型预测 环境配置 MindSpore 库的版本管理和数据集的下载操作。首先&#xff0c;它卸载了已安装的 MindSpore 版本&#xff0c;并重新安装指定版本&#xff08;2.3.0rc1&…

帆软BI 模仿一个可视化护理软件大屏 (三百六十行 行行fine BI)

帆软BI 模仿一个可视化护理软件大屏 &#xff08;三百六十行 行行fine BI&#xff09; 文章目录 帆软BI 模仿一个可视化护理软件大屏 &#xff08;三百六十行 行行fine BI&#xff09;前言一、怎么做&#xff1f;二、导入数据三、编辑数据制作联合饼图四、编辑数据风险管理五、…

微短剧出海CPS分销推广影视平台系统搭建思维逻辑介绍

随着国内短剧市场的蓬勃发展&#xff0c;其独特的魅力与影响力已跨越国界&#xff0c;成为海外观众的新宠。这一趋势不仅推动了短剧内容的全球化传播&#xff0c;也为海外市场的CPS&#xff08;按销售分润&#xff09;分销模式提供了广阔舞台。连接内容创作者、平台运营者、系统…

数据结构与算法-关于堆的基本排序介绍

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; 文章目录 引言一、堆排序…

职场中的六条建议

在职场的征途中&#xff0c;我们每个人都是独一无二的行者&#xff0c;面对挑战与机遇并存的每一天。我们在职场中工作要弄清楚工作的本质&#xff0c;一定要牢记几点&#xff1a; 工作的本质与态度 我们工作的目的就是为了挣钱&#xff0c;我们不是来义务劳动也不是来参加快乐…

【Redis 初阶】Redis 常见数据类型(预备知识、String、哈希、List)

Redis 提供了 5 种数据结构&#xff0c;理解每种数据结构的特点对于 Redis 开发运维非常重要&#xff0c;同时掌握每种数据结构的常见命令&#xff0c;会在使用 Redis 的时候做到游刃有余。 一、预备知识 官方文档&#xff1a;Commands | Docs (redis.io) 1、最核心的两个命令…

npm提示 certificate has expired 证书已过期 已解决

在用npm新建项目时&#xff0c;突然发现报错提示 : certificate has expired 证书已过期 了解一下&#xff0c;在网络通信中&#xff0c;HTTPS 是一种通过 SSL/TLS 加密的安全 HTTP 通信协议。证书在 HTTPS 中扮演着至关重要的角色&#xff0c;用于验证服务器身份并加密数据传输…

python——joblib进行缓存记忆化-对计算结果缓存

问题场景 在前端多选框需要选取多个数据进行后端计算。 传入后端是多个数据包的对应路径。 这些数据包需要按一定顺序运行&#xff0c;通过一个Bag(path).get_start_time() 可以获得一个float时间值进行排序&#xff0c;但由于数据包的特性&#xff0c;这一操作很占用性能和时…

动手学深度学习V2每日笔记(模型初始化和激活函数)

本文主要参考沐神的视频教程 https://www.bilibili.com/video/BV1u64y1i75ap2&vd_sourcec7bfc6ce0ea0cbe43aa288ba2713e56d 文档教程 https://zh-v2.d2l.ai/ 本文的主要内容对沐神提供的代码中个人不太理解的内容进行笔记记录&#xff0c;内容不会特别严谨仅供参考。 1. 模…

Linux安装与配置

下载VMware 首先我们需要下载一个叫VMware的软件&#xff1a; 进入官方下载&#xff0c;地址&#xff1a;https://www.vmware.com/cn/products/workstation-pro/workstation-pro-evaluation.html选择与自己电脑版本适配的VMware版本【 输入许可证密钥 MC60H-DWHD5-H80U9-6V85…

硬盘分区读不出来的解决之道:从自救到专业恢复

在日常的计算机使用过程中&#xff0c;硬盘分区读不出来的问题常常令人头疼不已。这一问题不仅阻碍了用户对数据的正常访问&#xff0c;还可能预示着数据安全的潜在威胁。硬盘分区读不出来&#xff0c;通常是由于分区表损坏、文件系统错误、物理扇区损坏、驱动程序冲突或硬件连…

流量卡对比?看看哪个运营商的流量卡更适合你?

你用过流量卡吗&#xff1f;在这个一机双卡的时代&#xff0c;大部分的朋友都是人手两张电话卡&#xff0c;甚至更多&#xff0c;其中还包括一张大流量卡&#xff0c;那么&#xff0c;你会选择流量卡吗&#xff1f; ​ 为了冲量和拉新用户&#xff0c;三大运营商都在线上推出一…

优化极限学习机,实现回归预测,三种算法对比,MATLAB代码免费获取

本期将原始蜣螂算法、减法优化器算法、鲸鱼优化算法进行应用。对极限学习机进行优化实现股票回归预测&#xff0c;三种算法相互对比。 股票预测案例 股票数据特征有&#xff1a;开盘价&#xff0c;盘中最高价&#xff0c;盘中最低价&#xff0c;收盘价等。预测值为股票价格。股…

大白话讲清楚GPT嵌入(Embedding)的基本原理

嵌入&#xff08;Embedding&#xff09;是机器学习中的一个基本概念&#xff0c;尤其是在自然语言处理 (NLP) 领域&#xff0c;但它们也广泛应用于其他领域。通常&#xff0c;嵌入是一种将离散的分类数据转换为连续向量的方法&#xff0c;通常在高维空间中&#xff0c;将复杂、…

Jmeter之逻辑控制器(事务控制器+仅一次控制器+吞吐量控制器)-第八天

一.逻辑控制器 1.1事务控制器 事务&#xff0c;其实可以理解为完成一个业务所调用所有接口的集合&#xff0c;当然可以是单个接口&#xff0c;也可以是多个相互关联的串联接口。 所以在进行性能测试时&#xff0c;在用于多接口串联的场景时&#xff0c;需要汇总统计该多个接…