Git log只能获取特定分支的提交

dim*_*irc 194 git

我想列出仅属于特定分支的所有提交.

通过以下内容,它列出了分支中的所有提交,但也列出了父(主)的提交

git log mybranch
Run Code Online (Sandbox Code Playgroud)

我找到的另一个选项是排除master可以访问的提交并给我我想要的东西,但我想避免需要知道其他分支名称.

git log mybranch --not master
Run Code Online (Sandbox Code Playgroud)

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

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

更新:

我正在测试我刚才发现的一个新选项,直到现在看来这可能是我想要的:

git log --walk-reflogs mybranch
Run Code Online (Sandbox Code Playgroud)

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

--walk-reflogs选项很好,但我检查了reflogs是否到期(默认为90天,gc.reflogExpire).

我想我找到了我想要的答案:

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

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

Smi*_*lie 143

从听起来你应该使用的cherry:

git cherry -v develop mybranch
Run Code Online (Sandbox Code Playgroud)

这将显示所有这些都包含在该提交的mybranch,而不是在发展.如果你不使用最后一个选项(mybranch),它将比较当前分支.

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

  • 您还可以执行`git cherry -v master`来比较当前分支与主分支. (10认同)
  • 这正是我所需要的,但似乎应该有一个更直观的命令(即使在Git世界中也是如此). (4认同)
  • 我不明白为什么当OP明确表示他想避免明确命名另一个分支时,这会被投票。并且“gitcherry-vdevelopmybranch”与OP提到的“gitlogmybranch--notdevelop”非常相似。 (3认同)
  • 使用git cherry的危险是,只有在分支之间它们的文件差异相同时,才匹配提交。如果进行了某种合并,这会使一个分支与另一个分支之间的差异有所不同,那么git cherry会将它们视为不同的提交。 (2认同)
  • @MattArnold,您必须将文本“develop”和“mybranch”更改为存储库中存在的分支 (2认同)

Von*_*onC 37

但我想避免需要知道其他分支名称.

我不认为这是可能的:Git中的分支总是基于另一个或至少在另一个提交上,如" git diff中显示的不够 ":

在此输入图像描述

您需要一个日志参考点来显示正确的提交.

如" GIT - 我从何处分支? "中所述:

分支只是指向DAG中某些提交的指针

因此,即使git log master..mybranch是一个答案,它仍然会显示太多提交,如果mybranch是基于myotherbranch,本身基于master.

为了找到该引用(分支的来源),您只能解析提交并查看它们所在的分支,如下所示:


Luk*_*man 25

我终于找到了做OP想要的方法.它很简单:

git log --graph [branchname]
Run Code Online (Sandbox Code Playgroud)

该命令将以图形格式显示可从提供的分支访问的所有提交.但是,您可以通过查看*提交行中第一个字符的提交图来轻松过滤该分支上的所有提交.

例如,让我们看看git log --graph master下面的cakephp GitHub repo 的摘录:

D:\Web Folder\cakephp>git log --graph master
*   commit 8314c2ff833280bbc7102cb6d4fcf62240cd3ac4
|\  Merge: c3f45e8 0459a35
| | Author: José Lorenzo Rodríguez <lorenzo@users.noreply.github.com>
| | Date:   Tue Aug 30 08:01:59 2016 +0200
| |
| |     Merge pull request #9367 from cakephp/fewer-allocations
| |
| |     Do fewer allocations for simple default values.
| |
| * commit 0459a35689fec80bd8dca41e31d244a126d9e15e
| | Author: Mark Story <mark@mark-story.com>
| | Date:   Mon Aug 29 22:21:16 2016 -0400
| |
| |     The action should only be defaulted when there are no patterns
| |
| |     Only default the action name when there is no default & no pattern
| |     defined.
| |
| * commit 80c123b9dbd1c1b3301ec1270adc6c07824aeb5c
| | Author: Mark Story <mark@mark-story.com>
| | Date:   Sun Aug 28 22:35:20 2016 -0400
| |
| |     Do fewer allocations for simple default values.
| |
| |     Don't allocate arrays when we are only assigning a single array key
| |     value.
| |
* |   commit c3f45e811e4b49fe27624b57c3eb8f4721a4323b
|\ \  Merge: 10e5734 43178fd
| |/  Author: Mark Story <mark@mark-story.com>
|/|   Date:   Mon Aug 29 22:15:30 2016 -0400
| |
| |       Merge pull request #9322 from cakephp/add-email-assertions
| |
| |       Add email assertions trait
| |
| * commit 43178fd55d7ef9a42706279fa275bb783063cf34
| | Author: Jad Bitar <jadbitar@mac.com>
| | Date:   Mon Aug 29 17:43:29 2016 -0400
| |
| |     Fix `@since` in new files docblocks
| |
Run Code Online (Sandbox Code Playgroud)

如您所见,只提交8314c2ff833280bbc7102cb6d4fcf62240cd3ac4并将c3f45e811e4b49fe27624b57c3eb8f4721a4323b*作为提交行中的第一个字符.这些提交来自主分支,而其他四个来自其他一些分支.

  • 这不是同一件事,但只需少量提交即可完成工作。 (2认同)

Ric*_*sen 11

以下shell命令应该执行您想要的操作:

git log --all --not $(git rev-list --no-walk --exclude=refs/heads/mybranch --all)
Run Code Online (Sandbox Code Playgroud)

注意事项

如果您已mybranch签出,则上述命令将不起作用.那是因为提交mybranch也可以通过HEAD,因此Git不认为提交是唯一的mybranch.要在mybranch签出时使其工作,您还必须为HEAD以下内容添加排除:

git log --all --not $(git rev-list --no-walk \
    --exclude=refs/heads/mybranch \
    --exclude=HEAD \
    --all)
Run Code Online (Sandbox Code Playgroud)

然而,你应该排除HEAD,除非mybranch被检查出来,否则你就有可能表明并不互斥提交mybranch.

同样,如果您有一个origin/mybranch与本地mybranch分支对应的远程分支,则必须将其排除:

git log --all --not $(git rev-list --no-walk \
    --exclude=refs/heads/mybranch \
    --exclude=refs/remotes/origin/mybranch \
    --all)
Run Code Online (Sandbox Code Playgroud)

如果远程分支是远程存储库的默认分支(通常仅适用于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)
Run Code Online (Sandbox Code Playgroud)

如果您已检出分支,并且有远程分支,并且远程分支是远程存储库的默认分支,那么您最终排除了很多:

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)
Run Code Online (Sandbox Code Playgroud)

说明

git rev-list命令是一个低级(管道)命令,它处理给定的修订并转储遇到的SHA1标识符.可以认为它等同于git log除了它只显示SHA1-no日志消息,没有作者姓名,没有时间戳,没有任何"花哨"的东西.

--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打印每个ref的tip提交的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
Run Code Online (Sandbox Code Playgroud)

但事实并非如此.我猜这是Git中的一个错误,但也许是故意的.

  • 我来到这里想要知道如何做Mercurial的`hg log -b <branch>`.我不明白为什么人们说git不友好./秒 (4认同)

小智 10

I'm using the following commands:

git shortlog --no-merges --graph --abbrev-commit master..<mybranch>
Run Code Online (Sandbox Code Playgroud)

or

git log --no-merges --graph --oneline --decorate master..<mybranch>
Run Code Online (Sandbox Code Playgroud)


Fre*_*ult 8

快速回答:

git log $(git merge-base master b2)..HEAD
Run Code Online (Sandbox Code Playgroud)

让我们说:

  1. 你有一个分支

  2. 做一些提交

  3. 您创建了一个名为b2的分支

  4. git log -n1; commit id是b2和master之间的合并基础

  5. b2做一些提交

  6. git log 将显示b2和master的日志历史记录

  7. 使用提交范围,如果您不熟悉这个概念,我邀请您谷歌或堆栈溢出 - 它,

    对于您的实际情况,您可以这样做

    git log commitID_FOO..comitID_BAR
    
    Run Code Online (Sandbox Code Playgroud)

    ".."是log命令的范围运算符.

    这意味着,以简单的形式,给我所有日志比commitID_FOO更新...

  8. 看看第4点,合并基础

    所以:git log COMMITID_mergeBASE..HEAD会告诉你差异

  9. Git可以为你检索合并基础

    git merge-base b2 master
    
    Run Code Online (Sandbox Code Playgroud)
  10. 最后你可以这样做:

    git log $(git merge-base master b2)..HEAD
    
    Run Code Online (Sandbox Code Playgroud)


Joh*_*ter 5

你可以尝试这样的事情:

#!/bin/bash

all_but()
{
    target="$(git rev-parse $1)"
    echo "$target --not"
    git for-each-ref --shell --format="ref=%(refname)" refs/heads | \
    while read entry
    do
        eval "$entry"

        test "$ref" != "$target" && echo "$ref"
    done
}

git log $(all_but $1)
Run Code Online (Sandbox Code Playgroud)

或者,借用Git 用户手册中的配方

#!/bin/bash
git log $1 --not $( git show-ref --heads | cut -d' ' -f2 | grep -v "^$1" )
Run Code Online (Sandbox Code Playgroud)