根据使用场景,汇总列出相应的git指令,便于查阅。主要参考了《Pro Git》。
¶获取帮助
- 仔细查看git给出的输出提示
- 如果不知道下一步应该执行什么命令,不妨试试
git status
- 如果不知道下一步应该执行什么命令,不妨试试
- git [command] -h
- git help [command]
- 在线手册
¶基本概念
- 工作区
- 暂存区(index or stage)
- 版本库(.git目录)
- git是记录文件的快照,而不是差异
- git对象:commit对象、tree对象、blob对象、tag对象
- SHA1
¶获取仓库
| 命令 | 说明 |
|---|---|
| git init | 在当前目录初始化一个空的仓库。 |
| git init --bare | 初始化一个裸仓库。 |
| git clone url | 从服务器克隆一个仓库。 |
| git clone url --bare | 克隆一个裸仓库。 |
| git clone url -b branch | 克隆仓库并切换到指定branch。 |
| git clone url dir | 指定仓库的文件名。 |
¶配置
| 命令 | 说明 |
|---|---|
| git config [–system/–global] | git config默认配置所在的仓库。 –system为系统中所有的用户配置, –global为当前用户的所有仓库配置。 优先级local>global>system。 |
| git config [–system/–global] -e | 打开相应的配置文件,手动编辑。 |
| git config --global user.name “username” | 设置用户名 |
| git config --global user.email “name@host” | 设置邮箱 |
| git config --global core.editor vi | 设置默认的编辑器 |
| git config --global core.autocrlf true | 提交时:回车换行 -> 换行,检出时:换行 -> 回车换行。 windows系统建议设置为true。 |
| git config --global core.autoctlf input | 提交时:回车换行 -> 换行,检出时:不转换。 Linux系统建议设置为input。 |
| git config remote.name.push refs/heads/*:refs/for/* | push代码时,推送到服务器的refs/for分支。name是服务器的名字。 |
| git config --global alias.co checkout | 设置checkout子命令的别名为co |
| git config --global alias.br branch | 设置branch子命令的别名为br |
| git config --global alias.ci commit | 设置commit子命令的别名为ci |
| git config --global alias.st status | 设置status子命令的别名为st |
| git config --global alias.unstage ‘reset HEAD --’ | 设置unstage别名,取消暂存指定文件 git unstage filename |
| git config --global alias.visual ‘!gitk’ | 设置别名调用外部命令,需要添加一个感叹号 |
| git config --global core.quotepath false | 控制路径的显示格式。设置为false,则可以正常显示中文。 |
¶文件状态变化周期
git status查看当前仓库的状态。

¶追踪文件
| 命令 | 说明 |
|---|---|
| git add filename | 将指定文件添加到版本库。 |
| git add . | 将当前目录有修改或未追踪的文件添加到版本库。 |
| git add -A | 将当前仓库有修改或未追踪的文件添加到版本库。 |
| git add -f | 忽略.gitignore文件 |
¶提交修改
| 命令 | 说明 |
|---|---|
| git commit | 将暂存区的内容提交到版本库,会打开默认编辑器编辑提交说明。 |
| git commit -m | 在命令行中指定提交说明,而不是进入编辑器。 |
| git commit --amend | 对最近的一笔提交进行修改(追加修改) |
| git commit -s | 在提交记录中加入“Signed-off-by:” |
| git commit --allow-empty | 允许空白提交 |
| git commit --reset-author | 同步修改作者的ID |
| git commit --amend | 向最后一笔修改追加修改 |
¶查看修改记录
| 命令 | 说明 |
|---|---|
| git log | 按时间先后显示当前分支的提交记录,包含提交ID、作者、时间、提交说明等内容。 |
| git log -p | 显示每次提交修改的内容。 |
| git log --oneline | 一行只显示一个提交,默认包含提交ID和提交说明。 |
| git log --graph | 图形化显示,可以直观显示分支切换和合并,通过与--oneline一起使用。 |
| git log --stat | 显示简略统计信息。 |
| git log -[n] | 仅显示最近的n条提交 |
| git log --after=“2021-06-01” | 查看从2021年6月1日开始的提交 |
| git log --before=“2021-06-01” | 查看从2021年6月1日之前的提交 |
| git log --grep “text” | 仅显示提交说明包含text字符串的提交 |
| git log --author=“author” | 仅显示指定作者的提交 |
| git reflog | 查看本地仓库的操作记录。找回修改的绝妙办法。 |
¶查看修改内容
| 命令 | 说明 |
|---|---|
| git diff | 查看工作区和暂存区的差异 |
| git diff HEAD | 查看工作区和版本库的差异 |
| git diff --cached | 查看暂存区和版本库的差异 |
| git show ref | 查看指定提交的修改内容。ref可以是commit id、tag、分支名等等。 |
¶patch
| 命令 | 说明 |
|---|---|
| git diff > xxx.patch | 如果修改没有提交,使用此方法。 |
| git apply xxx.patch | 应用patch |
| git format-patch -[n] | 将最近n笔提交生成patch文件 |
| git am xxx.patch | 应用format-patch生成的patch文件,会直接产生一笔提交,无需add/commit。 |
¶分支
| 命令 | 说明 |
|---|---|
| git branch | 列出仓库的所有本地分支,当前所在分支会用星号标出来 |
| git branch [-v | -vv] |
| git branch -a | 列出所有分支,包括远程分支,与-v搭配更香 |
| git branch [name] | 创建新分支,指向当前commit |
| git branch [name] [ref] | 在指定commit创建新分支 |
| git checkout [name] | 切换到指定分支,会更改工作区的内容 |
| git checkout -b [name] [ref] | 创建新分支,并切换到新分支。ref可选。 |
| git checkout -b [name] [remote]/[name] | 为远程分支创建本地分支,并追踪远程分支 |
| git branch -u [remote/branch] | 设置当前所在分支的上游分支 |
| git branch -u [remote/branch] [branch] | 设置指定分支的上游分支 |
| git merge [name] | 将指定分支合并到当前分支 |
| git branch -d [name] | 删除已经merge的指定分支。-D强制删除 |
| git push [remote] --delete [name] | 删除远程分支 |
¶tag
| 命令 | 说明 |
|---|---|
| git tag | 列出所有的标签 |
| git tag -l ‘xxx’ | 按照通配符列出匹配的标签 |
| git tag -a [tagname] -m “tag msg” | 在HEAD指向的提交创建附注标签 |
| git tag [tagname] | 在HEAD指向的提交创建轻量标签,不使用-a、-s、-m选项,只需提供标签名字 |
| git tag [tagname] [ref] | 在指定提交创建一个标签 |
| git tag -d [tagname] | 删除指定标签 |
| git push |
推送指定tag到远程服务器 |
| git push |
推送所有tag到远程服务器 |
¶remote
| 命令 | 说明 |
|---|---|
| git remote -v | 查看远程仓库的简写及其对应的URL |
| git remote show |
查看远程仓库更详细的信息 |
| git remote add |
添加一个远程仓库 |
| git remote remove |
删除一个远程仓库 |
| git remote rename |
重命名远程仓库 |
| git fetach |
从远程仓库下载本地没有的数据,不会自动merge |
| git pull |
从远程仓库下载本地没有的数据,并自动merge |
| git push |
将指定分支推送到远程服务器。 默认推送到同名分支,可用冒号指定推送到远程分支 |
| git push |
推送指定tag到远程服务器 |
| git push |
推送所有tag到远程服务器 |
¶选择提交
选择单个提交
- 40个字符的SHA1
- SHA1的前几个字符(至少4个)且没有歧义
- 分支名,分支的最新提交
- tag
- 父提交
- xxxx^:第一父提交
- xxxx^2:第二父提交,仅merge提交才有
- 祖先提交
- xxxx~:第一父提交,等价于xxxx^
- xxxx~~或xxxx~2:第一父提交的第一父提交
提交区间
- 双点:选出在一个分支中而不在另一个分支中的提交
- master…experiment:在 experiment 分支中而不在 master 分支中的提交
- origin/master…HEAD:在当前分支中而不在远程 origin 中的提交
- 三点:两个引用
之一包含但又不被两者同时包含的提交
¶rebase
- 将提交到某一分支上的所有修改都
移至另一分支上 - 变基完成之后,需要快进merge
- 如果提交存在于你的仓库之外,而别人可能基于这些提交进行开发,那么不要执行变基。
| 命令 | 说明 |
|---|---|
| git rebase [basebranch] | 将当前branch的修改都rebase到basebranch |
| git rebase [basebranch] [topicbranch] | 将topicbranch的修改rebase到basebranch |
| git rebase --onto [newbase] [basebranch] [topicbranch] | 相比上一个,rebase的目标分支由–onto选项指定 |
| git rebase -i | 交互式变基,主要功能有改写commit msg、追加修改、重新排序提交、压缩提交、拆分提交。 不要对服务器上的修改进行交互式变基。 |
| git rebase --continue | 继续变基 |
¶cherry-pick
¶reset与checkout
为了更好的理解reset和checkout,首先需要明确,git所有的命令都是操作三棵树。
| 树 | 用途 |
|---|---|
| HEAD | 上一次提交的快照,下一次提交的父结点。该分支上的最后一次提交的快照 |
| Index | 预期的下一次提交的快照 |
| Working Directory | 沙盒 |
| HEAD | Index | Workdir | WD Safe? | 说明 | |
|---|---|---|---|---|---|
| Commit level | |||||
| reset --soft [commit] | REF | NO | NO | YES | 仅移动HEAD分支的指向,不改变暂存区和工作区 撤销commit,回滚到了git commit之前 |
| reset [commit] | REF | YES | NO | YES | 移动HEAD分支的指向,使索引看起来像HEAD,不改变工作区 回滚到了git add和git commit之前 |
| reset --hard [commit] | REF | YES | YES | NO | 移动HEAD分支的指向,使索引看起来像HEAD,强制更改工作目录。 |
| checkout [commit] | HEAD | YES | YES | YES | 移动HEAD自身来指向另一个分支,并更新暂存区和工作区。 |
| File Level | |||||
| reset [commit] – [paths] | NO | YES | NO | YES | 从[commit]复制指定文件到暂存区 |
| checkout [commit] – [paths] | NO | YES | YES | NO | 从指定[commit]复制文件到暂存区和工作区 |
¶实用工具
¶stash
¶clean
¶blame
¶bisect
¶bundle
¶submodule
¶底层命令
| 命令 | 说明 |
|---|---|
| git cat-file -t | |
| git cat-file -p | |
| git rev-parse --show-toplevel | 显示工作区根目录 |
| git rev-parse --show-prefix | 相对于工作区根目录的相对目录 |
| git rev-parse --show-cdup | 显示从当前目录后退到工作区的根的深度 |
| git ls-tree | |
| git ls-files |
¶SHA1的生成方法
¶commit对象
- 计算提交信息包含的字符数
- git cat-file commit HEAD | wc -c
- 在提交信息的前面加上
commit <leng><null>- <leng> 是第一步计算出来的长度
- <null> 是空字符
- (printf “commit <leng>\000”; git cat-file commit HEAD) | sha1sum
¶blob对象
- 计算文件包含的字符数
- git cat-file blob HEAD:filename | wc -c
- 在提交信息的前面加上
blob <leng><null>- <leng> 是第一步计算出来的长度
- <null> 是空字符
- (printf “blob <leng>\000”; git cat-file blob HEAD:filename) | sha1sum
¶tree对象
- 计算tree包含的字符数
- git cat-file tree HEAD^{tree} | wc -c
- 在提交信息的前面加上
tree <leng><null>- <leng> 是第一步计算出来的长度
- <null> 是空字符
- (printf “tree <leng>\000”; git cat-file tree HEAD^{tree}) | sha1sum
¶技巧
¶命令提示符显示分支
在PS1环境变量中加入如下内容,一般是放在\w或\W的后面。
1 | \[\033[36m\]`__git_ps1`\[\033[0m\] |
效果如下:
1 | pk@localhost:blog (master)$ |
在shell执行如下命令,会在~/.bashrc追加一条命令,这条指令会在现有的PS1后面追加__git_ps1。避免了手工修改PS1。
1 | echo 'export PS1="$(echo $PS1 | sed "s/\\\\\\\$[ \t]*$//g")\[\033[36m\]"\`__git_ps1\`"\[\033[0m\]\\$ "' >> ~/.bashrc |