Git 常用排查指令详解
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 |
九、注意事项
- 文件路径要准确:很多命令输出为空是因为文件名或路径写错了,先用
git ls-tree确认 - 分支名有特殊字符要加引号:中文、空格等需要用双引号包裹
-S搜索默认不含 merge commit:需要加-m参数git show对 merge commit 默认只显示冲突部分:需要加-m看完整 diffgit show <commit>:<path>不支持通配符:必须用完整路径--after和--before是基于提交时间:不是合入时间,一个提交可能很早创建但很晚才合入
十、总结
排查 Git 合并问题的核心思路:
- 定位时间范围 →
git log --after --before - 找到相关提交 →
git log -S/git blame - 查看提交内容 →
git show/git diff - 理解分支关系 →
git merge-base/git branch --contains - 对比前后状态 →
git show <commit>:<path>
掌握这些命令的组合使用,就能追溯任何合并问题的根源。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)