这是我参与「第三届青训营 -后端场」笔记创作活动的第2篇笔记。本文主要介绍 Git 的入门到高级的相关概念和操作。
1. Git 是什么?
Git 是一个分布式的版本控制软件。主要的代码托管平台有 Github、Gitlab、Gerrit等。
| 版本控制类型 | 代表性工具 | 解决问题 |
|---|---|---|
| 本地版本控制 | RCS | 本地代码的版本控制 |
| 集中式版本控制 | SVN | 提供一个远端服务器维护代码版本,本地不保存代码版本 |
| 分布式版本控制 | Git | 每个仓库都能记录版本历史信息 |
2. Git 的基本使用方法
用户名和邮箱配置
$ git config --global user.name "xiaoming"
$ git config --global user.email "xiaoming@exmaple.com"
# 三个级别 --global --system --local
仓库初始化
$ git init
# 其他参数
# --initial-branch 指定初始化的分支
# --bare 创建一个裸仓库,纯 Git 目录,没有工作目录
# --template 通过模板创建预先构建好的自定义 Git 目录
添加文件和提交信息
# 所有跟踪文件中被修改过文件和未跟踪文件信息添加到暂存区
$ git add -A
# 将暂存区内容添加到本地仓库中
$ git commit -m "first commit"
工作区、暂存区和版本库
检查当前文件状态
# 状态简览
$ git status -s
# 查看文件的日志信息
$ git log
添加远端分支
$ git remote add origin_ssh git@github.com:git/git.git
$ git remote add origin_http https://github.com/git/git.git
推送到远端分支
$ git push origin_http main
3. Git 的高级操作
.git文件夹中的Object
- Blob:存储文件内容
- Tree:存储文件的目录信息
- Commit:存储提交信息,一个 Commit 可以对应唯一版本的代码
- Tag:附注标签,携带 Tag 相关信息
创建标签
- 轻量标签:不会新建Object
$ git tag v1.0
- 附注标签:会新建Object
$ git tag -a v1.1 -m 'my version 1.1'
回退版本
# --soft 回退到某个版本
$ git reset --soft HEAD
# --mixed 重置暂存区的文件,工作区文件内容保持不变
$ git reset HEAD^ # 回退所有内容到上一个版本
$ git reset HEAD~3 hello.go # 回退 hello.go 文件到上上上一个版本
# --hard 将暂存区与工作区都回到上一次版本
$ git reset --hard 052e
修改历史版本
- commit --amend:通过对之前的 commit 提交进行修改。不仅可以修改提交的内容,还可以修改commit 信息,修改后 commit id 会变。注意:这里的之前指最近的commit,而且没有push到远程。
- rebase:通过 git rebase -i HEAD~3 可以实现对最近三个 commit 的修改:
- 合并 commit
- 修改具体的 commit message
- 删除某个 commit
- filter --branch:该命令可以指定删除所有提交中的某个文件或者全局修改邮箱地址等操作
修剪代码仓库
- 悬空的Object:没有 ref 指向的 object,如commit --amend 就会产生悬空的 Object。
- GC:删除一些不需要的 obejct,以及会对object 进行一些打包压缩来减少仓库体积。
- Reflog:用于记录操作日志,防止误操作后数据丢失,通过 reflog 来找到丢失的数据,手动将日志设置为过期。
- 指定时间:git gc prune-now 指定修剪多久前的对象,默认两周前
# 查看多余的 commit
$ git fsck --lost-found
# 设置日志过期时间
$ git reflog expire --expire=now --all
# 修剪代码仓库
$ git gc --prune=now
合并分支
合并分支就是把其他分支的代码合并到当前的分支中。git会自动将当前分支和要合并的分支找到共同的基点,然后将当前分支的所有变化和要合并分支的变化进行三方合并,并产生一个新的提交,此次提交有两个父提交。
# 切换到主分支
$ git checkout master
# 把dev分支的内容合并到主分支
$ git merge dev
# 如果产生冲突后,先修改文件,去掉冲突的符号
# 最后提交修改到仓库
$ git add .
$ git commit -m '合并冲突'
变基 rebase
rebase 命令将提交到某一分支上的所有修改都移至另一分支上,就好像“重新 播放”一样。翻译成通俗的话: 找到参照的仓库和当前的仓库的相同的提交,然后把当前分支后续的提交挪动到参照仓库的提交的最后,形成一条线性的提交顺序。
$ git checkout experiment
$ git rebase master