下面的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命令是一个低级(管道)命令,它遍历给定的修订并转储遇到的SHA1标识符。可以把它看作是等价于git log,除了它只显示sha1 -没有日志消息,没有作者名称,没有时间戳,没有任何“花哨”的东西。
——no-walk选项,顾名思义,防止git rev-list遍历祖先链。所以如果你输入git rev-list——no-walk mybranch,它只会打印一个SHA1标识符:mybranch分支的tip提交标识符。
——exclude=refs/heads/mybranch——all参数告诉git rev-list从每个引用开始,除了refs/heads/mybranch。
因此,当你运行git rev-list——no-walk——exclude=refs/heads/mybranch——all时,git会打印除refs/heads/mybranch之外的每个ref的提示提交的SHA1标识符。这些提交及其祖先是您不感兴趣的提交——这些是您不想看到的提交。
其他的提交是你想要看到的,所以我们收集git rev-list——no-walk——exclude=refs/heads/mybranch——all的输出,并告诉git显示除了这些提交和它们的祖先之外的所有内容。
——no-walk参数对于大型存储库是必要的(并且是对小型存储库的优化):如果没有它,Git将不得不打印,shell将不得不收集(并在内存中存储)比必需的多得多的提交标识符。对于大型存储库,收集的提交数量很容易超过shell命令行参数的限制。
去虫子?
我本希望以下几点能起作用:
git log --all --not --exclude=refs/heads/mybranch --all
但事实并非如此。我猜这是Git中的一个bug,但也可能是故意的。