Skip to content

Git

简介

Git 和其它版本控制系统(包括 Subversion 和近似工具)的主要差别在于 Git 对待数据的方式。 从概念上来说,其它大部分系统以文件变更列表的方式存储信息,这类系统(CVS、Subversion、Perforce 等等) 将它们存储的信息看作是一组基本文件和每个文件随时间逐步累积的差异 (它们通常称作 基于差异(delta-based) 的版本控制)。

deltas

存储每个文件与初始版本的差异

Git 不按照以上方式对待或保存数据。反之,Git 更像是把数据看作是对小型文件系统的一系列快照。 在 Git 中,每当你提交更新或保存项目状态时,它基本上就会对当时的全部文件创建一个快照并保存这个快照的索引。 为了效率,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。 Git 对待数据更像是一个 快照流。

snapshots

存储项目随时间改变的快照

  • Workspace: 工作区
  • Index / Stage: 暂存区
  • Repository: 仓库区 ( 本地版本库 )
  • Remote: 远程仓库 ( 远程仓库 / 远程版本库 )

workflow

Git 工作流程

开始使用

创建新仓库:

git init

克隆现有仓库:

git clone <url>

准备提交

添加未跟踪文件或未暂存的更改:

git add <file>

添加所有未跟踪文件和未暂存的更改:

git add .

选择要暂存的文件部分:

git add -p

移动文件:

git mv <old> <new>

删除文件:

git rm <file>

让 Git 忘记某个文件但不删除它:

git rm --cached <file>

取消暂存一个文件:

git reset <file>

取消暂存所有内容:

git reset

检查你添加的内容:

git status

创建提交

创建提交(并打开文本编辑器编写消息):

git commit

创建提交:

git commit -m 'message'

提交所有未暂存的更改:

git commit -am 'message'

在分支间移动

切换分支:

git switch <name>



git checkout <name>

创建分支:

git switch -c <name>



git checkout -b <name>

列出分支:

git branch

按最近提交时间列出分支:

git branch --sort=-committerdate

删除分支:

git branch -d <name>

强制删除分支:

git branch -D <name>

比较已暂存/未暂存的更改

比较所有已暂存和未暂存的更改:

git diff HEAD

仅比较已暂存的更改:

git diff --staged

仅比较未暂存的更改:

git diff

比较提交

显示提交与其父提交之间的差异:

git show <commit>

比较两个提交:

git diff <commit> <commit>

比较自某个提交以来一个文件的变化:

git diff <commit> <file>

显示差异摘要:

git diff <commit> --stat

git show <commit> --stat

引用提交的方式

每次我们说 `<commit>` 时,你可以使用以下任何一种:
☆ a branch          main
☆ a tag             v0.1
☆ a commit ID       3e887ab
☆ a remote branch   origin/main
☆ current commit    HEAD
☆ 3 commits ago     HEAD^^^ 或 HEAD~3

丢弃你的更改

删除一个文件的未暂存更改:

git restore <file>



git checkout <file>

删除一个文件的所有已暂存和未暂存更改:

git restore --staged --worktree <file>



git checkout HEAD <file>

删除所有已暂存和未暂存的更改:

git reset --hard

删除未跟踪的文件:

git clean

“储存”所有已暂存和未暂存的更改:

git stash

编辑历史

"重置"最近的提交(保持工作目录不变):

git reset HEAD^

将最后 5 个提交压缩为一个:

git rebase -i HEAD~6

然后将任何你想修正到上一个提交的提交的 "pick" 改为 "fixup"

恢复失败的变基:

git reflog BRANCHNAME

然后在 reflog 中手动找到正确的提交 ID,然后运行:

git reset --hard <commit>

更改提交消息(或添加你忘记的文件):

git commit --amend

查看历史记录

查看分支的历史:

git log main
git log --graph main
git log --oneline

显示修改某个文件的所有提交:

git log <file>

显示修改某个文件的所有提交,包括重命名之前:

git log --follow <file>

查找添加或删除某些文本的所有提交:

git log -G banana

显示谁最后更改了文件的每一行:

git blame <file>

合并分叉的分支

使用变基:

git switch banana
git rebase main

之前:

img

之后:

img

使用合并:

git switch main
git merge banana

之前:

img

之后:

img

使用压缩合并:

git switch main
git merge --squash banana
git commit

之前:

img

之后:

img

使分支与另一个分支保持同步(也称为"快进合并"):

git switch main
git merge banana

之前:

img

之后:

img

挑选提交到当前分支:

git cherry-pick <commit>

之前:

img

之后:

img

恢复旧文件

从另一个提交获取文件的版本:

git checkout <commit> <file>



git restore <file> --source <commit>

添加远程仓库

git remote add <name> <url>

推送你的更改

main 分支推送到远程 origin

git push origin main

将当前分支推送到其远程"跟踪分支":

git push

推送你从未推送过的分支:

git push -u origin <name>

强制推送:

git push --force-with-lease

推送标签:

git push --tags

拉取更改

获取更改(但不更改你的任何本地分支):

git fetch origin main

获取更改然后变基你的当前分支:

git pull --rebase

获取更改然后将其合并到你的当前分支:

git pull origin main



git pull

配置 Git

设置配置选项:

git config user.name 'Your Name'

全局设置选项:

git config --global ...

添加别名:

git config alias.st status

查看所有可能的配置选项:

man git-config

重要文件

本地 git 配置:

.git/config

全局 git 配置:

~/.gitconfig

要忽略的文件列表:

.gitignore

Commit 规范

类型说明示例
feat新增功能 (feature)feat(auth): 添加微信登录功能
fix修复bugfix(payment): 修复支付回调重复通知
docs文档变更docs(api): 更新用户登录接口文档
style代码格式调整(不影响功能)style(ui): 调整按钮组件的CSS格式
refactor代码重构(非新增功能或修复)refactor(order): 使用策略模式重构优惠券计算
test增加或修改测试test(user): 添加用户注册的单元测试
chore构建过程或辅助工具的变动chore(deps): 升级webpack到v5.0.0
perf性能优化perf(image): 使用懒加载优化首屏图片
revert回滚到之前的版本revert: 回滚用户权限更新代码
build构建系统或外部依赖变更build(npm): 新增对Node 18的支持
ciCI配置和脚本变更ci(github): 添加自动化单元测试流水线

附录

参考

https://git-scm.com/book/zh/v2

https://git-scm.com/cheat-sheet#getting-started