我想列出只是特定分支的一部分的所有提交。

使用下面的代码,它列出了来自分支的所有提交,也包括来自父(master)的所有提交

git log mybranch

我发现的另一种选择是排除主可达的提交,并给我我想要的,但我想避免知道其他分支名称的需要。

git log mybranch --not master

我试图使用git for-each-ref,但它也列出了mybranch,所以实际上它排除了所有:

git log mybranch --not $(git for-each-ref --format '^%(refname:short)' refs/heads/)

更新:

我正在测试一个我不久前发现的新选项,直到现在看来,这可能是我一直在寻找的:

git log --walk-reflogs mybranch

更新(2013 - 02 - 13 t15:08):

——walk-reflogs选项很好,但我检查了reflogs的过期时间(默认90天,gc.reflogExpire)。

我想我找到了我一直在寻找的答案

git log mybranch --not $(git for-each-ref --format='%(refname)' refs/heads/ | grep -v "refs/heads/mybranch")

我只是从可用的分支列表中删除当前分支,并使用该列表从日志中排除。这样我只能得到只有mybranch才能到达的提交。


当前回答

我正在使用以下命令:

git shortlog --no-merges --graph --abbrev-commit master..<mybranch>

or

git log --no-merges --oneline --decorate master..<mybranch>

其他回答

听起来你应该用樱桃:

git cherry -v develop mybranch

这将显示mybranch中包含的所有提交,但不包含在develop中。如果省略了最后一个选项(mybranch),它将比较当前的分支。

正如VonC指出的那样,您总是在将您的分支与另一个分支进行比较,因此了解您的分支,然后选择与哪个分支进行比较。

下面的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,但也可能是故意的。

在我的情况下,我们使用Git Flow和GitHub。你所需要做的就是:在GitHub上比较你的功能分支和开发分支。

它将只显示提交到您的特性分支。

例如:

https://github.com/your_repo/compare/develop...feature_branch_name

我需要在一行中为特定的分支导出日志。

所以我可能想出了一个更简单的解决方案。 当执行git log——pretty=oneline——graph时,我们可以看到当前分支中所有未完成的提交都是以|开头的行

所以一个简单的grep -v就可以了: Git log——pretty=oneline——graph | grep -v "^|"

当然,如果你需要其他信息,你可以改变pretty参数,只要你把它放在一行中。

您可能还想删除合并提交。 当消息以“Merge branch”开头时,再管道另一个grep -v,就完成了。

在我的具体情况下,最后的命令是: git log——pretty="%ad: %an, %s"——graph | grep -v "^|" | grep -v "合并分支"

选项1(似乎更快,但你可能会得到错误bash: /mingw64/bin/git:参数列表在git bash中太长(它在Linux中工作),这取决于你的项目有多少分支)

Git log <your_branch>——not $(Git branch -a | grep -v <your_branch> | grep -ve '->' | sed "s/\s//g")

选项2

git - rev-list <your_branch> | git -rev -stdin | sed -E 's/~[0-9]+//g;s / \ ^ [0 - 9] + / / g”| grep”< your_branch >”| awk - f”“{打印$ 1}’