这是我参与「第三届青训营 -后端场」笔记创作活动的的第9篇笔记
Git
分布式版本控制系统
Git的基本使用方式
Git基本命令
Git目录介绍
项目初始化
mkdir 项目名
cd 项目名
git init
(默认分支是master分支)
其他参数
--initial-branch 初始化的分支,指定分支
--bare 创建一个裸仓库(纯Git目录,没有工作目录),不允许添加文件
--template 可以通过模板来创建预先构造好的自定义git目录
tree命令安装
Windows下安装的git bash不支持tree命令,因此需要自己安装tree命令。
- 下载地址:jaist.dl.sourceforge.net/project/gnu…
- 下载后,复制压缩包内bin目录中的tree.exe
- 粘贴到git安装目录 Git\usr\bin 中
Git Config
每个级别的配置可能重复,但是低级别的配置会覆盖高级别的配置
常见Git配置
Git Remote
查看Remote
git remote -v
添加Remote
git remote add origin_ssh git@github.com:git/git.git
git remote add origin_http https://github.com/git/git.git
同一个Origin设置不同的Push和Fetch URL
git remote add origin git@github.com:git/git
git remote set-url --add --push origin git@github.com:MY_REPOSITY/git
HTTP Remote
不推荐,不安全,推荐用SSH
SSH Remote
Git Add
touch readme.md (直接在文件夹创建也行)
vim readme.md
git status
git add .
git status
Objects
commit / tree / blob 在 git 里面都统一称为 Object,除此之外还有个 tag 的 object.
-
Blob
- 存储文件的内容
-
Tree
- 存储文件的目录信息
-
Commit
- 存储提交信息,一个 Commit 可以对应唯一版本的代码
Refs
Refs文件存储的内容
refs的内容就是对应的Commit ID
因此把ref当做指针,指向对应的Commit来表示当前Ref对应的版本。
不同种类的ref
refs/heads前缀表示的是分支,除此之外还有其他种类的ref,比如refs/tags前缀表示的是标签。
Branch
git checkout-b可以创建一个新分支
分支一般用于开发阶段,是可以不断添加 Commit 进行迭代的
Tag
标签一般表示的是一个稳定版本,指向的 Commit 一般不会变更
通过 git tag 命令生成 tag.
Annotation Tag
附注标签
- 一种特殊的Tag,可以给Tag提供一些额外的信息。
如何创建
git tag -a
查看该tag object的内容
git cat-file -p
追溯历史版本
修改历史版本
- commit- amend
- 通过这个命令可以修改最近的一次 commit 信息,修改之后 commit id 会变
- rebase
-
通过 git rebase -i HEAD~3 可以实现对最近三个 commit 的修改:
- 合并 commit
- 修改具体的 commit message
- 删除某个 commit
- filter - branch
- 该命令可以指定删除所有提交中的某个文件或者全局修改邮箱地址等操作
Object
Git GC
GC
通过 git gc命令,可以删除一些不需要的 object,以及会对 object 进行一些打包压缩来减少仓库的体积。
Reflog
reflog 是用于记录操作日志,防止误操作后数据丢失,通过 reflog 来找到丢失的数据,手动将日志设置为过期。
指定时间
git gc prune=now 指定的是修剪多久之前的对象,默认是两周前
Git Clone & Pull & Fetch
Clone
- 拉取完整的仓库到本地目录,可以指定分支,深度。
Fetch
- 将远端某些分支最新代码拉取到本地,不会执行 merge 操作,会修改 refs/remote 内的分支信息,如果需要和本地代码合并需要手动操作。
Pull
- 拉取远端某分支,并和本地代码进行合并,操作等同于 git fetch + git merge,也可以通过 git pull --rebase 完成 git fetch + git rebase 操作。
- 可能存在冲突,需要解决冲突。
Git Push
Push是将本地代码同步之远端的方式。
常用命令
- 一般使用 git push origin master 命令即可完成
冲突问题
- 如果本地的 commit 记录和远端的 commit 历史不一致,则会产生冲突,比如 git commit --amend or git rebase 都有可能导致这个问题。
- 如果该分支就自己一个人使用,或者团队内确认过可以修改历史则可以通过 git push origin master-f 来完成强制推送,一般不推荐主干分支进行该操作,正常都应该解决冲突后再进行推送。
推送规则限制
- 可以通过保护分支,来配置一些保护规则,防止误操作,或者一些不合规的操作出现,导致代码丢失。
Git研发流程
不同的工作流
集中式工作流
只依托于master分支进行研发活动
分支管理工作流
Gitflow
包含五种类型的分支
- Master:主干分支
- Develop:开发分支
- Feature:特性分支
- Release:发布分支
- Hotfix:热修复分支
代码清晰不混乱,但流程过于复杂,上线节奏慢。
Github Flow
只有一个主干分支,基于Pull Request 往主干分支中提交代码。
选择团队合作的方式
- owner 创建好仓库后,其他用户通过 Fork 的方式来创建自己的仓库,并在 fork 的仓库上进行开发
- owner 创建好仓库后,统一给团队内成员分配权限,直接在同一个仓库内进行开发
可以通过进行一些保护分支设置,来限制合入的策略,以及限制直接的push操作。
Gitlab Flow
Gitlab 推荐的工作流是在 GitFlow 和 Github Flow 上做出优化, 既保持了单一主分支的简便,又可以适应不同的开发环境。
原则:upstream first 上游优先
只有在上游分支采纳的代码才可以进入到下游分支, 一般上游分支就是 master.
代码合并
Fast-Forward
不会产生一个 merge 节点,合并后保持一个线性历史,如果 target 分支有了更新,则需要通过 rebase 操作更新 source branch 后才可以合入。
git merge test --ff-only
Three-Way Merge
三方合并,会产生一个新的merge节点
git merge test --no-ff
如何选择合适的工作流
针对小型团队合作,推荐使用Github工作流即可
- 尽量保证少量多次,最好不要一次性提交上千行代码
- 提交 Pull Request 后最少需要保证有 CR 后再合入
- 主干分支尽量保持整洁,使用 fast-forward 合入方式,合入前进行 rebase
实操记录
项目初始化
mkdir demo
cd demo
ls
git init
tree .git
cat .git/HEAD
git remote -h
SSH Remote
git以前下的,可能当时没配置用户名和邮箱,没配置前打不开
Vim基本操作
- 进入vim正常模式后,按
i进入插入模式,输入内容 - 输入完成后,按
Esc退出插入模式 - 输入完成后,按
shift+:进入进入命令模式 - 输入
w保存 - 再次按
shift+:进入命令模式,输入q退出vim编辑器
git add后文件在暂存区,然后commit到git目录里
Refs
创建新分支
创建tag
创建附注标签
查看该tag object的内容
提交新的ommit
修改历史版本
查找悬空的commit
Git gc
Create a new repository
克隆
Push
创建feature分支
Pull request
拉到本地
git checkout main
git pull origin main