Git

Git

Posted by Lbb on June 5, 2022

Git 常用命令速查,按使用场景整理,覆盖安装、配置、仓库、文件操作、分支、版本回滚与排查。

安装

  • Linux
1
2
3
4
# Fedora 上的 yum:
$ sudo yum install git
# Debian 上的 apt-get:
$ sudo apt-get install git
  • Mac:安装 Xcode Command Line Tools(Mavericks 及以后),或从官网下载安装包
  • Windows:从官网下载安装包
  • 版本查询
1
git --version

环境设置

初次运行 Git 前需要配置 user.nameuser.email

Git 有三个配置文件(优先级从高到低):

  • 版本库级别:/.git/config
  • 全局:用户主目录下的 ~/.gitconfig
  • 系统级:/etc/gitconfig
1
2
3
4
5
git config -e                # 编辑当前仓库配置
git config -e --global       # 编辑全局配置
git config -e --system       # 编辑系统配置
git config <section>.<key>   # 读取某个配置
git config <section>.<key> <value>  # 设置某个配置
  • 设置用户名与邮箱
1
2
git config --global user.name "Your Name"
git config --global user.email "email@example.com"
  • 查看配置
1
git config --list
  • 避免 pull 时产生多余的合并提交(用 rebase 代替 merge)
1
git config --global pull.rebase true
  • 颜色高亮
1
2
3
git config --global color.ui true
git config --global color.status auto
git config --global color.branch auto
  • 设置默认编辑器
1
git config --global core.editor vim
  • 设置命令别名
1
2
git config --global alias.ci commit
git config --global alias.co checkout
  • 设置默认合并工具
1
git config --global merge.tool vimdiff
  • 删除配置
1
2
git config --unset --global user.name
git config --unset --global user.email
  • SSH 密钥:生成 RSA 密钥对,将公钥配置到 GitHub
1
2
3
ssh-keygen -t rsa -C "youremail@example.com"
cat ~/.ssh/id_rsa.pub
ssh -T git@github.com   # 验证是否连通

生成的一对密钥中,id_rsa 是私钥(保密),id_rsa.pub 是公钥(填到 GitHub)。

仓库

  • 创建本地版本库
1
2
3
mkdir gittest
cd gittest
git init
  • 克隆远程仓库;--bare--mirror 创建不含工作区的裸版本库
1
2
3
git clone <repository> <directory>
git clone --bare <repository> <directory.git>
git clone --mirror <repository> <directory.git>
  • 关联远程仓库
1
2
git remote add origin git@github.com:lbb4511/Story.git
git push -u origin master   # 首次推送并设置上游跟踪
  • 远程仓库管理
1
2
3
4
5
git remote -v                # 查看远程仓库及 URL
git remote show origin       # 查看远程详情(分支、跟踪关系)
git remote rename origin upstream   # 重命名远程
git remote set-url origin <new-url> # 修改远程 URL
git remote remove origin     # 删除远程
  • 拉取 / 推送
1
2
3
4
5
git pull origin master    # 从远程拉取并合并到当前分支
git fetch origin          # 只拉取远程更新,不合并
git push origin master    # 推送本地提交到远程
git push --tags           # 推送所有标签
git push --force-with-lease origin master  # 安全强推(拒绝覆盖他人新提交)

git push --force 会直接覆盖远程历史,协作时慎用;--force-with-lease 只有在远程自上次 fetch 后没有新增提交时才允许强推,更安全。

  • 推送被拒绝:原因是远程仓库和本地不同步,需先拉取合并再推送
1
2
3
git fetch origin
git merge origin/master
git push origin master

更简单的做法是直接 git pull origin master(等价于 fetch + merge)。

文件操作

  • 添加(git add)
1
2
3
4
5
git add <file>    # 添加文件到暂存区
git add .         # 递归添加当前目录所有文件
git add -u        # 添加已跟踪文件的改动(含删除和修改)
git add -A        # 添加所有改动(已跟踪 + 未跟踪)
git add -i        # 交互式添加
  • 删除(git rm)

rm 只删除工作区文件;git rm 会把删除动作加入暂存区,提交后真正删除文件。

1
2
git rm <file>     # 删除文件
git rm -r <dir>   # 递归删除目录
  • 移动或重命名(git mv)
1
git mv <old> <new>
  • 忽略文件(.gitignore):在仓库根目录创建 .gitignore,写入规则即可让 Git 忽略对应文件,常用规则示例:
1
2
3
4
5
*.log
node_modules/
build/
.env
!.env.example

常用操作:

1
2
git check-ignore <file>   # 检查某文件是否被忽略,输出匹配到的规则
git rm -r --cached <dir>  # 移除已跟踪文件但仍保留本地文件(加 ignore 后需执行一次)
  • 清除(git clean):删除本地多余的未跟踪文件与目录
1
2
git clean -nd     # 预删除,显示将要删除的内容
git clean -fd     # 强制删除多余的文件和目录
  • 查看状态(git status)
1
2
git status      # 查看工作区与暂存区状态
git status -s   # 简短输出
  • 查看差异(git diff)

git diff

1
2
3
4
5
git diff              # 工作区与暂存区差异
git diff <file>       # 查看某文件本次修改内容
git diff HEAD         # 工作区与 HEAD 的差异
git diff --cached     # 暂存区与 HEAD 的差异
git diff <id1> <id2>  # 两次提交之间的差异
  • 提交(git commit)
1
2
3
4
git commit -m "提交描述"      # 提交
git commit -am "提交描述"     # add + commit 一步完成
git commit --amend           # 修补上一次提交
git commit --allow-empty     # 允许空提交
  • 查看历史(git log)
1
2
3
4
5
6
7
8
git log --oneline             # 简短显示提交
git log --graph               # 图示分支与合并
git log --pretty=raw          # 显示 parent 属性
git log --stat                # 显示每个提交涉及的变动文件
git log -5                    # 最近 5 条
git log -p                    # 显示每个提交的完整差异
git show <commit>             # 查看某次提交详情
git show HEAD@{5}             # 查看当前分支第 5 次之前的状态
  • 过滤历史提交
1
2
3
4
5
6
git log --author="名字"       # 按作者过滤
git log --since="2 weeks ago" # 按时间过滤(--until 为截止时间)
git log --grep="关键字"       # 按提交信息搜索
git log -S"字符串"            # 按代码内容变更搜索(新增或删除该字符串的提交)
git log -- file              # 只看某个文件的提交历史
git log --oneline --all      # 查看所有分支的提交
  • 按作者统计提交(git shortlog,生成 changelog 常用)
1
2
3
git shortlog                  # 按作者分组统计提交数
git shortlog -sn              # 按提交数排序显示作者统计
git shortlog -sne             # 附带作者邮箱

分支

  • 查看 / 创建 / 删除
1
2
3
4
5
6
7
8
9
git branch                    # 列出本地分支
git branch -a                 # 列出所有分支(含远程)
git branch <name>             # 创建分支
git branch <name> <commit>    # 基于指定提交创建分支
git branch -d <name>          # 删除分支(已合并才允许)
git branch -D <name>          # 强制删除分支
git branch -m <old> <new>     # 重命名分支
git branch --merged           # 显示已合并到当前分支的分支
git branch --no-merged        # 显示未合并到当前分支的分支
  • 切换分支(传统写法)
1
2
git checkout <branch>      # 切换分支
git checkout -b <branch>   # 创建并切换分支
  • 切换分支(现代写法,语义更清晰)
1
2
git switch <branch>        # 切换分支
git switch -c <branch>     # 创建并切换分支
  • 合并(git merge)
1
2
3
git merge <branch>          # 合并分支到当前分支
git merge origin/master     # 合并远程 master 到当前分支
git cherry-pick <commit>    # 挑选某次提交应用到当前分支
  • 变基(git rebase)

git rebase

1
2
git rebase <branch>      # 将当前分支变基到目标分支
git rebase -i <commit>   # 交互式变基(合并、改写提交)

回滚与版本控制

  • 撤销工作区改动(git restore,现代写法)
1
2
3
git restore <file>                 # 用暂存区覆盖工作区
git restore --staged <file>        # 把文件撤出暂存区
git restore --source=<commit> <file>  # 从指定提交恢复文件
  • 传统写法(git checkout –)
1
2
3
git checkout -- <file>     # 用暂存区覆盖工作区文件
git checkout <commit> -- <file>  # 用指定提交覆盖暂存区与工作区
git checkout .             # 丢弃所有本地修改(危险操作)
  • 版本回退(git reset)

git reset

1
2
3
4
git reset --hard <commit>   # 移动 HEAD,重置暂存区和工作区(危险,会丢改动)
git reset --soft <commit>   # 只移动 HEAD,不动暂存区和工作区
git reset --mixed <commit>  # 默认:移动 HEAD 并重置暂存区,保留工作区
git reset HEAD <file>       # 将文件撤出暂存区

提交 ID 可以使用完整 SHA-1,也可以只写前几位。

  • 撤销提交(git revert):新建一个反向提交,保留历史,适合已推送的分支
1
git revert <commit>
  • 找回提交(git reflog):显示所有 HEAD 移动记录,可找回被 reset 掉的提交
1
git reflog
  • 标签(git tag)
1
2
3
4
git tag                    # 列出标签
git tag -a v2.0 -m '描述'  # 打附注标签
git show v2.0              # 查看标签详情
git push --tags            # 推送所有标签

其他常用命令

  • 暂存(git stash):把当前未提交的修改暂存起来,工作区回到干净状态
1
2
3
4
5
git stash                 # 暂存当前修改
git stash list            # 查看暂存列表
git stash show -p stash@{0}  # 查看某次暂存内容
git stash apply stash@{0}    # 应用暂存
git stash pop             # 应用并删除暂存
  • 检索(git grep):搜索文件内容
1
2
git grep 'text'           # 在工作区中搜索
git grep 'text' v1.0      # 在指定版本中搜索
  • 归档(git archive):把某次提交的目录树打包
1
2
3
git archive -o latest.zip HEAD
git archive -o partial.tar HEAD src doc
git archive --format=tar --prefix=1.0/ v1.0 | gzip > foo-1.0.tar.gz
  • 查看 Git 对象(git cat-file)
1
2
git cat-file -t <object>   # 查看对象类型(tree、commit、blob 等)
git cat-file -p <object>   # 查看对象内容
  • 排查仓库(git fsck / git blame)
1
2
git fsck              # 检查仓库完整性
git blame <file>      # 查看文件每行最后修改的提交
  • 二分定位(git bisect):在已知坏提交和好提交之间二分查找引入 bug 的提交
1
2
3
4
5
6
7
8
git bisect start                  # 开始二分
git bisect bad                    # 标记当前提交为坏
git bisect good <commit>          # 标记一个已知的好提交
# Git 会检出中间提交,测试后标记:
git bisect bad                    # 该提交仍坏
git bisect good                   # 该提交正常
# 反复几次后 Git 会定位到首个坏提交;结束时:
git bisect reset                  # 退出二分,回到原分支
  • 补丁工作流(git format-patch / git am):把提交导出为补丁文件,供邮件或他人应用
1
2
3
4
git format-patch -1 <commit>      # 导出某次提交为补丁文件(如 0001-xxx.patch)
git format-patch origin/master    # 导出 origin/master 之后的所有提交
git apply <patch>                 # 应用补丁到工作区(不提交)
git am <patch>                    # 应用补丁并生成提交(保留作者信息)
  • 生成版本号(git describe):基于最近标签生成形如 v1.0-3-gabc123 的描述,CI 版本号常用
1
2
3
git describe               # 最近标签 + 提交数 + 短哈希
git describe --tags        # 使用轻量标签
git describe --abbrev=0    # 只显示最近标签名
  • 稀疏检出(git sparse-checkout):只检出仓库的部分目录,适合超大仓库
1
2
3
4
5
git clone --filter=blob:none --sparse <repository>   # 稀疏克隆(不下载文件内容)
git sparse-checkout set <dir>        # 只检出指定目录
git sparse-checkout add <dir2>       # 追加检出的目录
git sparse-checkout list            # 查看当前检出的目录
git sparse-checkout disable         # 取消稀疏检出,检出全部
  • 子模块(git submodule):在一个仓库中引用其他仓库,保持依赖版本独立
1
2
3
4
5
6
git submodule add <repository> <path>  # 添加子模块
git submodule update --init --recursive  # 检出并初始化子模块(clone 后常用)
git submodule update --remote        # 更新子模块到远程最新提交
git submodule foreach git pull      # 对所有子模块执行命令
git submodule deinit -f <path>      # 取消子模块
git rm -f <path>                    # 移除子模块
  • 多个工作区(git worktree):在不影响当前工作区的情况下,同时检出多个分支到不同目录
1
2
3
4
5
git worktree add <path> <branch>   # 在新目录检出分支,形成一个独立工作区
git worktree add -b <new-branch> <path>   # 基于当前 HEAD 创建新分支并检出
git worktree list                  # 列出所有工作区及其目录、分支
git worktree remove <path>         # 移除工作区(工作区须干净,否则加 -f)
git worktree prune                 # 清理失效工作区记录(目录被手动删除后)

用法示例:修复线上 bug 时不需要 stash 或 clone,只需在另一个目录检出 hotfix 分支,改完合并后删除该工作区即可;所有工作区共享同一个仓库对象库。

命令速查表

配置

命令 注释
git init 初始化本地 git 仓库(创建新仓库)
git config –global user.name “xxx” 配置用户名
git config –global user.email “xxx@xxx.com” 配置邮件
git config –global color.ui true git status 等命令自动着色
git config –unset –global user.name 删除配置
git config –list 查看所有配置
ssh-keygen -t rsa -C “xxx@xxx.com” 生成 SSH 密钥对

仓库

命令 注释
git clone 克隆远程仓库
git remote add origin 增加远程定义(用于 push/pull/fetch)
git remote -v 查看远程仓库及 URL
git remote show origin 查看远程详情
git remote set-url origin 修改远程 URL
git fetch 获取所有远程分支(不更新本地分支,另需 merge)
git fetch –prune 获取所有远程分支并清除服务器上已删掉的分支
git pull origin master 获取远程分支 master 并 merge 到当前分支
git push origin master 将当前分支 push 到远程 master 分支
git push –force-with-lease origin master 安全强推(拒绝覆盖他人新提交)
git push –tags 把所有 tag 推送到远程仓库

文件操作

命令 注释
git status 查看当前版本状态(是否修改)
git status -s 简短输出
git add 添加文件至暂存区
git add . 添加当前子目录下所有更改过的文件至暂存区
git add -u 添加已跟踪文件的改动(含删除和修改)
git add -A 添加所有改动(已跟踪 + 未跟踪)
git commit -m ‘xxx’ 提交
git commit –amend -m ‘xxx’ 合并上一次提交(用于反复修改)
git commit -am ‘xxx’ 将 add 和 commit 合为一步
git rm 删除文件并加入暂存区
git rm -r 递归删除
git mv 移动/重命名文件
git clean -fd 强制删除多余的未跟踪文件和目录
git diff 显示所有未添加至 index 的变更
git diff –cached 显示所有已添加 index 但还未 commit 的变更
git diff HEAD – 比较与 HEAD 版本某文件的差异
git checkout – 用暂存区覆盖工作区文件(丢弃修改)

历史与标签

命令 注释
git log 显示提交日志
git log –oneline –graph 图示提交日志
git log -1 显示 1 行日志,-n 为 n 行
git log –stat 显示提交日志及相关变动文件
git log -p 显示每个提交的完整差异
git log –author=”名字” 按作者过滤
git log –since=”2 weeks ago” 按时间过滤
git log –grep=”关键字” 按提交信息搜索
git log -S”字符串” 按代码内容变更搜索
git log 只看某文件的提交历史
git shortlog -sn 按作者统计提交数
git show 显示某个提交的详细内容(可只用 commitid 前几位)
git show HEAD 显示 HEAD 提交日志
git show HEAD^ 显示 HEAD 的父(上一个版本)的提交日志,^^ 为上两个版本
git show HEAD@{5} 查看第 5 次之前的状态
git tag 显示已存在的 tag
git tag -a v2.0 -m ‘xxx’ 增加附注 tag
git show v2.0 显示 tag 的日志及详细内容

分支与合并

命令 注释
git branch 显示本地分支
git branch -a 显示所有分支
git branch -r 显示所有远程分支
git branch 创建分支
git branch -d 删除分支(已合并到其他分支才允许)
git branch -D 强制删除分支
git branch -m 本地分支改名
git branch –merged 显示所有已合并到当前分支的分支
git branch –no-merged 显示所有未合并到当前分支的分支
git checkout -b 从当前分支创建新分支并检出
git checkout –track / 检出远程分支并创建本地跟踪分支
git checkout 检出版本(tag)
git switch 切换分支(现代写法)
git switch -c 创建并切换分支
git merge 合并分支到当前分支
git cherry-pick 挑选某次提交应用到当前分支
git rebase 变基当前分支

回滚与版本控制

命令 注释
git reset –hard 硬回退:重置引用、暂存区和工作区(危险)
git reset –soft 软回退:只移动 HEAD,不动暂存区和工作区
git reset HEAD 将文件撤出暂存区
git revert 新建反向提交撤销某次提交(保留历史)
git reflog 显示所有提交记录,可找回被 reset 掉的提交
git restore 用暂存区覆盖工作区文件(现代写法)
git restore –staged 把文件撤出暂存区
git stash 暂存当前修改,将所有至为 HEAD 状态
git stash list 查看所有暂存
git stash show -p stash@{0} 查看某次暂存内容
git stash apply stash@{0} 应用暂存
git stash pop 应用并删除暂存

子模块与其他

命令 注释
git submodule add 添加子模块
git submodule update –init –recursive 检出并初始化子模块
git worktree add 在新目录检出分支,形成独立工作区
git worktree list 列出所有工作区
git bisect start 开始二分定位
git format-patch -1 导出提交为补丁文件
git am 应用补丁并生成提交
git describe 基于最近标签生成版本号描述
git sparse-checkout set 稀疏检出,只检出指定目录
git grep “关键字” 文件中搜索文本
git blame 查看文件每行最后修改的提交
git fsck 检查仓库完整性
git gc 压缩仓库,垃圾回收