Git 常用排查指令详解

前言

当合并后出现问题(编译报错、代码被意外修改等),需要通过 Git 命令追溯问题来源。本文整理了排查过程中常用的指令,按使用场景分类讲解。

注:

博客:

https://blog.csdn.net/badao_liumang_qizhi


一、查看提交历史

git log

查看提交历史记录。

# 基本用法:查看当前分支的提交历史
git log

# 查看指定分支的历史
git log dev

# 单行显示(简洁模式)
git log --oneline

# 自定义格式
git log --format="%h %ai %an %s"
# %h = 短SHA
# %ai = 作者时间(ISO格式)
# %an = 作者名
# %s = 提交说明

按时间范围过滤

# 查看某个时间之后的提交
git log --after="2026-05-20 16:00"

# 查看某个时间之前的提交
git log --before="2026-05-21 17:00"

# 组合使用:查看时间段内的提交
git log --after="2026-05-20 16:00" --before="2026-05-21 17:00"

# 完整示例:查看 dev 分支在某时间段内的提交
git log dev --format="%h %ai %an %s" --after="2026-05-20 16:00" --before="2026-05-21 17:00"

只看合并提交

# --merges 只显示合并提交
git log --merges --oneline

# 查看 dev 分支上的合并记录
git log dev --oneline --merges | head -10

二、查找谁修改了某段代码

git log -S(pickaxe 搜索)

搜索引入或删除了某段文本的提交。

# 搜索哪个提交引入了 "Long count" 这段文本
git log --oneline -S "Long count"

# 在指定分支上搜索
git log dev --oneline -S "Long count"

# 限定文件范围
git log dev --oneline -S "Long count" -- "*.java"

# 使用通配路径(匹配任意目录层级)
git log dev --oneline -S "Long count" -- "**/UserService.java"

# -m 参数:让搜索也覆盖 merge commit 的变更
git log dev --oneline -m -S "Long count" -- "**/UserService.java"

注意-S 默认不搜索 merge commit 中的变更,加 -m 才会搜索。

git blame

查看文件中每一行最后是被谁、在哪个提交中修改的。

# 查看某文件的逐行归属
git blame path/to/File.java

# 查看指定分支上的文件
git blame dev -- path/to/File.java

# 配合 grep 只看关心的行
git blame dev -- path/to/File.java | grep "selectCount"

输出格式

9568a283 (张三 2026-01-16 17:17:17 +0800 981) Long count = mapper.selectCount(wrapper);

含义:这行代码最后一次修改是在提交 9568a283,由张三在 2026-01-16 修改,位于第 981 行。

git log -L(行级历史追踪)

追踪某个文件中指定行的完整变更历史。

# 追踪第 100 行的历史
git log -L 100,100:path/to/File.java

# 追踪第 100-110 行的历史
git log -L 100,110:path/to/File.java

# 在指定分支上追踪
git log dev -L 100,100:path/to/File.java

三、查看提交内容

git show

查看某个提交的详细信息和改动内容。

# 查看某次提交的完整信息
git show abc1234

# 只看统计信息(改了哪些文件)
git show abc1234 --stat

# 只看某个文件的改动
git show abc1234 -- path/to/File.java

# 使用通配路径
git show abc1234 -- "**/File.java"

# 配合 grep 过滤
git show abc1234 -- "**/File.java" | grep -A 3 -B 3 "关键词"
# -A 3 = 显示匹配行之后3行
# -B 3 = 显示匹配行之前3行

查看 merge commit 的改动

普通 git show 对 merge commit 默认只显示冲突解决部分。要看完整改动需要加 -m

# -m 参数:分别对比两个父提交显示 diff
git show abc1234 -m

# 只看某个文件
git show abc1234 -m -- "**/File.java"

# 看统计信息
git show abc1234 -m --stat

查看某个提交时文件的完整内容

# 语法:git show <commit>:<file_path>
git show abc1234:src/main/java/com/example/UserService.java

# 配合 grep 查找特定内容
git show abc1234:src/main/java/com/example/UserService.java | grep "count"

# 配合 grep -n 显示行号
git show abc1234:src/main/java/com/example/UserService.java | grep -n "count"

注意:这里的文件路径不能用通配符,必须是完整的相对路径。


四、对比差异

git diff

对比两个版本之间的差异。

# 对比两个提交之间的差异
git diff abc1234 def5678

# 只看某个文件的差异
git diff abc1234 def5678 -- path/to/File.java

# 使用通配路径
git diff abc1234 def5678 -- "**/pom.xml"

# 只看文件名列表(不看具体内容)
git diff abc1234 def5678 --name-only

# 看统计信息
git diff abc1234 def5678 --stat

# 配合 grep 过滤
git diff abc1234 def5678 -- "**/pom.xml" | grep -i "mybatis"

对比 merge commit 的父提交

merge commit 有两个父提交,用 ^1^2 引用:

# ^1 = 第一个父提交(当前分支合并前的状态)
# ^2 = 第二个父提交(被合并分支的状态)

# 对比合并前后的变化
git diff abc1234^1 abc1234

# 看合并带入了什么(对比当前分支合并前 vs 合并后)
git diff abc1234^1 abc1234 -- "**/File.java"

五、查找分支关系

git merge-base

找到两个分支的共同祖先(分叉点)。

# 找两个分支的共同祖先
git merge-base feature dev

# 分支名包含特殊字符时用引号
git merge-base "feature/my-branch" dev

用途:确定你的分支是从哪个状态拉出来的,从而判断合并时的基准。

git branch --contains

查看哪些分支包含了某个提交。

# 查看哪些分支包含了提交 abc1234
git branch --contains abc1234

# 包括远程分支
git branch -a --contains abc1234

用途:确认某个修改是否已经存在于某个分支中。

git reflog

查看分支的操作历史(包括创建、切换、reset 等)。

# 查看当前分支的 reflog
git reflog

# 查看指定分支的 reflog
git reflog show feature

# 通常最后一条会显示分支创建信息
git reflog show feature | tail -5

输出示例

abc1234 feature@{5}: branch: Created from dev

这说明 feature 分支是从 dev 创建的。


六、搜索文件

git ls-tree

列出某个提交中的文件树。

# 列出某个提交中的所有文件
git ls-tree -r abc1234 --name-only

# 配合 grep 查找文件
git ls-tree -r abc1234 --name-only | grep "UserService"

# 查看某个分支上的文件
git ls-tree -r dev --name-only | grep "UserService"

用途:确认文件的完整路径,避免路径写错导致其他命令输出为空。

git grep

在 Git 仓库中搜索文本内容。

# 在当前工作区搜索
git grep "selectCount"

# 在指定分支上搜索
git grep "Integer.*selectCount" dev

# 限定文件类型
git grep "Integer.*selectCount" dev -- "*.java"

七、综合排查流程示例

场景:合并后编译报错,需要找出是谁引入的问题

第一步:确定时间范围
# 查看出问题时间段内的提交
git log dev --format="%h %ai %an %s" --after="2026-05-20 16:00" --before="2026-05-21 17:00"
第二步:确认文件路径
# 找到报错文件的完整路径
git ls-tree -r dev --name-only | grep "UserService"
第三步:查看谁最后修改了报错的那行
# 用 blame 定位
git blame dev -- "src/main/java/com/example/UserService.java" | grep "count"
第四步:查看那次提交的详情
# 查看提交信息
git log -1 --format="%H%n作者: %an%n时间: %ai%n说明: %s" abc1234

# 查看具体改了什么
git show abc1234 -- "**/UserService.java"
第五步:对比合并前后
# 找到合并提交
git log dev --oneline --merges --after="2026-05-20" | head -5

# 对比合并前后文件的变化
git show <merge_sha>^1:path/to/File.java | grep "count"  # 合并前
git show <merge_sha>:path/to/File.java | grep "count"    # 合并后
第六步:确认分支来源
# 找共同祖先
git merge-base "feature-branch" dev

# 查看共同祖先时的代码状态
git show <merge_base_sha>:path/to/File.java | grep "count"

八、常用参数速查表

参数 用途 示例
--oneline 单行显示提交 git log --oneline
--stat 显示文件修改统计 git show abc --stat
--format 自定义输出格式 git log --format="%h %an %s"
--after 时间之后 git log --after="2026-05-20"
--before 时间之前 git log --before="2026-05-21"
--merges 只看合并提交 git log --merges
-S 搜索引入/删除文本的提交 git log -S "text"
-m 对 merge commit 也做 diff git log -m -S "text"
-n 限制显示数量 git log -5(显示5条)
--name-only 只显示文件名 git diff --name-only
-A n grep 显示匹配后n行 grep -A 3 "text"
-B n grep 显示匹配前n行 grep -B 3 "text"
^1 第一个父提交 git show abc^1
^2 第二个父提交 git show abc^2
--contains 包含某提交的分支 git branch --contains abc
-r 递归列出文件树 git ls-tree -r dev

九、注意事项

  1. 文件路径要准确:很多命令输出为空是因为文件名或路径写错了,先用 git ls-tree 确认
  2. 分支名有特殊字符要加引号:中文、空格等需要用双引号包裹
  3. -S 搜索默认不含 merge commit:需要加 -m 参数
  4. git show 对 merge commit 默认只显示冲突部分:需要加 -m 看完整 diff
  5. git show <commit>:<path> 不支持通配符:必须用完整路径
  6. --after--before 是基于提交时间:不是合入时间,一个提交可能很早创建但很晚才合入

十、总结

排查 Git 合并问题的核心思路:

  1. 定位时间范围git log --after --before
  2. 找到相关提交git log -S / git blame
  3. 查看提交内容git show / git diff
  4. 理解分支关系git merge-base / git branch --contains
  5. 对比前后状态git show <commit>:<path>

掌握这些命令的组合使用,就能追溯任何合并问题的根源。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐