以下shell命令应该能够实现你想要的功能:
git log --all --not $(git rev-list --no-walk --exclude=refs/heads/mybranch --all)
注意事项
如果您当前已经检出了 mybranch
分支,则上述命令将无法正常工作。这是因为 mybranch
分支上的提交也可以通过 HEAD
访问,因此 Git 不认为这些提交是唯一归属于 mybranch
的。要在检出 mybranch
分支时使命令成功执行,您还需要添加一个排除条件来排除 HEAD
分支:
git log --all --not $(git rev-list --no-walk \
--exclude=refs/heads/mybranch \
--exclude=HEAD \
--all)
但是,除非mybranch
被检出,否则不应排除HEAD
,否则您可能会显示与mybranch
无关的提交。
同样地,如果您有一个名为origin/mybranch
的远程分支,对应本地的mybranch
分支,您将需要将其排除:
git log --all --not $(git rev-list --no-walk \
--exclude=refs/heads/mybranch \
--exclude=refs/remotes/origin/mybranch \
--all)
如果远程分支是远程仓库的默认分支(通常仅对origin/master
成立),您还必须将origin/HEAD
排除在外:
git log --all --not $(git rev-list --no-walk \
--exclude=refs/heads/mybranch \
--exclude=refs/remotes/origin/mybranch \
--exclude=refs/remotes/origin/HEAD \
--all)
如果你已经检出了该分支,
并且存在远程分支,
并且远程分支是远程仓库的默认分支,则会排除很多内容:
git log --all --not $(git rev-list --no-walk \
--exclude=refs/heads/mybranch \
--exclude=HEAD
--exclude=refs/remotes/origin/mybranch \
--exclude=refs/remotes/origin/HEAD \
--all)
解释
git rev-list
命令是一个低级(plumbing)命令,它遍历给定的修订版本并转储遇到的SHA1标识符。可以将其视为等效于git log
,只显示SHA1标识符,没有日志消息、作者姓名、时间戳或其他“花哨”的信息。
--no-walk
选项,顾名思义,防止git rev-list
遍历祖先链。因此,如果您键入git rev-list --no-walk mybranch
,它只会打印一个SHA1标识符:mybranch分支的末尾提交的标识符。
--exclude=refs/heads/mybranch --all
参数告诉git rev-list
从每个引用开始,除了refs/heads/mybranch
。
所以,当您运行git rev-list --no-walk --exclude=refs/heads/mybranch --all
时,Git会打印每个引用的末尾提交的SHA1标识符,除了refs/heads/mybranch
。这些提交及其祖先是您不感兴趣的提交 - 这些是您不想看到的提交。
另外的提交是您想要查看的提交,因此我们收集git rev-list --no-walk --exclude=refs/heads/mybranch --all
的输出,并告诉Git显示除了那些提交及其祖先之外的所有内容。
--no-walk
参数对于大型仓库是必需的(并且对于小型仓库是一种优化):否则,Git将不得不打印,并且shell将不得不收集(并在内存中存储)比必要多得多的提交标识符。对于大型仓库,收集的提交数量很容易超过shell的命令行参数限制。
Git bug?
我原本期望以下内容可以工作:
git log --all --not --exclude=refs/heads/mybranch --all
但实际上并没有。我猜这可能是Git中的一个漏洞,但也有可能是有意为之。