Git的使用

记录git的使用

Git 命令大全

本文基于知乎文章《Git 命令大全》(原文链接)整理,涵盖 Git 核心操作命令、常见问题解决方案,并补充实用扩展知识

一、初始化与配置

1. 核心命令整理(原文内容)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 初始化本地 Git 仓库(在当前目录创建 .git 文件夹)
git init

# 配置全局用户名(所有仓库生效)
git config --global user.name "你的用户名"

# 配置全局邮箱(与 Git 平台账号邮箱一致,用于身份识别)
git config --global user.email "你的邮箱@xxx.com"

# 开启命令自动着色(git status、git log 等输出更易读)
git config --global color.ui true
git config --global color.status auto
git config --global color.diff auto
git config --global color.branch auto
git config --global color.interactive auto

# 移除全局 HTTP 代理配置(解决代理失效导致的连接问题)
git config --global --unset http.proxy

2. 补充知识与扩展

  • 配置作用域区别

    • --global:全局配置(保存在 ~/.gitconfigC:\Users\用户名\.gitconfig),对当前用户所有仓库生效;
    • --local:仓库级配置(保存在当前仓库的 .git/config),仅对当前仓库生效,优先级高于 --global
    • --system:系统级配置(保存在 /etc/gitconfigGit 安装目录/etc/gitconfig),对所有用户生效(需管理员权限)。
      示例:为当前仓库单独配置邮箱
    1
    git config --local user.email "仓库专属邮箱@xxx.com"
  • 查看配置

    1
    2
    git config --list  # 查看所有生效的配置(按优先级排序)
    git config user.name # 查看指定配置项(如用户名)
  • 常用辅助配置

    1
    2
    3
    4
    # 配置默认文本编辑器(解决 commit 时编辑器异常问题)
    git config --global core.editor "code --wait" # VS Code 为例
    # 配置换行符自动转换(避免跨系统协作换行符冲突)
    git config --global core.autocrlf true # Windows 下;Linux/macOS 下设为 input

二、克隆、状态与提交

1. 核心命令整理(原文内容)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 克隆远程仓库(SSH 地址示例,也可使用 HTTPS 地址)
git clone git+ssh://git@192.168.53.168/VT.git

# 查看当前仓库状态(显示修改未暂存、暂存未提交的文件)
git status

# 单个文件添加到暂存区(跟踪文件变更)
git add xyz.txt

# 当前目录所有修改/新增文件添加到暂存区(不含被忽略文件)
git add .

# 提交暂存区文件(-m 后为提交说明,需清晰描述变更内容)
git commit -m "feat: 新增登录功能"

# 修改上一次提交(仅适用于未推送到远程的提交,避免修改历史)
git commit --amend -m "feat: 新增登录功能(补充密码验证)"

# 跳过暂存区,直接提交已跟踪文件的修改(未跟踪文件需先 git add)
git commit -am "fix: 修复登录按钮点击无响应问题"

2. 补充知识与扩展

  • 克隆的扩展用法

    1
    2
    3
    4
    5
    6
    7
    # 克隆指定分支(避免克隆全部分支占用空间)
    git clone -b 分支名 远程仓库地址
    # 示例:克隆远程 develop 分支
    git clone -b develop https://github.com/xxx/xxx.git

    # 浅克隆(仅拉取最近 N 次提交,适合大型仓库提速)
    git clone --depth 1 远程仓库地址 # 仅拉取最近 1 次提交
  • 暂存区理解
    暂存区(Index)是 Git 特有的“中间层”,用于临时存放待提交的变更。通过 git add 将变更存入暂存区,git commit 将暂存区内容提交到本地仓库。好处是可分批次提交不同文件的变更(例如:先提交功能代码,再提交文档)。

  • 提交信息规范
    推荐遵循 Angular 提交规范,格式:类型(范围): 描述

    • 类型:feat(新功能)、fix(bug 修复)、docs(文档修改)、style(代码格式调整,无逻辑变更)、refactor(重构)、test(测试代码)、chore(构建/工具配置);
      示例:fix(login): 修复手机号格式验证错误

三、文件删除与重命名

1. 核心命令整理(原文内容)

1
2
3
4
5
6
7
8
# 从暂存区和工作区同时删除文件(需谨慎,删除后需 commit 生效)
git rm xxx.txt

# 递归删除目录(含子目录下所有文件)
git rm -r docs/

# 重命名文件(等价于 “mv 旧名 新名 + git add 新名 + git rm 旧名”)
git mv README.md README_2.0.md

2. 补充知识与扩展

  • 仅从暂存区删除(保留工作区文件)
    若误将不需要跟踪的文件 git add,可从暂存区移除但保留本地文件:

    1
    2
    git rm --cached 不需要跟踪的文件.txt
    git rm --cached -r . #清空暂存区
  • 删除已提交的文件(保留本地副本)
    若文件已提交到仓库,想停止跟踪但保留本地文件:

    1
    2
    git rm --cached 已提交文件.txt
    git commit -m "chore: 停止跟踪已提交文件.txt"
  • 重命名的注意事项
    Git 对文件名大小写不敏感(如 ReadMe.mdREADME.md 视为同一文件),若需修改文件名大小写,需先删除旧名再添加新名:

    1
    2
    3
    git rm ReadMe.md
    mv ReadMe.md README.md
    git add README.md

四、日志查看与显示

1. 核心命令整理(原文内容)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 显示完整提交日志(按时间倒序,含作者、时间、提交 ID、说明)
git log

# 显示最近 1 次提交
git log -1

# 显示最近 5 次提交
git log -5

# 显示日志及每次提交的变更文件(含新增/删除/修改的文件数)
git log --stat

# 显示日志及每次提交的具体代码变更(-p 显示补丁,-m 显示合并提交的双方信息)
git log -p -m

# 图形化显示提交历史(含分支合并线,%h 显示短提交 ID,%s 显示提交说明)
git log --pretty=format:'%h %s' --graph

# 查看指定提交的完整内容(需输入完整提交 ID,或前 4-6 位即可)
git show dfb02e6e4f2f7b573337763e5c0013802e392818
git show dfb02 # 短 ID 示例

# 查看当前 HEAD 指向的提交详情(HEAD 是当前分支的“指针”)
git show HEAD

# 查看上一个版本的提交(HEAD^ 等价于 HEAD~1)
git show HEAD^

# 查看上上上次版本的提交(HEAD~3 表示往前数 3 个版本)
git show HEAD~3

2. 补充知识与扩展

  • 常用日志过滤与格式化

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    # 按作者筛选日志(查找指定人提交的记录)
    git log --author="张三"

    # 按时间筛选日志(查找近 3 天的提交)
    git log --since="3 days ago"
    # 查找 2024-01-01 到 2024-05-01 之间的提交
    git log --since="2024-01-01" --until="2024-05-01"

    # 按提交说明筛选(查找含“登录”关键词的提交)
    git log --grep="登录"

    # 简洁日志(一行显示一个提交,常用!)
    git log --oneline # 等价于 --pretty=oneline --abbrev-commit
    # 图形化简洁日志(查看分支关系更直观)
    git log --oneline --graph --all # --all 显示所有分支的日志
  • 查看特定文件的提交历史
    跟踪单个文件的修改记录(适合排查“谁改了这个文件”):

    1
    2
    git log -p README.md  # 显示 README.md 的所有修改历史及代码变更
    git log --follow README.md # 跟踪文件重命名后的历史(默认不跟踪)

五、标签管理

1. 核心命令整理(原文内容)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 查看本地所有标签(按字母顺序排列)
git tag

# 创建带注释的标签(-a 表示 annotated,含作者、时间、说明,推荐用于版本发布)
git tag -a v2.0 -m "版本 2.0:新增支付功能"

# 显示标签对应的提交详情(含标签说明、提交内容)
git show v2.0

# 查看标签 v2.0 对应的所有提交日志
git log v2.0

# 推送所有本地标签到远程仓库(标签不会随 git push 自动推送)
git push --tags

2. 补充知识与扩展

  • 标签的两种类型

    1. 带注释标签(Annotated)git tag -a 创建,含完整元数据(作者、时间、说明),会被 Git 永久跟踪,适合正式版本(如 v1.0、v2.0);
    2. 轻量标签(Lightweight):仅为提交 ID 的“别名”,无元数据,适合临时标记(如测试版本):
      1
      2
      git tag v2.0-beta  # 创建轻量标签
      git tag -d v2.0-beta # 删除轻量标签(与删除带注释标签命令一致)
  • 推送指定标签到远程
    若不想推送所有标签,可指定单个标签:

    1
    git push origin v2.0  # 仅推送标签 v2.0 到远程
  • 删除远程标签
    需先删除本地标签,再推送“删除指令”到远程:

    1
    2
    git tag -d v2.0  # 删除本地标签
    git push origin :refs/tags/v2.0 # 删除远程标签
  • 检出标签(查看历史版本)
    标签是“静态快照”,检出后会进入 detached HEAD 状态(无分支关联),若需修改,需创建新分支:

    1
    2
    git checkout v2.0  # 检出标签 v2.0(进入 detached HEAD 状态)
    git checkout -b fix-v2.0 v2.0 # 基于标签创建新分支,用于修复旧版本问题

六、差异比较(diff)

1. 核心命令整理(原文内容)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 显示工作区与暂存区的差异(未 git add 的修改)
git diff

# 显示暂存区与本地仓库的差异(已 git add 但未 git commit 的修改)
git diff --cached

# 显示工作区与上一次提交(HEAD^)的差异
git diff HEAD^

# 显示工作区与 HEAD 版本中指定目录(lib/)的差异
git diff HEAD -- ./lib

# 显示远程 master 分支与本地 master 分支的差异(需先 git fetch)
git diff origin/master..master

# 仅显示差异文件列表(不显示具体代码变更,适合快速排查)
git diff origin/master..master --stat

2. 补充知识与扩展

  • 比较分支/提交的差异

    1
    2
    3
    4
    5
    6
    7
    8
    # 比较两个分支的差异(如 feature/login 与 master)
    git diff feature/login..master

    # 比较两个提交之间的差异(需输入两个提交 ID)
    git diff dfb02..a8c3f # 显示 dfb02 到 a8c3f 之间的变更

    # 比较指定文件在两个分支中的差异
    git diff feature/login master -- ./src/login.js
  • 忽略空白字符差异
    若代码仅调整了空格/换行(无逻辑变更),可忽略空白差异:

    1
    2
    git diff -w  # -w 忽略所有空白差异
    git diff --ignore-space-at-eol # 仅忽略行尾空白差异
  • 使用工具可视化 diff
    若觉得命令行 diff 不直观,可使用图形化工具(如 VS Code):

    1
    2
    git difftool  # 调用默认图形化工具显示差异
    git difftool --tool=vscode # 指定 VS Code 为 diff 工具

七、远程仓库操作

1. 核心命令整理(原文内容)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 添加远程仓库(命名为 origin,通常为默认远程仓库名)
git remote add origin git+ssh://git@192.168.53.168/VT.git

# 获取远程仓库的所有更新(不合并到本地分支,仅更新本地缓存的远程分支)
git fetch

# 获取远程更新并清理本地缓存中已被远程删除的分支(避免无效分支残留)
git fetch --prune

# 拉取远程 master 分支并合并到当前本地分支(等价于 git fetch + git merge)
git pull origin master

# 推送当前本地分支到远程 master 分支(若远程无该分支则自动创建)
git push origin master

# 删除远程分支(hotfixes/BJVEP933,格式:origin:远程分支名)
git push origin :hotfixes/BJVEP933

2. 补充知识与扩展

  • 查看远程仓库信息

    1
    2
    3
    git remote  # 查看所有远程仓库名(如 origin)
    git remote -v # 查看远程仓库的详细地址(fetch 拉取地址、push 推送地址)
    git remote show origin # 查看 origin 远程仓库的详细信息(含分支关联、提交状态)
  • 修改远程仓库地址
    若远程仓库地址变更(如 Git 服务器迁移),无需删除重建,直接修改:

    1
    2
    3
    4
    5
    # 方法 1:修改地址
    git remote set-url origin 新的远程地址
    # 方法 2:先删除旧地址,再添加新地址
    git remote remove origin
    git remote add origin 新的远程地址
  • SSH 与 HTTPS 地址的区别

    类型 优势 劣势 适用场景
    SSH 无需每次输入账号密码(配置 SSH 密钥后) 需提前配置 SSH 密钥,首次 setup 稍复杂 长期开发的个人/团队仓库
    HTTPS 无需配置密钥,直接输入账号密码即可连接 每次推送需输入账号密码(可配置凭据缓存) 临时克隆、公共仓库访问
  • 安全推送替代 git push --force
    原文提示慎用 git push --force(可能覆盖远程提交),推荐更安全的 --force-with-lease

    1
    git push --force-with-lease origin master

    作用:仅当远程分支未被他人修改时才强制推送,若他人已提交,会提示冲突,避免误删他人代码。

  • 关联本地分支与远程分支
    首次推送本地分支到远程时,建议关联分支(后续可直接 git pull/push,无需指定远程分支):

    1
    2
    3
    git push -u origin 本地分支名  # -u 等价于 --set-upstream
    # 示例:推送本地 feature/pay 分支并关联远程同名分支
    git push -u origin feature/pay

八、分支管理

1. 核心命令整理(原文内容)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 查看本地所有分支(当前分支前带 * 标记)
git branch

# 查看包含指定提交(50089 为短提交 ID)的所有本地分支
git branch --contains 50089

# 查看所有分支(本地 + 远程,远程分支以 remotes/origin/ 开头)
git branch -a

# 仅查看所有远程分支
git branch -r

# 查看已合并到当前分支的所有本地分支(可安全删除)
git branch --merged

# 查看未合并到当前分支的所有本地分支(删除需谨慎)
git branch --no-merged

# 重命名本地分支(将 master 重命名为 master_copy,需在非目标分支下操作)
git branch -m master master_copy

# 删除本地分支(仅当分支已合并到其他分支时生效,避免误删未合并代码)
git branch -d hotfixes/BJVEP933

# 强制删除本地分支(无论是否合并,用于删除确定无用的分支)
git branch -D hotfixes/BJVEP933

2. 补充知识与扩展

  • Git 2.23+ 新命令:git switchgit restore
    Git 新增更直观的分支切换命令 git switch(替代 git checkout 的分支切换功能):

    1
    2
    3
    git switch master  # 切换到已存在的 master 分支
    git switch -c feature/pay # 创建并切换到 feature/pay 分支(-c 等价于 --create)
    git switch -c feature/pay origin/feature/pay # 基于远程分支创建本地分支并切换
  • 查看分支关联状态
    查看本地分支与远程分支的关联关系(是否已 --set-upstream):

    1
    git branch -vv  # 显示每个分支的关联远程分支及提交差异
  • 清理本地无效分支
    当远程分支被删除后,本地 git branch -a 仍会显示 remotes/origin/已删除分支,可通过以下命令清理:

    1
    2
    3
    git fetch --prune  # 清理本地缓存的远程已删除分支
    # 或手动删除本地跟踪的无效远程分支
    git branch -r | grep -v 'origin/master' | xargs -I {} git branch --delete --remotes {}

九、分支检出与合并

1. 核心命令整理(原文内容)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 创建并切换到新分支(master_copy,等价于 git branch master_copy + git checkout master_copy)
git checkout -b master_copy

# 从远程 develop 分支创建本地 devel 分支并切换
git checkout -b devel origin/develop

# 检出已存在的分支(features/performance)
git checkout features/performance

# 跟踪远程分支(将本地 hotfixes/BJVEP933 与远程同名分支关联,后续可直接 git pull/push)
git checkout --track hotfixes/BJVEP933

# 切换到标签版本(v2.0,会进入 detached HEAD 状态)
git checkout v2.0

# 回退单个文件到上一次提交的状态(放弃工作区修改,需谨慎)
git checkout -- README.md

# 将远程 master 分支合并到当前本地分支
git merge origin/master

# 应用指定提交(ff44785404a8e 为提交 ID)到当前分支(常用于跨分支复用单个提交)
git cherry-pick ff44785404a8e

2. 补充知识与扩展

  • git mergegit rebase 的区别(核心扩展!)
    两者均用于合并分支,但提交历史不同,适用场景不同:

    操作 提交历史 适用场景 风险
    git merge 保留分支合并记录(生成一个“合并提交”),历史更完整 团队协作的公共分支(如 master)合并功能分支 无(不修改已有提交历史)
    git rebase 将当前分支的提交“移植”到目标分支末尾,历史更简洁(无合并提交) 个人开发分支(如 feature/*)合并到 master 前整理历史 有(修改已有提交历史,禁止对已推送到远程的公共分支使用

    示例:将 feature/login 分支合并到 master

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # 方法 1:merge(保留合并记录)
    git checkout master
    git pull origin master
    git merge feature/login
    git push origin master

    # 方法 2:rebase(整理历史,仅用于个人分支)
    git checkout feature/login
    git rebase master # 解决冲突后
    git checkout master
    git merge feature/login # 此时为“快进合并”,无合并提交
    git push origin master
  • git cherry-pick 高级用法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 应用多个连续提交(从 a8c3f 到 dfb02,左开右闭,即包含 dfb02 不包含 a8c3f)
    git cherry-pick a8c3f..dfb02

    # 应用提交时保留原作者信息
    git cherry-pick -x ff44785 # -x 会在提交说明中添加“(cherry picked from commit ...)”

    # 解决 cherry-pick 冲突后继续
    git cherry-pick --continue
    # 放弃 cherry-pick
    git cherry-pick --abort
  • 合并冲突解决步骤(原文未详细说明,补充核心流程)
    git mergegit rebase 出现冲突时,按以下步骤解决:

    1. 查看冲突文件:冲突文件中会用 <<<<<<< HEAD(当前分支内容)、=======(目标分支内容)、>>>>>>> 分支名 标记冲突区域;
    2. 编辑冲突文件:删除冲突标记,保留正确的代码;
    3. 标记冲突已解决:git add 冲突文件路径
    4. 继续合并/变基:
      • 若为 git mergegit commit -m "merge: 解决与 master 分支的冲突"(或 Git 自动提示提交);
      • 若为 git rebasegit rebase --continue
    5. (可选)放弃合并/变基:git merge --abortgit rebase --abort

十、版本控制操作(reset/rebase/revert)

1. 核心命令整理(原文内容)

1
2
3
4
5
6
7
8
9
10
11
12
# 重置当前分支到 HEAD 状态(--hard 会放弃工作区和暂存区的所有修改,需极度谨慎!)
git reset --hard HEAD

#如果只有一个提交,但想要撤回他
git update-ref -d HEAD

# 变基操作(整理提交历史,默认基于当前分支的上游分支,需结合 -i 使用)
git rebase

# 撤销指定提交(创建一个新提交抵消原提交的变更,不修改历史,适合已推送的提交)
git revert dfb02e6e4f2f7b573337763e5c0013802e392818

2. 补充知识与扩展

  • git reset 的三种模式(核心区别!)
    git reset 用于“回滚”版本,不同模式对工作区、暂存区的影响不同:

    模式 工作区 暂存区 本地仓库 适用场景
    --soft 保留修改 保留修改 回滚到指定版本 撤销 git commit,但保留已 git add 的内容(如提交信息写错)
    --mixed(默认) 保留修改 回滚 回滚到指定版本 撤销 git commitgit add,但保留工作区修改(如误 add 不需要的文件)
    --hard 回滚(删除修改) 回滚 回滚到指定版本 彻底放弃所有修改,回到指定版本(如代码完全错误,需从头开始)

    示例:

    1
    2
    3
    git reset --soft HEAD~1  # 撤销上一次 commit,保留暂存区(原文 FAQ 4 用到)
    git reset --mixed HEAD~1 # 撤销上一次 commit 和 add,保留工作区
    git reset --hard HEAD~1 # 撤销上一次 commit、add,且删除工作区修改(危险!)
  • git rebase -i(交互式变基,整理提交历史)
    用于合并多个小提交、修改提交说明、删除无用提交,仅适用于未推送到远程的分支:

    1
    2
    # 整理最近 3 次提交(HEAD~3 表示往前数 3 个版本)
    git rebase -i HEAD~3

    执行后会进入编辑器,显示最近 3 次提交,每行开头为 pick(保留该提交),可修改为:

    • reword(修改提交说明);
    • squash(将当前提交合并到上一个提交);
    • drop(删除当前提交);
      保存后按提示完成变基,最终将多个小提交合并为一个清晰的提交。
  • git revertgit reset 的区别

    操作 对历史的影响 适用场景 风险
    git revert 创建新提交抵消原提交,不修改历史 撤销已推送到远程的提交(避免影响他人)
    git reset 直接修改分支指针,删除历史提交 撤销未推送到远程的本地提交 有(修改历史,远程已有的提交无法用 reset 撤销)

    示例:撤销已推送的提交 dfb02

    1
    2
    git revert dfb02  # 会自动创建一个新提交,说明为“Revert "原提交说明"”
    git push origin master # 推送新提交到远程,完成撤销

十一、暂存与恢复(stash)

1. 核心命令整理(原文内容)

1
2
3
4
5
6
7
8
9
10
11
# 暂存当前工作区和暂存区的所有修改(未提交的内容),保存为一个“快照”
git stash

# 查看所有暂存的快照列表(按创建时间排序,stash@{0} 为最新)
git stash list

# 查看指定 stash 快照的具体内容(stash@{0} 为最新快照)
git stash show -p stash@{0}

# 应用指定 stash 快照到当前工作区(应用后快照仍保留)
git stash apply stash@{0}

2. 补充知识与扩展

  • stash 的常用扩展命令

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    # 暂存时添加备注(方便后续识别快照内容,推荐!)
    git stash save "开发到一半的登录功能"

    # 应用最新快照并删除该快照(等价于 apply + drop,常用)
    git stash pop # 应用 stash@{0} 并删除
    git stash pop stash@{1} # 应用 stash@{1} 并删除

    # 删除指定快照(无需应用时)
    git stash drop stash@{0}

    # 删除所有快照(清理无用 stash)
    git stash clear

    # 基于 stash 快照创建新分支(适用于快照内容复杂,避免与当前分支冲突)
    git stash branch new-branch stash@{0}
  • stash 的注意事项

    • stash 仅暂存已跟踪文件的修改和暂存区的变更,未跟踪的新文件不会被暂存;
    • 若需暂存未跟踪文件,需加 -u(–include-untracked):
      1
      git stash -u  # 暂存已跟踪文件修改 + 未跟踪文件
    • 若需暂存忽略文件(.gitignore 中的文件),需加 -a(–all):
      1
      git stash -a  # 暂存所有修改(已跟踪 + 未跟踪 + 忽略文件)

十二、文件查找与日志辅助

1. 核心命令整理(原文内容)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 在所有跟踪文件中查找含“delete from”关键词的内容(支持正则)
git grep "delete from"

# 查找同时包含“#define”和“SORT_DIRENT”的内容(--and 表示逻辑与)
git grep -e '#define' --and -e SORT_DIRENT

# 列出当前暂存区(Index)中的所有文件(即已跟踪的文件)
git ls-files

# 显示最近修改过的文件历史(含每次修改的提交信息)
git whatchanged

# 查看所有引用的历史记录(包括已删除的分支、reset 回滚的提交,比 git log 更全面)
git reflog

# 查看 HEAD 引用历史中第 5 个状态的提交详情
git show HEAD@{5}

# 查看 master 分支昨天的状态对应的提交详情
git show master@{yesterday}

2. 补充知识与扩展

  • git grep 高级用法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 仅显示匹配行的行号
    git grep -n "delete from"

    # 显示匹配文件的文件名,不显示具体行内容
    git grep -l "delete from"

    # 在指定分支(如 develop)中查找关键词
    git grep "delete from" develop

    # 在指定目录(如 src/)中查找关键词
    git grep "delete from" src/
  • git reflog 的关键作用
    git reflog 记录了 Git 仓库中所有引用(HEAD、分支、标签)的变更历史,是“救回误删内容”的核心工具:

    • 恢复误删的分支:通过 git reflog 找到分支删除前的最后一个提交 ID,再创建分支(原文 FAQ 6 用到);
    • 恢复 git reset --hard 误删的工作区:找到 reset 前的提交 ID,用 git reset --hard 提交ID 恢复;
      示例:恢复误删的 feature/pay 分支
    1
    2
    git reflog  # 找到 feature/pay 分支最后的提交 ID,如 a8c3f
    git checkout -b feature/pay a8c3f # 基于该提交重建分支

十三、低层操作(了解即可)

1. 核心命令整理(原文内容)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 以文本图示显示分支关系(含提交信息)
git show-branch

# 显示所有分支(本地 + 远程)的关系图示
git show-branch --all

# 查看 HEAD 指向的提交对象下的文件结构(含文件类型、SHA1 值、文件名)
git ls-tree HEAD

# 查看标签 v2.0 对应的提交对象的 SHA1 值(将引用转换为具体提交 ID)
git rev-parse v2.0

# 显示指定提交(2be7fcb476)的简化原始信息(不含代码变更,仅元数据)
git show -s --pretty=raw 2be7fcb476

# 垃圾回收(优化仓库,清理无用对象、合并松散对象,减小仓库体积)
git gc

# 仓库完整性检查(检测损坏的对象或引用,修复仓库问题)
git fsck

2. 补充知识与扩展

  • 低层操作的适用场景
    这些命令主要用于 Git 内部原理学习或仓库故障排查,日常开发极少用到:

    • git gc:当仓库体积过大(如频繁提交大文件)时,手动执行可优化性能,Git 也会在后台自动执行;
    • git fsck:当仓库报错(如“corrupt object”)时,用于检测损坏的对象,若需修复,可能需要结合备份的 .git/objects 目录。

十四、常见 Git 问题与解决方案(FAQ)

1. 原文问题整理与补充

1.1 fatal: not a git repository(不是 Git 仓库)

  • 错误原因:当前目录未初始化 Git 仓库(无 .git 文件夹),或切换到了非仓库目录。

  • 解决方案

    1
    2
    3
    4
    # 方案 1:在当前目录初始化仓库(新建仓库)
    git init
    # 方案 2:切换到已存在的仓库目录(假设仓库在 ~/project 下)
    cd ~/project

1.2 error: failed to push some refs to ...(推送失败)

  • 错误原因:远程分支有本地未同步的新提交(本地分支落后于远程),Git 防止覆盖远程代码而拒绝推送。

  • 解决方案(原文补充):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # 方案 1:拉取远程更新并合并(推荐,保留合并记录)
    git pull origin 分支名 # 如 git pull origin master
    # 解决合并冲突后,再推送
    git push origin 分支名

    # 方案 2:拉取远程更新并变基(整理历史,仅用于个人分支)
    git pull --rebase origin 分支名
    # 解决变基冲突后,再推送
    git push origin 分支名

    # 方案 3:强制推送(仅当远程分支无他人修改时使用,极度谨慎!)
    git push --force-with-lease origin 分支名 # 比 --force 更安全

1.3 如何撤销 git add?(取消暂存)

  • 解决方案(原文 + 补充):

    1
    2
    3
    4
    5
    6
    # 方案 1:适用于所有 Git 版本(原文方案)
    git reset HEAD 文件名 # 如 git reset HEAD login.js
    git reset HEAD . # 撤销当前目录所有文件的暂存

    # 方案 2:适用于 Git 2.23+(更直观)
    git restore --staged 文件名 # 如 git restore --staged login.js

1.4 如何撤销 git commit?(未推送)

  • 错误场景:提交信息写错,或漏加文件,且未推送到远程。

  • 解决方案(原文 + 补充):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 方案 1:保留修改,回到 commit 前的暂存状态(原文方案)
    git reset --soft HEAD~1

    # 方案 2:保留修改,回到 commit 前的工作区状态(取消暂存)
    git reset --mixed HEAD~1 # 等价于 git reset HEAD~1(默认 --mixed)

    # 方案 3:直接修改上一次提交(推荐,避免多一次 reset 记录)
    git commit --amend -m "修正后的提交说明"
    # 若漏加文件,先 add 再 amend
    git add 漏加的文件.txt
    git commit --amend --no-edit # --no-edit 保留原提交说明

1.5 如何删除某次 commit?(未推送)

  • 错误场景:某次提交有误(如包含敏感信息),且未推送到远程。

  • 解决方案(原文 + 补充):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 方案 1:交互式变基(原文方案,推荐)
    git rebase -i HEAD~N # N 为“当前版本到目标提交”的距离(如删除最近第 3 次提交,N=3)
    # 编辑界面中,将目标提交前的“pick”改为“drop”,保存退出
    # 若出现冲突,解决后执行 git rebase --continue

    # 方案 2:reset 回滚(适用于删除最近的提交)
    git reset --hard 目标提交ID # 回滚到目标提交,删除后续所有提交
    # 示例:删除最近 2 次提交,回滚到 HEAD~2 对应的提交
    git reset --hard HEAD~2
  • 警告:严禁对已推送到远程的提交使用此方法,会导致团队历史混乱!

1.6 如何恢复被删除的分支?

  • 前提:被删除的分支曾有提交记录(可通过 git reflog 找到)。

  • 解决方案(原文 + 补充):

    1
    2
    3
    4
    5
    6
    7
    8
    # 步骤 1:查看所有引用历史,找到被删除分支的最后一个提交 ID(如 a8c3f)
    git reflog

    # 步骤 2:基于该提交 ID 重建分支
    git checkout -b 被删除的分支名 提交ID # 如 git checkout -b feature/pay a8c3f

    # 步骤 3:(若分支已推送到远程)重新推送分支
    git push -u origin 被删除的分支名

1.7 Git 仓库突然很大,怎么排查?

  • 原因:仓库中存在大文件(如压缩包、日志),或历史提交中包含大文件。

  • 解决方案(原文 + 补充):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    # 步骤 1:查看仓库中最大的 20 个文件(原文方案)
    git rev-list --objects --all | sort -k 2 | \
    git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | \
    grep ^blob | sort -k3 -n | tail -20

    # 步骤 2:删除大文件(若文件未提交,直接删除并添加到 .gitignore)
    rm 大文件路径
    echo "大文件路径" >> .gitignore
    git add .gitignore
    git commit -m "chore: 忽略大文件并删除"

    # 步骤 3:若大文件已提交到历史,需清理历史(需谨慎,会修改历史!)
    # 使用 BFG Repo-Cleaner 工具(比 git filter-branch 更快)
    # 1. 安装 BFG:https://rtyley.github.io/bfg-repo-cleaner/
    # 2. 清理历史中的大文件(如大于 100MB 的文件)
    bfg --strip-blobs-bigger-than 100M 仓库路径
    # 3. 优化仓库
    git gc --prune=now --aggressive
    # 4. 强制推送修改后的历史(仅在个人仓库或团队确认后执行)
    git push --force-with-lease origin master

1.8 You have not concluded your merge(未完成合并)

  • 错误原因:上一次 git merge 出现冲突,未解决完就中断了操作。

  • 解决方案(原文 + 补充):

    1
    2
    3
    4
    5
    6
    # 方案 1:放弃上一次合并,回到合并前状态(推荐,重新合并)
    git merge --abort

    # 方案 2:继续完成合并(若已解决冲突)
    git add 冲突文件路径 # 标记冲突已解决
    git commit -m "merge: 完成与 master 分支的合并(解决冲突)"

1.9 detached HEAD(HEAD 脱离分支)

  • 含义:HEAD 直接指向某个提交 ID,而非分支指针(常见于检出标签、旧提交),此时修改无法直接提交到分支。

  • 解决方案(原文 + 补充):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 方案 1:回到已存在的分支(如 master,丢弃 detached 状态的修改)
    git checkout master

    # 方案 2:基于当前 detached 状态创建新分支(保留修改,推荐)
    git checkout -b new-branch # 新建分支并切换,修改会保留在新分支

    # 方案 3:若需将修改提交到已有分支(如 feature/pay)
    git stash # 暂存当前修改
    git checkout feature/pay # 切换到目标分支
    git stash pop # 恢复修改
    git commit -m "feat: 从 detached 状态恢复的修改"

1.10 忘记某次 commit ID 怎么办?

  • 解决方案(原文 + 补充):

    1
    2
    3
    4
    5
    6
    7
    8
    # 方案 1:查看所有提交历史(含提交 ID、说明)
    git log --oneline # 简洁显示,快速查找

    # 方案 2:查看所有引用历史(包括已删除的提交、reset 记录)
    git reflog # 找到目标提交的 ID(如 a8c3f)

    # 方案 3:按作者/时间/关键词筛选(缩小范围)
    git log --author="张三" --since="1 week ago" --grep="登录"

2. 补充常见问题

2.1 如何忽略已跟踪的文件?

  • 问题场景:已 git add 的文件(如配置文件 config.ini),后续想忽略但不删除本地文件。

  • 解决方案

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 步骤 1:从暂存区移除文件(保留本地文件)
    git rm --cached config.ini

    # 步骤 2:将文件添加到 .gitignore
    echo "config.ini" >> .gitignore

    # 步骤 3:提交修改
    git add .gitignore
    git commit -m "chore: 忽略已跟踪的 config.ini 文件"
  • 注意.gitignore 仅对未跟踪文件生效,已跟踪文件需先 git rm --cached

2.2 如何恢复被 git checkout -- 文件 误删的修改?

  • 问题场景:执行 git checkout -- 文件名 后,工作区修改被删除,未提交也未 stash。

  • 解决方案
    若修改未被 git add,Git 无法直接恢复,但可尝试通过编辑器的“本地历史”(如 VS Code 的“文件 > 恢复文件”)恢复,或使用第三方数据恢复工具。

  • 预防:执行 git checkout -- 文件 前,先用 git status 确认修改是否需要保留,重要修改先 git stash

十五、实用提示与工作流建议

1. 原文提示补充

  • 善用 git stash:切换分支前若有未提交的修改,用 git stash save "备注" 暂存,避免修改丢失;

  • 慎用 git push --force:优先使用 git push --force-with-lease,若必须 force,需先确认远程分支无他人修改;

  • 定期优化仓库:执行 git gc 清理无用对象,git fetch --prune 清理无效远程分支;

  • 可视化工具辅助:新手推荐使用 Sourcetree(免费)、GitKraken(付费),或 IDE 内置 Git 工具(VS Code、IntelliJ IDEA),降低命令行操作门槛。

2. 补充:常用 Git 工作流

  • 1. GitHub Flow(简洁,适用于持续部署)

    1. main 分支创建 feature/bugfix 分支;
    2. 本地开发,频繁提交并推送到远程同名分支;
    3. 开发完成后,提交 Pull Request(PR);
    4. 代码审核通过后,合并到 main 分支;
    5. 合并后删除 feature/bugfix 分支,main 分支自动部署。
  • 2. Git Flow(规范,适用于版本化发布)
    核心分支:

    • main:生产环境分支,仅存放稳定版本;
    • develop:开发环境分支,集成各功能分支;
    • feature/*:功能开发分支(从 develop 创建,合并回 develop);
    • hotfix/*:生产环境紧急修复分支(从 main 创建,合并回 maindevelop);
    • release/*:版本发布分支(从 develop 创建,合并回 maindevelop,并打标签)。