Git log to get commits only for a specific branch
我想列出仅属于特定分支的所有提交。
通过以下内容,它列出了分支中的所有提交,但也列出了父(主)的提交
1 | git log mybranch |
我找到的另一个选项是排除master可以访问的提交并给我我想要的东西,但我想避免需要知道其他分支名称。
1 | git log mybranch --not master |
我试图使用
1 | git log mybranch --not $(git for-each-ref --format '^%(refname:short)' refs/heads/) |
更新:
我正在测试我刚才发现的一个新选项,直到现在看来这可能是我想要的:
1 | git log --walk-reflogs mybranch |
更新(2013-02-13T15:08):
--walk-reflogs选项很好,但我检查了reflogs的到期时间(默认为90天,gc.reflogExpire)。
我想我找到了我想要的答案:
1 | git log mybranch --not $(git for-each-ref --format='%(refname)' refs/heads/ | grep -v"refs/heads/mybranch") |
我只是从可用分支列表中删除当前分支,并使用该列表从日志中排除。这样我只能获得mybranch才能达到的提交。
听起来你应该使用
1 | git cherry -v develop mybranch |
这将显示mybranch中包含的所有提交,但不会显示。如果你不使用最后一个选项(mybranch),它将比较当前分支。
正如VonC指出的那样,您总是将您的分支与另一个分支进行比较,因此请了解您的分支,然后选择要与哪个分支进行比较。
BUT I would like to avoid the need of knowing the other branches names.
我不认为这是可能的:Git中的分支总是基于另一个或至少在另一个提交上,如"git diff中显示的不够":
您需要一个日志参考点来显示正确的提交。
如"GIT - 我从何处分支?"中所述:
branches are simply pointers to certain commits in a DAG
因此,即使
为了找到该引用(分支的来源),您只能解析提交并查看它们所在的分支,如下所示:
- "Git:找出提交来自哪个分支"。
- "我怎样才能看到另一个分支从哪个分支分叉?"
我终于找到了做OP想要的方法。它很简单:
1 | git log --graph [branchname] |
该命令将以图形格式显示可从提供的分支访问的所有提交。但是,您可以通过查看提交图表轻松过滤该分支上的所有提交,其中
例如,让我们看看下面的cakephp GitHub repo上的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | D:\Web Folder\cakephp>git log --graph master * commit 8314c2ff833280bbc7102cb6d4fcf62240cd3ac4 |\ Merge: c3f45e8 0459a35 | | Author: José Lorenzo Rodríguez <[email protected]> | | 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 <[email protected]> | | 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 <[email protected]> | | 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 <[email protected]> |/| 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 <[email protected]> | | Date: Mon Aug 29 17:43:29 2016 -0400 | | | | Fix `@since` in new files docblocks | | |
如您所见,只有提交
以下shell命令应该执行您想要的操作:
1 | git log --all --not $(git rev-list --no-walk --exclude=refs/heads/mybranch --all) |
注意事项
如果
1 2 3 4 | git log --all --not $(git rev-list --no-walk \ --exclude=refs/heads/mybranch \ --exclude=HEAD \ --all) |
但是,除非
同样,如果您有一个名为
1 2 3 4 | git log --all --not $(git rev-list --no-walk \ --exclude=refs/heads/mybranch \ --exclude=refs/remotes/origin/mybranch \ --all) |
如果远程分支是远程存储库的默认分支(通常仅对
1 2 3 4 5 | git log --all --not $(git rev-list --no-walk \ --exclude=refs/heads/mybranch \ --exclude=refs/remotes/origin/mybranch \ --exclude=refs/remotes/origin/HEAD \ --all) |
如果您已检出分支,并且有远程分支,并且远程分支是远程存储库的默认分支,那么您最终排除了很多:
1 2 3 4 5 6 | 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 bug?
我希望以下工作:
1 | git log --all --not --exclude=refs/heads/mybranch --all |
但事实并非如此。我猜这是Git中的一个错误,但也许是故意的。
快速回答:
1 | git log $(git merge-base master b2)..HEAD |
让我们说:
你有一个主分支
做一些提交
您创建了一个名为b2的分支
做
在b2做一些提交
使用提交范围,如果您不熟悉这个概念,我邀请您谷歌或堆栈溢出 - 它,
对于您的实际情况,您可以这样做
1 | git log commitID_FOO..comitID_BAR |
".."是log命令的范围运算符。
这意味着,以简单的形式,给我所有日志比commitID_FOO更新...
看看第4点,合并基础
所以:
Git可以为你检索合并基础
1 | git merge-base b2 master |
最后你可以这样做:
1 | git log $(git merge-base master b2)..HEAD |
这将输出当前分支上的提交。如果传递任何参数,它只输出哈希值。
git_show_all_commits_only_on_this_branch
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | #!/bin/bash function show_help() { ME=$(basename $0) IT=$(cat <<EOF usage: $ME {NEWER_BRANCH} {OLDER_BRANCH} {VERBOSE} Compares 2 different branches, and lists the commits found only in the first branch (newest branch). e.g. $ME -> default. compares current branch to master $ME B1 -> compares branch B1 to master $ME B1 B2 -> compares branch B1 to B2 $ME B1 B2 V -> compares branch B1 to B2, and displays commit messages ) echo"$IT" exit } if ["$1" =="help" ] then show_help fi # Show commit msgs if any arg passed for arg 3 if ["$3" ] then OPT="-v" fi # get branch names OLDER_BRANCH=${2:-"master"} if [ -z"$1" ] then NEWER_BRANCH=$(git rev-parse --abbrev-ref HEAD) else NEWER_BRANCH=$1 fi if ["$NEWER_BRANCH" =="$OLDER_BRANCH" ] then echo" Please supply 2 different branches to compare!" show_help fi OUT=$(\git cherry $OPT $OLDER_BRANCH $NEWER_BRANCH) if [ -z"$OUT" ] then echo"No differences found. The branches $NEWER_BRANCH and $OLDER_BRANCH are in sync." exit; fi if ["$OPT" =="-v" ] then echo"$OUT" else echo"$OUT" | awk '{print $2}' fi |
你可以尝试这样的事情:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #!/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) |
或者,借用Git用户手册中的配方:
1 2 | #!/bin/bash git log $1 --not $( git show-ref --heads | cut -d' ' -f2 | grep -v"^$1" ) |
1 | git rev-list --exclude=master --branches --no-walk |
将列出每个不是
1 | git rev-list master --not $(git rev-list --exclude=master --branches --no-walk) |
将列出
排序对于为提交选择设置过滤器管道的选项很重要,因此
在我的情况下,我们正在使用Git Flow和GitHub。您需要做的就是:将您的功能分支与GitHub上的开发分支进行比较。
它将显示仅对您的功能分支进行的提交。
例如:
https://github.com/your_repo/compare/develop...feature_branch_name
我发现这种方法相对容易。
结账到分行而不是
跑
1 | git rev-list --simplify-by-decoration -2 HEAD |
这将只提供两个SHA:
1)分支的最后提交[C1]
2)并将父级提交给分支的第一次提交[C2]
现在跑
1 | git log --decorate --pretty=oneline --reverse --name-status <C2>..<C1> |
这里C1和C2是你运行第一个命令时会得到的两个字符串。在第二个命令中不使用<>放置这些值。
这将给出分支内文件更改历史列表。