- 开发工具
- CLI
- 版本控制
【免费下载链接】git-extras
GIT utilities -- repo summary, repl, changelog population, author commit percentages and more
导读
git missing是 git-extras 工具集中用于分支提交差异诊断的实用命令,它的核心能力是:一次性列出“只存在于两个分支中任意一个、但不存在于另一个”的全部提交,从而让你在合并(merge)或推送(push)之前,快速判断哪些提交会进入对端、哪些仍留在本地。读完本文,你将掌握该命令的完整语法、参数语义、底层实现原理(基于git log的三点语法与--left-right标记),并能配合 pathspec 限定目录进行精细化比较。
功能定位:一次看清两个分支“各自独有”的提交
在日常协作中,我们经常面临这样的问题:master和feature分支各自前进了几步,想确认合并前双方各自新增了哪些提交;或者本地分支领先远端,想知道推上去会带上什么。普通git log master..feature只能列出单方向差异,而git missing展示的是双向对称差集——任何只存在于其中一个分支的提交都会出现在结果里,并用<和>明确标注它属于哪一侧。
该命令的官方定义见 man/git-missing.md:
Shows commits that are in either of two branches but not both. Useful for seeing what would come across in a merge or push.
同仓库的 Commands.md 也给出了同样的描述:“Print out which commits are on one branch or the other but not both”,并支持用路径限定比较范围。
语法与参数说明
完整语法(SYNOPSIS)如下:
git-missing [<first branch>] <second branch> [<git log options>] [[--] <path>...]参数逐一拆解
| 参数 | 含义 | 说明 |
|---|---|---|
[<first branch>] | 参与比较的第一个分支 | 可选。省略时默认为当前检出的分支 |
<second branch> | 参与比较的第二个分支 | 必填。与 first branch 一起构成比较对 |
[<git log options>] | 透传给git log的任意参数 | 如--no-merges(过滤合并提交)、--oneline等 |
[[--] <path>...] | 可选 pathspec(路径限定) | 把比较范围限制到指定文件或目录;用--明确分隔路径与分支/选项 |
其中 pathspec 是 Git 官方的路径匹配语法,支持 glob 通配等模式。原文档的参考指向 Git 术语表(gitglossary),这里直接以仓库内命令 bin/git-missing 的解析行为为准展开。
从源码看参数如何被解析
虽然手册只说明了“有哪些参数”,但要真正用对--与 pathspec,理解 bin/git-missing 的解析逻辑是关键。该脚本本质是一个约 50 行的 Bash 脚本,核心是循环遍历参数并分类:
declare -a git_log_args=() declare -a branches=() declare -a pathspec=() declare parse_path=false for arg in "$@" ; do if [[ $parse_path == true ]]; then pathspec+=("$@") # 遇到 -- 后,剩余全部视为 pathspec break fi case "$arg" in --) parse_path=true ;; # 显式分隔符:之后都是路径 --*) git_log_args+=( "$arg" ) ;; # 以 -- 开头的参数透传给 git log *) branches+=( "$arg" ) ;; # 其余按分支收集 esac done由此可以得出三条关键行为:
--之后的参数全部进入 pathspec,脚本直接取剩余所有参数,因此 pathspec 可以同时传多个文件或目录;- 以
--开头的参数(如--no-merges、--oneline)被收集进git_log_args,原样透传给底层git log——这也是手册说“任何应传给 git log 的 flags 均可使用”的实现依据; - 不带
--前缀的普通参数按分支收集:收集到 2 个则分别作为 first、second branch;收集到 1 个则仅作为 second branch(此时 first 默认当前分支);数量不符则报错error: at least one branch required并以退出码 1 结束。
分支数量校验
if [ ${#branches[@]} -eq 2 ]; then firstbranch="${branches[0]}" secondbranch="${branches[1]}" elif [ ${#branches[@]} -eq 1 ]; then secondbranch="${branches[0]}" else echo >&2 "error: at least one branch required" exit 1 fi注意一个边界情况:如果既没有--、又只传了一个分支,那么<path>会被误判为分支名。因此只要同时使用路径限定与单分支形式,就必须显式写--,这正是语法中[[--] <path>...]中--存在的意义。
底层实现:一次git log调用完成双向比较
参数整理完毕后,脚本只执行一条命令完成全部工作:
git log "${git_log_args[@]}" "$firstbranch"..."$secondbranch" \ --format="%m %h %s" --left-right -- "${pathspec[@]}"这条命令的三个要点:
- 三点语法
<first>...<second>(三个点):等价于对称差集,列出“在两侧任一分支有、但不同时存在于两侧”的提交,这正是“missing”语义的底层来源。注意它和两点语法<first>..<second>(仅列 second 独有提交)有本质区别; --left-right:在每个提交前加<或>标记,标注该提交属于左侧分支还是右侧分支,对应输出中的< d14b8f0与> 97ef387;--format="%m %h %s":%m输出左右标记(配合--left-right使用),%h输出短哈希,%s输出提交主题(subject),最终形成< 短哈希 主题这一紧凑可读的输出格式。
由于所有自定义参数(如--no-merges)都被插在命令前部,它们会与git log的原生选项正常组合生效;pathspec 通过--放在命令尾部,避免与分支参数冲突。
实战示例
示例一:比较当前分支与 master
$ git missing master < d14b8f0 only on current checked out branch > 97ef387 only on master省略第一个分支时,first 分支默认为当前检出分支。<表示该提交只存在于当前分支(合并进来会带来的提交),>表示只存在于master。
示例二:比较两个具名分支
$ git missing foo bar < b8f0d14 only on foo > f38797e only on bar两个分支都显式给出,适合在分支间做“合并前预览”,或者核对远端分支与本地分支的双向领先/落后关系。
示例三:限定路径比较
$ git missing master -- src/ < ed52989 only on current checked out branch, in src/ directory > 7988c4b only on master, in src/ directory这里--之后的src/是 pathspec,比较结果只包含涉及src/目录的提交。这在评估“合并是否会影响某个模块”时非常实用——例如只关心前端目录src/的改动,就不用被其他目录的提交干扰。
组合 git log 选项
透传选项可用于进一步裁剪结果,例如过滤合并提交,只关心普通功能提交:
$ git missing master --no-merges < 6a1b2c3 feat: add retry logic > 84d9e1f fix: resolve timeout issue也可以配合--oneline等常用git log选项,输出格式仍由脚本的--format覆盖,但选项过滤行为照常生效。
Shell 补全支持
仓库为git missing提供了 Bash 补全,见 etc/bash_completion.sh:
_git_missing(){ # Suggest all known refs __gitcomp "$(git for-each-ref --format='%(refname:short)')" }补全函数通过git for-each-ref枚举仓库内所有已知引用(分支、标签等)的短名称,在输入分支名时自动提示候选。也就是说,分支参数部分享受原生补全,而路径部分遵循 Git 自身的 pathspec 补全规则。安装 shell 补全后即可直接体验(补全脚本位于仓库 etc 目录,包含 Bash、Zsh、Fish 三个版本)。
与其他文档的关联
- 使用与输出示例还可参考 Commands.md,其中保留了与该命令一致的双向差异说明与两条示例;
- roff 格式的手册页位于 man/git-missing.1,内容与 man/git-missing.md 保持一致,供
man系统渲染使用; - 该命令的原始作者为 Nate Jones(见原文档 AUTHOR 一节)。
小结
git missing用一个分支参数即完成双向差异扫描,其价值在于把“合并/推送前需要确认的内容”以对称差集的形式一次性呈现,配合--no-merges等git log选项和-- <path>pathspec 限定,可以灵活地聚焦到任意维度。理解其底层“三点语法 +--left-right+%m %h %s格式”的实现后,你不仅能熟练使用它,还能举一反三地组合原生git log能力做更复杂的提交分析。
- 开发工具
- CLI
- 版本控制
【免费下载链接】git-extras
GIT utilities -- repo summary, repl, changelog population, author commit percentages and more
相关推荐
git-extras 的 git-squash 命令详解:将分支/提交区间压缩为单次提交
git extras 的 git squash 命令详解:将分支/提交区间压缩为单次提交 导读 git squash 是 git extras 工具集中用于 历
开发工具CLI版本控制解决TypeScript模拟数据痛点:Intermock处理联合类型与交叉类型的技巧
解决TypeScript模拟数据痛点:Intermock处理联合类型与交叉类型的技巧 TypeScript开发中,模拟数据生成常常面临联合类型(Union Ty
开发工具CLI版本控制30 seconds of code 实践:用 `git shortlog` 查看两个提交之间的变更摘要
30 seconds of code 实践:用 git shortlog 查看两个提交之间的变更摘要 git shortlog 是 Git 自带的一个"提交历史
教程文档
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考