📋 核心要点
  • 三个核心区域:工作区(workspace)→ 暂存区(index/stage)→ 版本库(repository/.git),远程是 remote
  • git add 入暂存区,git commit 入本地库,git push 上远程;git pull = fetch + merge
  • 撤销分三档:--soft(保留暂存)、--mixed(撤销暂存、保留工作区)、--hard(全部丢弃)
  • git config --global 配用户与别名;git log / git branch / git tag 分别查提交、分支、标签
  • 子模块用 git submodule add/update --init --recursive 管理嵌套仓库

1. 基本名词

  • master:默认开发分支
  • origin:默认远程版本库
  • index / stage:暂存区
  • workspace:工作区
  • repository:本地仓库
  • remote:远程仓库

2. 基本概念

  • 工作区:在电脑中能看到的目录
  • 暂存区(stage/index):一般存放在 .git 目录的 index 文件中
  • 版本库:工作区的 .git 目录就是 git 的版本库

git_base.png

.git 版本库目录结构:

Bash
.git
├── branches
├── config       # 当前仓库配置(远程 url、分支等)
├── description  # 仓库描述信息
├── FETCH_HEAD   # 指向当前从远程拉取到的最后一个版本
├── HEAD         # 当前分支引用,内容为 `ref: refs/heads/branchName`
├── hooks        # 一些 shell 脚本
├── index        # 暂存区(二进制),第一次 git add 时生成,每条索引含 SHA-1、文件名、模式、权限、合并状态、时间戳等
├── info         # 仓库信息,可全局忽略文件(也可写入根目录 .gitignore)
   └── exclude
├── logs         # 提交日志
   ├── HEAD     # 当前分支的提交日志
   └── refs
├── modules
   └── themes
├── objects      # 所有文件对象
   ├── info
   └── pack
├── ORIG_HEAD    # 远程仓库最后一次记录状态
├── packed-refs  # clone 仓库时的所有引用
└── refs
    ├── heads    # 本地分支
    ├── remotes  # 远程分支
    └── tags     # 标签

3. 基本命令

命令解释
git config配置 git 基本信息
git init将当前目录初始化为空仓库,创建 .git 目录
git status显示文件状态:红色=已修改未提交,绿色=已暂存
git add将文件从工作区添加到暂存区
git commit将暂存区修改提交到本地仓库,生成 commit-id
git pull拉取远程分支更新并与本地指定分支合并
git fetch取回远程所有分支更新,记录在 .git/FETCH_HEAD
git push将本地分支更新推送到远程主机
git branch分支管理
git checkout创建/切换分支,撤销工作区修改
git tag标签管理
git log查看历史提交记录
git reset撤销暂存区修改或本地仓库提交
git remote管理远程仓库
git merge合并分支
git stash暂存当前修改以便切换分支
.gitignore忽略无需提交的文件

4. 基本操作

新建代码仓库

Bash
# 在当前目录新建 Git 仓库
git init
# 新建目录并初始化为 Git 仓库
git init [project-name]
# 克隆项目及整个历史
git clone [url]           # 支持 https 和 ssh 两种方式
# 递归克隆主项目与全部子项目到指定目录
git clone [url] ./test_dir --recursive

基本配置

Bash
# git 版本更新(Windows)
git update-git-for-windows
# 查看当前配置
git config --list
# 编辑配置文件(--global 为全局配置,只配当前目录则不加)
git config -e --global
# 设置用户信息
git config --global user.name "name"
git config --global user.email "email address"
# 查看单个配置项
git config user.name
git config user.email
# 定义别名(非必要)
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.br branch

文件的增删改

Bash
# 查看文件状态
git status
git status -s   # 极简方式显示状态
# 状态缩写含义:
#   A 本地新增文件(服务器上没有)
#   C 文件的新拷贝
#   D 本地删除文件(服务器上还在)
#   M 修改(红色=未暂存,绿色=已暂存)
#   R 文件名被修改
#   T 文件类型被修改
#   U 文件未合并
#   X 未知状态
#   ? 未被 git 管理

# 暂存当前修改,便于切换到其他分支
git stash

# 查看变更详情
git diff                # 尚未缓存的改动
git diff --cached       # 已缓存的改动
git diff HEAD           # 已缓存 + 未缓存的所有改动
git diff --stat         # 只显示摘要

# 添加到暂存区
git add [file1] [file2]...   # 指定文件
git add [dir]                # 指定目录(递归)
git add .                    # 当前目录所有文件
git add --all                # 所有文件
git add *.c                  # 所有 .c 文件
git add --update             # 已跟踪文件

# 删除工作区文件并放入暂存区
git rm [file1] [file2]...
# 停止追踪但文件保留在工作区
git rm --cached [file]
# 改名并放入暂存区
git mv [file-original] [file-renamed]

代码提交

Bash
# 提交暂存区到仓库
git commit -m 'commit message'
# 提交暂存区指定文件
git commit [file1] [file2]... -m 'commit message'
# 跳过暂存,直接提交工作区自上次 commit 之后的变化(相当于 git add . + git commit)
git commit -a -m 'commit message'
# 提交时显示所有 diff 信息
git commit -v
# 用一次新提交代替上一次(代码没变时用于改写提交信息)
git commit --amend -m 'commit message'
# 重做上一次提交,并纳入指定文件的新变化
git commit --amend [file1] [file2]...

分支管理

Bash
# 查看本地分支
git branch
# 查看本地和远程分支(* 表示当前分支)
git branch -a
# 新建测试分支
git branch test
# 重命名分支
git branch -m test my_test
# 删除分支
git branch -d dev
# 切换到某个标签对应的版本
git checkout tag001
# 创建并切换分支
git checkout -b test
git checkout -b test tag001   # 在 tag001 标签处创建新分支
# 合并指定分支到当前分支
git merge [branch]
# 撤销工作区全部修改(恢复到 HEAD 状态)
git checkout .
# 撤销某个文件的修改(改动但未 git add)
git checkout -- fileName
# 拉取远程 test 分支并创建本地 test 分支
git checkout -b test origin/test

标签管理

Bash
# 列出所有本地标签
git tag
# 给最新提交打轻量标签
git tag <tagname>
# 给最新提交打附注标签
git tag -a <tagname>
# 打带说明的附注标签
git tag -a <tagname> -m "标签"
# 删除标签
git tag -d <tagname>

查看信息

Bash
# 查看历史提交记录
git log
# 每条记录打印一行
git log --oneline
# 查看某人的提交记录
git log --author='name'
# 以 ASCII 图形展示分支合并
git log --graph
# 显示 n 条日志
git log -n
# 显示某日期之后 / 之前 / 之间的记录
git log --after='2020-08-08' [--before='2020-08-26']

远程操作

Bash
# 查看所有远端仓库
git remote -v
# 查看某个远端仓库信息
git remote show [remote]
# 添加远端仓库(shortname 可省略,默认与远端同名)
git remote add [shortname] [url]
# 删除远端仓库
git remote rm name
# 重命名远端仓库
git remote rename old_name new_name
# 拉取远端分支并合并(git pull [remote] [remote branch]:[local branch])
git pull origin master:hotfix   # 远端 master 合并到本地 hotfix
git pull origin master          # 合并到当前分支
# 只拉取、不合并
git fetch [alias]
# 拉取远端所有 tag
git pull --tags
# 拉取并清理远端已不存在的分支
git pull --prune
# 拉取后合并远端数据到当前分支
git merge [alias]/[branch]
# 推送本地分支到远程(git push [remote] [local branch]:[remote branch])
git push origin master:master
git push origin master          # 本地与远端分支同名
git push --force origin master  # 版本有差异时强制推送(慎用)
# 删除远端 origin 的 master 分支
git push origin --delete master
# 生成 RSA 密钥对(公钥 + 私钥)
ssh-keygen -t rsa -C 'email'
# 添加远程仓库
git remote add origin https://example.com/repo.git
# 更新远程分支列表
git remote update origin --prune
git remote update origin -p

撤销

Bash
# 撤销暂存区(git add 但未 commit)
git reset HEAD fileName        # 或 git reset --mixed HEAD fileName
git reset HEAD .               # 撤销全部暂存
# 已 commit 但未 push 的撤销
git reset --soft commit-id     # 头指针回退,暂存区与工作区内容不变
git reset --soft HEAD~1
git reset --mixed commit-id    # 回退并撤销暂存区,工作区内容不变
git reset --mixed HEAD~1
git reset --hard commit-id     # 全部恢复到指定版本(丢弃工作区改动)
git reset --hard HEAD~1
# commit-id 通过 git log 查看(取前 6 位即可);HEAD~1 表示前一次提交,以此类推

子模块处理

Bash
# 添加子模块到本地 dir 目录
git submodule add [url] [dir]
# 将子模块 [dir] 跟踪到 [dev] 分支
git submodule set-branch -b [dev] [dir]
# 更新子模块到最新
git submodule update
# 初始化子模块
git submodule init
# 初始化并递归更新到当前提交点最新
git submodule update --init --recursive

5. git commit 常用前缀

前缀含义
feat新功能(feature)
fix修复 bug
docs文档更新
style格式更新(不影响代码运行的变动)
refactor重构(非新功能、非 bug 修复的代码改动)
perf性能优化
test增加测试
chore构建过程或辅助工具变动
revert回滚到上一版本
merge代码合并
sync同步主线或分支的 bug