这是我参与「第三届青训营 -后端场」笔记创作活动的第1篇笔记
Git 版本控制
1.1 版本控制类型
本地版本控制 RCS
集中式版本控制 SVN
- 提供一个远端服务器来维护代码版本,用户所有提交都提交到该服务器中
- 增量保存每次提交的 Diff,如果提交的增量中和远端现存的文件存在冲突,则需要本地提前解决冲突
- 本地不保存代码版本,所有提交都只能连上服务器后才能提交,如果服务端故障容易导致历史版本丢失
分布式版本控制 Git
- 每个库都存有完整的提交历史,可以直接在本地进行代码提交
- 每次提交记录的都是完整的文件快照,而不是记录增量
-
通过 Push 等操作来完成和远端代码的同步
- Push 其实只是同步,提交是在本地完成
- 对大文件的支持不是特别好(可用 git-lfs 工具弥补)
1.2 Git 发展历史
作者:Linus Torvalds
-
GitHub
全球最大的代码托管平台
-
GitLab
全球最大的开源代码托管平台,项目的所有代码都开源,可以在自己的服务器上搭建 GitLab
-
Gerrit
谷歌开发的平台,Android 项目就托管在 Gerrit 上
Git 基本命令
-
配置
- git config
- git remote
-
提交代码
- git add
- git commit
-
远端同步
-
拉取代码
- clone
- pull
- fetch
-
推送代码
- push
-
常见问题
-
为什么我配置了 Git 配置,但依然没有办法拉取代码
没有密钥,没有权限
- 为什么我 fetch 了远端分支,但是我看本地当前的分支历史还是没有变化
git init 命令
其他参数:
--initial-branch初始化的分支
--bare创建一个裸仓库(纯 Git 目录,没有工作目录,一般在服务器用)
--template可以通过模板来创建预先构建好的自定义 git 目录
目录结构
HEAD 文件内容: ref: refs/heads/master 表示当前指向的分支是 master
git config
不同级别的 git 配置
- global
- system
- local
低级别的配置会覆盖高级别的配置
常见 git 配置
-
用户名配置
- user.name
- user.email
- instead of 配置
- git 命令别名配置
git remote
HTTP remote
免密配置
- 内存
git config --global credential.helper 'cache --timeout=3600'
-
硬盘
git config --global credential.helper "store --file /path/to/credential-file"- 不指定目录的情况默认是
~/.git-credentials
- 不指定目录的情况默认是
- 具体格式
{scheme}://${user}:${password}@github.com
一般不推荐用 HTTP 方式访问 git,因为不安全,一般还是会使用 SSH
SSH remote
URL:git@github.com:git/git.git
ssh-keygen -t ed25519 -C "``saicaca@github.com``"
生成好后查看 pub 文件内容 cat id_ed25519.pub,将其添加到 GitHub 中
Git 命令
touch
命令含义:用于修改文件或者目录的时间属性,包括存取时间和更改时间。若文件不存在,系统会建立一个新的空白文件。
touch readme.md
add
令 Git 包含某文件
add readme.md
完成上面的操作后 objects 文件夹里会多出来东西(上面的 e6 和 9de…… 连起来就是文件ID)
此时文件是加密的,但通过 cat-file 命令可以看到内容
commit 命令
git commit -m "add readme"
commit 后会多出一些文件,包括目录树、commit 记录等
Objects
commit / tree / blob 统称为 Object,除此之外还有个 tag
-
Blob
存储文件的内容
-
Tree
存储文件的目录信息
-
Commit
存储提交信息,一个 Commit 可以对应唯一版本的代码
refs
refs 的内容就是对应的 Commit ID,可以把 ref 当做指针,指向对应的 Commit 来表示当前 ref 对应的版本
在 refs 下面会多出 test 文件,文件的内容就是 commit 的 ID
两种 ref
-
refs/heads 表示的是分支(branch)
- Branch 是出于开发过程中的,可以不断添加 commit
git checkout -b test
-
refs/tags 表示的是标签
- tags 表示稳定的版本,不会再进行变更
git tag v0.0.1
Annotation Tag
一种特殊的 tag,可以给 tag 提供一些额外的信息
git tag -a v0.0.2 -m "add feature xxx"
这种 tag 文件里的内容不是指向 commit 而是指向一个 object
这个 b487xxx 才是真正指向的 commit object
commit —amend
git commit --amend
在弹出的编辑器中修改保存
注意老的 commit object 并不会被删除,产生悬空的 Object,没有任何 ref 指向,可用 git fsck --lost-found 查找悬空的 Object
Git Clone & Pull & Fetch
如果对代码情况很清楚可以用 Pull,如果不是很清楚会不会有冲突就用 Fetch,在本地做一次 rebase 解决冲突
分支管理工作流
-
Git Flow
- 分支类型丰富,规范严格
-
五种类型
- Master
- Develop
- Feature
- Release
- Hotfix
- 如果按规范执行代码会很清晰,但流程过于复杂,上线过程会比较慢
-
GitHub Flow
- 只有主干分支和开发分支,规则简单
-
GitLab Flow
- 在主干分支和开发分支之上构建环境分支,版本分支,满足不同发布 or 环境的需要
这里的工作流只是推荐,并不强制
代码合并
-
Fast-Forward
git merge test --ff-only
-
Three-Way Merge
git merge test --no-ff
在没有指定合并方式时软件会自动选择
如何选择合适的工作流
- 小型团队合作推荐使用 GitHub 工作流
- 大型团队合作根据自己的需要选择不同的工作流
\