<p align="center">
<img src="media/poster.png" width="300" />
<br />
<b>Git常用命令参考手册</b>
<p align="center">基本涵盖了在开发中用到的git命令,能满足日常需求</p>
<p align="center">通俗易懂的例子,30分钟快速入门</p>
<p align="center">
<a href="https://github.com/xjh22222228/git-manual/stargazers"><img src="https://img.shields.io/github/stars/xjh22222228/git-manual" alt="Stars Badge"/></a>
<img src="https://img.shields.io/github/license/xjh22222228/git-manual" />
<a href="https://hits.dwyl.com/xjh22222228/git-manual">
<img src="https://hits.dwyl.com/xjh22222228/git-manual.svg" />
</a>
</p>
</p>
注:2020 年 10 月 GitHub 已将默认分支 `master` 更名为 `main` 分支。
---
# 目录
- [配置](#配置)
- [初始化仓库](#初始化仓库)
- [克隆仓库](#克隆仓库)
- [管理仓库](#管理仓库)
- [暂存文件](#暂存文件)
- [提交文件](#提交文件)
- [推送远端](#推送远端)
- [查看分支](#查看分支)
- [切换分支](#切换分支)
- [创建分支](#创建分支)
- [删除分支](#删除分支)
- [重命名分支](#重命名分支)
- [转移提交](#转移提交)
- [临时保存](#临时保存)
- [文件状态](#文件状态)
- [日志](#日志)
- [责怪](#责怪)
- [合并](#合并)
- [删除文件](#删除文件)
- [还原](#还原)
- [拉取](#拉取)
- [移动-重命名](#移动-重命名)
- [比较文件内容差异](#比较文件内容差异)
- [查看历史提交信息](#查看历史提交信息)
- [回滚版本](#回滚版本)
- [撤销](#撤销)
- [标签](#标签)
- [变基](#变基)
- [工作流](#工作流)
- [子模块](#子模块)
- [子树](#子树)
- [二分查找](#二分查找)
- [归档](#归档)
- [格式化日志](#格式化日志)
- [清空 commit 历史](#清空-commit-历史)
- [帮助](#帮助)
- [提交规范](#提交规范)
- [解决冲突](#解决冲突)
- [仓库迁移](#仓库迁移)
- [奇技淫巧](#奇技淫巧)
- [GUI 客户端](#GUI-客户端)
- [生成 SSH_Key](#生成SSH_Key)
- [其他](#其他)
- [记住密码](#记住密码)
- [清除账号](#清除账号)
- [加速](#加速)
- [思维导图](#思维导图)
## 配置
```bash
# 查看全局配置列表
git config --global -l
# 查看局部配置列表
git config --local -l
# 查看所有的配置以及它们所在的文件
git config --list --show-origin
# 查看已设置的全局用户名/邮箱
git config --global --get user.name
git config --global --get user.email
# 设置全局用户名/邮箱
git config --global user.name "xiejiahe"
git config --global user.email "example@example.com"
# 设置本地当前工作区仓库用户名/邮箱
git config --local user.name "xiejiahe"
git config --local user.email "example@example.com"
# 删除配置
git config --unset --global user.name
git config --unset --global user.email
# 修改默认文本编辑器,比如 nano
# 常用编辑器:emacs / nano / vim / vi
git config --global core.editor nano
# 将默认差异化分析工具设置为 vimdiff
git config --global merge.tool vimdiff
# 编辑当前仓库配置文件
git config -e # 等价 vi .git/config
# 文件权限的变动也会视为改动, 可通过以下配置忽略文件权限变动
git config core.fileMode false
# 文件大小写设为敏感, git默认是忽略大小写
git config --global core.ignorecase false
# 配置 git pull 时默认拉取所有子模块内容
git config submodule.recurse true
# 记住提交账号密码, 下次操作可免账号密码
git config --global credential.helper store # 永久
git config --global credential.helper cache # 临时,默认15分钟
# 设置代理,http或者https
git config --global http.proxy "http://127.0.0.1:8080"
git config --global https.proxy "http://127.0.0.1:8080"
# 取消设置代理,http或者https
git config --global --unset http.proxy
git config --global --unset https.proxy
```
#### 命令别名配置
git 可以使用别名来简化一些复杂命令,类似 [alias](https://github.com/xjh22222228/linux-manual#alias) 命令。
```bash
# git st 等价于 git status
git config --global alias.st status
# 如果之前添加过,需要添加 --replace-all 进行覆盖
git config --global --replace-all alias.st status
# 执行外部命令, 只要在前面加 ! 即可
git config --global alias.st '!echo hello';
# 加 "!" 可以执行外部命令执行一段复杂的合并代码过程,例如:
git config --global alias.mg '!git checkout develop && git pull && git merge main && git checkout -';
# 删除 st 别名
git config --global --unset alias.st
```
#### 配置代理
```bash
# 设置
git config --global https.proxy http://127.0.0.1:1087
git config --global http.proxy http://127.0.0.1:1087
# 查看
git config --global --get http.proxy
git config --global --get https.proxy
# 取消代理
git config --global --unset http.proxy
git config --global --unset https.proxy
```
## 初始化仓库
`git init` 创建一个空的 Git 仓库或重新初始化一个现有的仓库
实际上 `git init` 命令用得不多,通常在 GUI 上进行操作。
```bash
# 会在当前目录生成.git
git init
# 以安静模式创建,只会打印错误或警告信息
git init -q
# 在当前目录下创建一个裸仓库,里面只有 .git 下的所有文件
git init --bare
```
## 克隆仓库
```bash
# https 协议克隆
git clone https://github.com/xjh22222228/git-manual.git
# SSH 协议克隆
git clone git@github.com:xjh22222228/git-manual.git
# 克隆指定分支, -b 指定分支名字,实际上是克隆所有分支并切换到 develop 分支上
git clone -b develop https://github.com/xjh22222228/git-manual.git
# --single-branch 完全只克隆指定分支
git clone -b develop --single-branch https://github.com/xjh22222228/git-manual.git
# 指定克隆后的文件夹名称
git clone https://github.com/xjh22222228/git-manual.git git-study # 如果后面是 . 在当前目录创建
# 递归克隆,如果项目包含子模块就非常有用
git clone --recursive https://github.com/xjh22222228/git-manual.git
# 浅克隆, 克隆深度为1, 只克隆指定分支且历史记录只保留最后一条, 通常用于减少克隆时间和项目大小
git clone --depth=1 https://github.com/xjh22222228/git-manual.git
git clone --depth=1 --no-single-branch https://github.com/xjh22222228/git-manual.git # --no-single-branch 同时克隆其他所有分支
# 裸克隆, 没有工作区内容,不能进行提交修改,一般用于复制仓库
git clone --bare https://github.com/xjh22222228/git-manual.git
# 镜像克隆, 也是裸克隆, 区别于包含上游版本库注册
git clone --mirror https://github.com/xjh22222228/git-manual.git
```
#### 克隆指定文件夹
有些仓库会包含 客户端、服务端、等多个端的代码, 但又不想完整克隆整个项目, 只想克隆某个文件夹,这个时候就需要用到 `稀疏检出`。
开启稀疏检出必须满足 2 个条件:
- `core.sparsecheckout` 设置为 true
- `.git/info/sparse-checkout` 文件列出要检出的目录列表
本仓库有个 `media` 文件夹,用它来演示吧。
```bash
# 1、创建一个目录并进入
mkdir hello-git && cd hello-git
# 2、初始化仓库
git init
# 3、设置仓库地址
git remote add origin https://github.com/xjh22222228/git-manual.git
# 4、开启稀疏检出功能
git config core.sparsecheckout true
# 5、编辑 .git/info/sparse-checkout 文件, 默认是没有需要手动新建
# 也可以通过命令将需要检出的目录路径写入追加进去
echo "media" >> .git/info/sparse-checkout
# 6、拉取内容, 这里指定的是 mater 分支
git pull origin main
```
<details>
<summary>演示克隆指定文件夹.gif</summary>
<img src="media/gitclone-sparsecheckout.gif">
</details>
## 管理仓库
`git remote` 命令用来管理远程仓库。
通常一个项目对应多个仓库就需要用到 `git remote`, 比如要推送到 `git