这里写自定义目录标题
- Git的基本使用方式
- 2.1.1 Git config
- 2.1.2 常见git配置(重要)
- 2.2 git remote和远端
- 2.2.1 HTTP remote
- 2.2.2 SSH remote
- 2.3 git add
- 2.4 git commit
- 2.5 objects
- 2.6 refs
- 2.7 annotation tag
- 追溯历史版本
- 2.9 修改历史版本
- 2.10 object
- 2.11 git gc
- 2.12 完整的git视图
- 2.13 git clone & pull & fetch
- 2.14 git push
- 常见问题
- Git 研发流程
- 3.1 不同的工作流
- 3.2 集中式工作流
- 3.3 分支管理工作流
- 常见问题
- 欢迎使用Markdown编辑器
这里写自定义目录标题
- Git的基本使用方式
- 2.1.1 Git config
- 2.1.2 常见git配置(重要)
- 2.2 git remote和远端
- 2.2.1 HTTP remote
- 2.2.2 SSH remote
- 2.3 git add
- 2.4 git commit
- 2.5 objects
- 2.6 refs
- 2.7 annotation tag
- 追溯历史版本
- 2.9 修改历史版本
- 2.10 object
- 2.11 git gc
- 2.12 完整的git视图
- 2.13 git clone & pull & fetch
- 2.14 git push
- 常见问题
- Git 研发流程
- 3.1 不同的工作流
- 3.2 集中式工作流
- 3.3 分支管理工作流
- 常见问题
- 欢迎使用Markdown编辑器
- 协同工作
- 开源社区
为什么要设计这门课程
- 入职后按照git配置,拉取代码有问题,缺少自己排查配置问题的能力
- 一些异常操作,不符合研发规范,不清楚保护分支
课程目标
- 学会正确使用
git
1. Git 是什么
分布式版本控制系统
版本控制是什么:
一种记录一个或若干文件内容的变化
为什么要版本控制
更好关注变更
及时回滚
- 本地版本控制
- 最初的方式
- 通过本地复制文件夹
- 缺点: 本地
- 最初的方式
- 集中式版本控制
- 代表工具:SVN
- 原理: 增量保存每次提交的Diff
- 缺点
- 本地不会保存
- 分支不够友好
- 容易导致历史版本丢失
- 分布式版本控制
- 原理
- 每个库都有完整的提交历史
- 每次提交记录都是完整的文件快照
- 通过push等操作来完成和远端的同步
- 缺点
- 学习成本更高
- 对大文件不是很友好
- 原理
- git发展历史
作者: Linux的作者
开发原因
Bitkeeper不允许Linux团队继续无偿使用
开发时间
两周
github: 全球最大的代码托管平台
gitlab: 全球最大的开源代码托管平台
gerrit: Google开发的一个代码托管平台, 安卓这个项目就托管在Gerrit之上
Git的基本使用方式
git命令
- 配置
- 提交代码
- 远端同步
- 拉取代码
- 推送代码
常见问题
- 为什么我配置了git,但依然没办法拉取代码
- 配置权限的问题
项目初始化
git init
:
--initial-branch
初始化的分支
--bare
创建一个裸仓库
add和commit: 存在暂存区
命令
mkdir study
cd study
ls
git init
initialized existing Git repository in /Users/xzl/Desktop/study/.git/
tree .git
tree .git
命令用于以树形结构显示当前目录下的.git
文件夹及其内容。在版本控制系统 Git 中,.git
文件夹是用来存储仓库的所有历史记录、分支、标签和配置信息的地方。通过运行tree .git
命令,您可以获得一个清晰的视图,显示.git
文件夹中的子目录和文件,以及它们之间的层次关系。
cat .git/HEAD
显示当前在的分支是main分支
config
一些配置
object
一些文件信息
refs
分支信息
后面的操作都会修改这些目录里的内容
工作区通过add
把内容放到暂存区
我们的暂存区和最后通过commit
提交其实都在我们刚才看到的git目录里
2.1.1 Git config
三种类型: 全局,系统,本地
--global use global config file
--system use system config file
--local use repository config file
每个级别的配置可能重复,但是低级别的配置会覆盖高级别的配置
系统 > 全局 > 本地
2.1.2 常见git配置(重要)
- 用户名配置
git config --global user.name "xxxx"
这个命令是用来配置Git的全局用户名称(user.name)。当你在Git提交代码时,Git会记录下提交者的信息,包括用户名和电子邮件地址。通过设置全局用户名称,你可以指定你在提交代码时所使用的用户名。
- Instead of 配置
- 别名
2.2 git remote和远端
查看
git remote -v
添加
git remote add origin_ssh git@github.com:git/git.git
这个命令是用来将一个远程仓库与你的本地仓库关联起来。它通过一个简短的名字(origin_ssh)来代表远程仓库的地址。
在这个命令中,origin_ssh
是一个自定义的远程仓库名称,你可以根据需要进行修改。git@github.com:git/git.git
是远程仓库的地址,它遵循SSH协议的格式。
具体来说,git@github.com
是GitHub的主机名,它指示你将要将你的本地仓库关联到GitHub上。git/git.git
是远程仓库的路径,它指示你要关联的具体仓库。这个路径可以因你要关联的仓库而有所不同。
执行这个命令后,你的本地仓库就会和远程仓库建立起连接。这样你就可以使用Git命令来推送(push)和拉取(pull)代码到远程仓库,并与其他开发者进行协作。通常情况下,你只需要执行这个命令一次,以后就可以使用关联的远程仓库进行代码交互。
git remote add origin_http git@github.com:git/git.git
同一个origin设置不同的push和fetch url
比如说我希望从远端仓库拉取代码然后推送到我自己的仓库里
git remote add origin git@github.com:git/git.git
git remote set-url --add --push origin git@github.com:my_repo/git.git
也可以直接用vim
去改
2.2.1 HTTP remote
URL: https://github.com/git/git.git
正常来说不推荐用http,没那么安全,还是会使用ssh
2.2.2 SSH remote
URL: git@github.com:git/git.git
两种配置都有免密配置
ssh: 优先使用ed25519
可以把这个public的key复制出来存到github上
当你在GitHub上添加新的SSH密钥时,它会提供以下几个作用:
-
认证与授权:通过将SSH公钥添加到你的GitHub帐户中,你可以使用私钥进行身份验证,以证明你是该帐户的所有者。这样,你就可以执行与你帐户相关的操作,如克隆、推送和拉取代码等。
-
安全连接:SSH密钥通过使用公钥加密和私钥解密的方式,确保了数据在传输过程中的安全性。当你使用SSH协议与GitHub进行通信时,数据将被加密,以防止未经授权的访问或数据篡改。
-
简化访问:一旦你将SSH密钥添加到GitHub中,你就可以通过SSH协议轻松地与GitHub进行通信,而无需每次都输入用户名和密码。这样可以提高工作效率并提供更方便的访问方式。
-
多设备共享:通过将SSH密钥添加到GitHub中,你可以在多个设备上轻松地访问和管理你的代码库。这意味着你可以在不同的计算机或服务器上使用私钥,而无需每次都生成新的密钥对。
总之,通过添加新的SSH密钥,你可以在GitHub上进行身份验证、建立安全连接、简化访问并方便地在多个设备上共享代码。这为你提供了更方便、更安全的代码管理和协作环境。
2.3 git add
这里我们新建一个文档,然后我们看git发现没什么变化
这是git add
之前和之后的git status
的变化
然后我们对readme进行修改,添加一行hello world
进去,再add
就可以用git cat-file -p <object id>
来看出区别
2.4 git commit
git commit -m "add readme"
再观察一下.git这个目录
为什么会多两个文件呢
blob(目录树)
在Git中,Blob(Binary Large Object)对象用来表示文件内容的快照。每个文件在Git中都被存储为一个独立的Blob对象。
Blob对象保存着文件的数据,它们是Git存储中的基本数据单元。每个Blob对象都有一个唯一的哈希值,用于在Git中进行引用和查找。
Blob对象的作用包括:
-
文件内容存储:Blob对象保存了文件的实际内容。它们充当了文件的快照,记录了特定版本的文件数据。
-
内容比较和查找:Git使用Blob对象来比较文件的内容是否发生了更改,从而确定哪些部分需要在提交中进行保存。Blob对象的哈希值还用于快速查找特定文件版本。
-
文件版本控制:Blob对象是Git进行版本控制的基础。通过记录文件内容的不同版本的Blob对象,Git可以轻松地进行版本回溯、分支合并等操作。
总之,Blob对象在Git中扮演着关键的角色,用于存储和管理文件的内容。它们使得Git能够高效地跟踪文件的修改历史,并提供强大的版本控制功能。
commit信息
还有一个可以结合git log
一起看
2.5 objects
commit/ tree / blob 在git里面统称为object,除此之外还有个tag的object
- blob: 存储文件内容
- tree:存储文件的目录信息
- commit: 提交信息
如何把这三个信息串联在一起呢?
- 通过commit寻找tree信息, 每个commit都会存储对应的tree id
- 通过tree存储的信息,获取对应的目录树信息 (可能存在多个blob)
- 从tree中获得blob的id,通过blob id获取对应的文件内容
如下所示:
2.6 refs
刚才我们的操作也修改了ref目录下面的内容
显示了我们的commit id
新建一个分支,用git checkout -b test
,我们会发现和main分支的内容是一样的
ref文件储存的内容
内容就是对应的commit id
因此把ref当做指针,指向对应的commit来表示当前ref对应的版本
不同种类的ref
- ref/heads 表示的是分支
- ref/tags 表示的是标签
branch
用于开发阶段,可以不断添加commit进行迭代,是会变化的
tag
表示的是一个稳定的版本,指向的commit一般不变
git tag v0.0.1
2.7 annotation tag
一种特殊的tag,可以给tag提供一些额外的信息
git tag -a v0.0.2 -m "add feature 1"
会发现它指向不同的object,并且有了一些额外的信息例如,是谁添加的tag
这里的object就是我们第四种object
追溯历史版本
获取当前版本代码
通过ref指向的commit可以获取唯一的代码版本
获取历史版本代码
commit里面会存有parent commit字段,通过commit的串联获取历史版本代码
回到我们刚才的md文件,修改文件添加一个#号,再add和commit
我们会发现多了三个文件,一个blob,一个commit,一个tree
看一下:
我们会发现我们的blob的id变了,因为我们修改了文件,这个时候访问这个blob id对应的文件就会变成我们更新的文件
这个时候我们看我们的test ref也指向新的commit
2.9 修改历史版本
- commit --amend
通过这个命令可以修改最近一次commit的信息,修改之后commit id会变
如下所示,我们改commit信息添加1111
并且,操作新增了一个commit object,老的并没有删除
- rebase
通过git rebase -i HEAD~3 可以实现对最近三个commit的修改:
- 合并 commit
- 修改具体的commit message
- 删除某个commit
- filter --branch
该命令可以指定删除所有提交中的某个文件或者全局修改邮箱地址等操作
2.10 object
上述操作修改了ref指向的commit,但是之前的commit没有被删掉,所以我们引出一个概念叫悬空object
用git fsck --lost-foundgit fsck --lost-found
查看
新的问题: 我们肯定想删掉这些多余的commit
2.11 git gc
因为我们发现,git的很多操作会新生成很多文件, git优化后我们可以处理掉
GC
用git gc命令,可以删除一些不需要的object
依旧会对object进行一些打包压缩来减少仓库的体积
reflog
reflog 适用于记录操作日志,防止误操作后数据丢失
通过reflog来找丢失的数据,手动将日志设置为过期
指定时间
git gc prune = now 指定的是修剪多久之前的对象,默认是两周前
git reflog expire --expire=now --all
git gc --prune=now
我们发现去掉了很多没用的文件,并把之前的东西打包了
2.12 完整的git视图
很多ref, branch或者tag, tag可能是附注标签,指向一个tag,每个commit都会有一个tree和blob,每个commit都会有一个仓库
2.13 git clone & pull & fetch
clone
拉取完整的仓库到本地目录,可以指定分支,深度
fetch
将远端某些分支最新的代码拉取到本地,不会执行merge操作
会修改refs/remote内的分支信息,如果需要和本地代码合并需要手动操作
pull
拉取远端某分支,并和本地代码进行合并,操作等于git fetch + git merge
, 也可以通过 git pull --rebase
完成git fetch + git rebase
操作
可能存在冲突,需要解决冲突
2.14 git push
常用命令
git push origin main
常见问题
- 为什么我明明配置了git配置,但是依然没有办法拉取代码
- 免密认证没有配
- instead of配置没有配,配的ssh免密配置,但是使用的还是http协议访问
- 为什么我fetch了远端分支,但是我看本地当前的分支历史还是没有变化
- fetch会把代码拉取到本地的远端分支,但是并不会合并到当前分支,所以当前分支历史没有变化, 要手动merge或者rebase
Git 研发流程
03常见问题
- 在gerrit平台上使用merge的方式合代码
- 不了解保护分支,code review, ci等概念,研发流程不规范
- 代码历史混乱,合并方式不清晰
3.1 不同的工作流
类型 | 代表平台 | 特点 | 合入方式 |
---|---|---|---|
集中式工作流 | Gerrit/ svn | 只依托于主干分支进行开发,不存在其他分支 | fast-forward |
分支管理工作流 | github/ gitlab | 可以定义不同特性的开发分支,上线分支,在开发分支完成开发后再通过MR/PR合入主干分支 | 自定义,fast—forward or three-way merge都可以 |
3.2 集中式工作流
只依托于main分支进行研发活动
工作方式
- 获取远端main代码
- 直接在main上完成修改
- 提交前拉取最新的代码和本地的代码合并,并解决冲突
- 提交
3.2.1 集中式工作流- Gerrit
安卓开发用的多
基本原理
- 依托于 change id概念
- 提交上去的代码要review
优点
- 提供强制的代码评审机制,保证代码的质量
- 提供更丰富的权限功能,可以针对分支权限的管控
- 保证main历史的整洁性
缺点
- 开发人员较多会有冲突
3.3 分支管理工作流
分支管理工作流 | 特点 |
---|---|
git flow | 分支类型丰富,规范严格 |
github flow | 只有主干分支和开发分支,规则简单 |
gitlab flow | 在主干分支和开发分支上构建环境分支,版本分支,满足不同发布or环境需要 |
3.3.1 分支管理工作流- gitflow
早期出现的分支管理策略
五种类型分支:
- matser
- develop
- feature
- release
- hotfix
优点:
- 代码会很清晰
缺点:
- 流程复杂
3.3.2 github flow
只有一个主干分支,基于pull request往主干分支中提交代码
选择团队合作的方式
- owner创建好仓库后,其他用户通过fork的方式来创建自己的仓库,并在fork的仓库上进行开发
- owner创建好仓库后,统一给团队内成员分配权限,直接在同一仓库内进行开发
我们按照第二种方式来创建一个仓库:
- new 一个repository
- 复制ssh的key
- 在本地
git clone git@github.com:Bruce-XUZILIN/demo.git
- 查看tree,里面什么都没没有
- 新建一个readme,add再commit再push
新切一个feature分支,修改readme文件,再push
这里面多了个http的链接,打开就会有pull request
create pull request之后再merge,就会发现main分支上更新了我们修改的内容
之后,我们切回main分支,再运行git pull origin main
拉取最新的内容
我们再看git log会发现多了一个commit
可以去branch设置一些保护分支的规范
3.3.2 gitlab flow
在gitflow 和 github flow上做出优化,既保持了单一住分支的渐变,又可以适应不同的开发环境
原则:upstream first 上游优先
只有在上游分支才拿的代码才可以进入到下游分支,一般上游分支就是main
3.4 代码合并
fast-forward:
git merge test --ff-only
threeway(会生成一个merge节点):
git merge test --no-ff
3.5 如何选择合适的工作流
小型团队合作: github
- 少量滴哦次
- 提交pull request最少保证cr后再merge
- 主干分支整洁,ff的方式合并,合并前rebase
常见问题
- 在gerrit平台上使用merge的方式合代码: 不推荐
- 不了解保护分支,code review, ci等概念,研发流程不规范
- 代码历史混乱,合并方式不清晰
欢迎使用Markdown编辑器
你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。
新的改变
我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:
- 全新的界面设计 ,将会带来全新的写作体验;
- 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
- 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
- 全新的 KaTeX数学公式 语法;
- 增加了支持甘特图的mermaid语法1 功能;
- 增加了 多屏幕编辑 Markdown文章功能;
- 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
- 增加了 检查列表 功能。
功能快捷键
撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
检查列表:Ctrl/Command + Shift + C
插入代码:Ctrl/Command + Shift + K
插入链接:Ctrl/Command + Shift + L
插入图片:Ctrl/Command + Shift + G
查找:Ctrl/Command + F
替换:Ctrl/Command + G
合理的创建标题,有助于目录的生成
直接输入1次#,并按下space后,将生成1级标题。
输入2次#,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用TOC
语法后生成一个完美的目录。
如何改变文本的样式
强调文本 强调文本
加粗文本 加粗文本
标记文本
删除文本
引用文本
H2O is是液体。
210 运算结果是 1024.
插入链接与图片
链接: link.
图片:
带尺寸的图片:
居中的图片:
居中并且带尺寸的图片:
当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。
如何插入一段漂亮的代码片
去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片
.
// An highlighted block
var foo = 'bar';
生成一个适合你的列表
- 项目
- 项目
- 项目
- 项目
- 项目1
- 项目2
- 项目3
- 计划任务
- 完成任务
创建一个表格
一个简单的表格是这么创建的:
项目 | Value |
---|---|
电脑 | $1600 |
手机 | $12 |
导管 | $1 |
设定内容居中、居左、居右
使用:---------:
居中
使用:----------
居左
使用----------:
居右
第一列 | 第二列 | 第三列 |
---|---|---|
第一列文本居中 | 第二列文本居右 | 第三列文本居左 |
SmartyPants
SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:
TYPE | ASCII | HTML |
---|---|---|
Single backticks | 'Isn't this fun?' | ‘Isn’t this fun?’ |
Quotes | "Isn't this fun?" | “Isn’t this fun?” |
Dashes | -- is en-dash, --- is em-dash | – is en-dash, — is em-dash |
创建一个自定义列表
-
Markdown
- Text-to- HTML conversion tool Authors
- John
- Luke
如何创建一个注脚
一个具有注脚的文本。2
注释也是必不可少的
Markdown将文本转换为 HTML。
KaTeX数学公式
您可以使用渲染LaTeX数学表达式 KaTeX:
Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n−1)!∀n∈N 是通过欧拉积分
Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=∫0∞tz−1e−tdt.
你可以找到更多关于的信息 LaTeX 数学表达式here.
新的甘特图功能,丰富你的文章
- 关于 甘特图 语法,参考 这儿,
UML 图表
可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图:
这将产生一个流程图。:
- 关于 Mermaid 语法,参考 这儿,
FLowchart流程图
我们依旧会支持flowchart的流程图:
- 关于 Flowchart流程图 语法,参考 这儿.
导出与导入
导出
如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。
导入
如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。
注脚的解释 ↩︎