Git 是一个开源的分布式版本控制系统,其本质上是一个内容寻址的 Key-Value 数据库。它有四种类型的存储对象:文件(blob)、树(tree)、提交(commit)、标签(tag),保存在 .git/objects/
目录。如 Blob 对象会先添加头部信息 类型+内容字节数+空字节
,然后计算 SHA 值作为文件名,使用 zlib 压缩成内容,每一次修改的文件都会完整的保存一份快照而非记录差异。这里列举常用的命令行,便于快速查阅使用。
编辑文本文件后,在工作区可以看到修改的差异内容,将改动提交到暂存区后再次编辑,工作区看到的是与暂存区的差异;从暂存区再提交到版本库,版本库由分支和节点组成,可以进行节点切换和分支合并等操作,在本机上已经有了完整的版本控制能力;再提交到远程仓库,解决多人和多主机协作或备份问题,通常搭建内部仓库服务器用 gitlab 或 gitblit,或托管到开源仓库 GitHub。版本操作的四个区域如下:
- 工作区(Working Area)
- 暂存区(Staging Area)
- 本地仓库/版本库(Local Repository)
- 远程仓库(Remote Repository)
Ⅰ、查看
1,查看工作区和暂存区的状态
git status
2,查看工作区和暂存区的变动
git diff <file> # 工作区和暂存区的差异
git diff --cached <file> # 暂存区和本地仓库(上次提交)的差异
3,查看仓库中提交的节点信息
git log --pretty=fuller --stat # 显示详细日志和变动的文件
git log --oneline --graph -5 # 显示精简日志的前5行
4,查看全部分支
git branch -a # 全部分支(包括远程仓库的分支)
git branch -a -v # 全部分支和它们的最新节点
5,查看某个节点的变动
git show <ID> --stat # --stat 表示只显示变动的文件名,而不显示具体内容
6,查看文件的修改历史
git blame <file>
7,查看当前节点的 CommitID(常用编译到Build信息中)
git rev-parse HEAD
git rev-parse --short=10 HEAD # 截取 commitId 中的前 10 位
8,查看 .git/objects/
目录下的文件内容
git cat-file -p <SHA-ID>
Ⅱ、提交
1,从工作区提交到暂存区
git add src/ # 添加 src 目录下全部的文件
git add *.cpp # 添加当前目录下的全部 .cpp 后缀的文件
git add src/*.cpp # 添加 src 目录下全部的 .cpp 后缀的文件
git add . # 添加全部文件
git add -f <file> # 强制添加被 .gitignore 忽略的文件
丢弃暂存区
的文件
git reset HEAD # 使用 HEAD 节点的全部文件重置暂存区(这样两边内容一致没有差异,等同于丢弃)
git reset HEAD <file> # 使用 HEAD 节点的指定文件重置暂存区
git rm --cached <file> # 删除暂存区的指定文件,若是新文件效果同reset,若是之前有提交的老文件暂存区记为删除、工作区记为新增
注:HEAD 节点是当前分支最顶部的提交,也就是最新的一次提交。
丢弃工作区
的文件(未被检索的文件除外)
git checkout -- <file> # 丢弃工作区中指定文件([--] 用于标识文件,避免被误识别为分支等类型)
git checkout HEAD <file> # 丢弃工作区和暂存区中指定文件
git checkout HEAD . # 丢弃工作区和暂存区的全部文件(点[.]表示所有文件,也可以不加)
git reset --hard HEAD # 丢弃工作区和暂存区的全部文件(同上)
丢弃工作区未被检索
的文件
rm <file> # 使用 Linux 命令删除文件
rm -r <file/dir> # 使用 Linux 命令删除文件或文件夹
git clean -f # 强制删除全部文件(-f 代表强制删除,如 config 中有配置 clean.requireforce=false 可以不加)
git clean -df # 强制删除全部文件和文件夹
2,从暂存区提交到本地仓库
git commit -m "xxx" # 提交暂存区中的全部文件
git commit <file1> <file2> -m "xxx" # 提交暂存区中的 file1, file2
git commit -a -m "xxx" # 提交暂存区中的全部文件,和工作区中被修改的文件(未被追踪的文件不会提交)
git commit --amend # 将暂存区中的全部文件提交到上个节点中(修改上节点,适用于本地仓库)
代码提交通常会加的前缀描述:
- feat:添加新功能
- fix:修复Bug
- perf:优化代码性能
- refactor:重构代码
- build:编译打包
- test:更新测试用例
- docs:更新文档
- style:调整代码格式
- chore:更新配置或工具
3,从本地仓库推送到远程仓库
git push
拉取远程仓库的更新
git fetch origin # origin 是远程仓库的名称(单个远程仓库时不需要指定)
git pull # 从远程仓库拉取并合并
配置远程仓库
git remote -v # 查看全部远程仓库
git remote add <repo> <url> # 添加一个远程仓库
git remote get-url <repo> # 查看远程仓库的 url 地址
git remote set-url <repo> <url> # 给远程仓库设置 url
Ⅲ、分支管理
1,切换节点与分支
git checkout <CommitID> # 切换到某个节点(移动 HEAD 节点)
git checkout <branch> # 切换到某个本地分支
git checkout -b <branch> # 切换到某个远程分支(需本地没有该分支)
git checkout -b <branch> <CommitID> # 切换到某个节点,并创建分支
2,合并与变基
git merge <CommitID/branch> # 与某个节点或分支合并(多出合并节点)
git rebase <CommitID/branch> # 在某个节点或分支上,追加当前分支节点
Ⅳ、配置
1,查看和编辑配置
git config --list # 查看全部配置
git config --global --list # 查看全局配置
git config --system --list # 查看系统配置
git config --local --list # 查看本地配置
2,编辑配置
git config --global user.name "xxx" # 设置用户名
git config --global user.email "xxx@domain.com" # 设置邮箱
git config --global --edit # 使用编辑器打开全局配置文件
3,记住账号
git config --global credential.helper store
配置全局(--global
)的凭证,保存在默认的磁盘位置 ~/.git-credentials
,账号会明文存储,格式为 https://user:password@example.com
。这样保存并不安全,如 MacOS 上有提供更安全的 osxkeychain 证书管理,具体参照参照官方文档。下面命令指定缓存在内存中300秒:
git config credential.helper 'cache --timeout=300'
Ⅴ、其它
1,创建和克隆
git init # 在当前目录下创建 Git
git clone <url> # 从远程仓库克隆
git clone --branch dev --depth 1 <url> # 拉取 dev 分支,且浅克隆最后一次提交
2,Stash 贮藏
git stash save "message..." # 保存当前工作区
git stash list # 查看存储列表
git stash show -p stash@{0} # 显示第1个栈的变动
git stash pop stash@{0} # 恢复第1个栈,并删除
使用场景:当你在项目的一部分上已经工作一段时间后,所有东西都进入了混乱的状态, 而这时你想要切换到另一个分支做一点别的事情。问题是,你不想仅仅因为过会儿回到这一点而为做了一半的工作创建一次提交。
3,Hooks 钩子
使用场景:在特定的重要动作发生时触发自定义脚本,可定义在客户端的和服务器端。
4,Repo
Repo 是用于管理多个 Git 项目的工具,使用 Python 在 Git 基础上开发的一系列脚本命令。
5,文档命令
man git
man git-add # 查看 git add 命令用法
git help add # 查看 git add 命令用法
相关资料
- Git教程: https://git-scm.com/book/zh/v2
- 菜鸟教程: https://www.runoob.com/git/git-basic-operations.html
- gitignore: https://github.com/github/gitignore
- 谈谈 Git 存储原理及相关实现: https://zhuanlan.zhihu.com/p/361367094
- 聊聊 Git 的三种传输协议及实现: https://zhuanlan.zhihu.com/p/354043577