使用Git,显示在一个特定分支上仅* *存在的所有提交,而不是*任何*其他

时间:2011-04-19 17:34:24

标签: git

给定一个分支,我希望在该分支上看到 only 的提交列表。在this question中,我们讨论了查看哪些提交在一个分支上而不是一个或多个指定的其他分支的方法。

这略有不同。我想看看哪些提交在一个分支上,但不在任何其他分支上。

用例是一种分支策略,其中某些分支只应合并到,而不是直接在其上提交。这将用于检查是否已在“仅合并”分支上直接进行任何提交。

编辑:以下是设置虚拟git repo以进行测试的步骤:

git init
echo foo1 >> foo.txt
git add foo.txt
git commit -am "initial valid commit"
git checkout -b merge-only
echo bar >> bar.txt
git add bar.txt
git commit -am "bad commit directly on merge-only"
git checkout master
echo foo2 >> foo.txt 
git commit -am "2nd valid commit on master"
git checkout merge-only 
git merge master

只有直接在仅合并分支上进行的消息“直接在仅合并时提交错误”的提交才会显示。

7 个答案:

答案 0 :(得分:67)

我的同事刚刚找到了这个优雅解决方案git log --first-parent --no-merges。在您的示例中,当然初始提交仍会显示。

请仔细阅读:这个答案并没有完全回答这个问题,因为初始提交仍然显示出来。另一方面,许多来到这里的人似乎找到了他们正在寻找的答案。在投票前请考虑这一点。请参阅评论以供讨论。

答案 1 :(得分:25)

由亲爱的朋友Redmumba提供:

git log --no-merges origin/merge-only \
    --not $(git for-each-ref --format="%(refname)" refs/remotes/origin |
    grep -Fv refs/remotes/origin/merge-only)

...其中origin/merge-only是您的远程仅合并分支名称。如果使用仅限本地的git仓库,请将refs/remotes/origin替换为refs/heads,并将远程分支名称origin/merge-only替换为本地分支名称merge-only,即:

git log --no-merges merge-only \
    --not $(git for-each-ref --format="%(refname)" refs/heads |
    grep -Fv refs/heads/merge-only)

答案 2 :(得分:14)

public enum Result {
    case None
    case BibliographyItems([BibliographyItem])
    case InlineMathFragments([InlineMathFragment])
    case Equations([Equation])
    case BlockElements([BlockElement])
    case InlineElements([InlineElement])
}

这将显示您分支中的所有提交。

答案 3 :(得分:12)

也许这可能会有所帮助:

git show-branch

答案 4 :(得分:7)

试试这个:

git rev-list --all --not $(git rev-list --all ^branch)

基本上git rev-list --all ^branch获取不在分支中的所有修订,然后是repo中的所有修订,并减去上一个列表,即分支中的修订

在@Brian的评论之后:

来自git rev-list的文档:

List commits that are reachable by following the parent links from the given commit(s)

所以像git rev-list A这样的命令,其中A是一个提交,它将列出可从包含A的A到达的提交。

考虑到这一点,比如

git rev-list --all ^A

将列出无法从A

访问的提交

所以git rev-list --all ^branch将列出从分支的尖端无法访问的所有提交。这将删除分支中的所有提交,或者换句话说,仅在其他分支中提交。

现在让我们来git rev-list --all --not $(git rev-list --all ^branch)

这就像git rev-list --all --not {commits only in other branches}

因此,我们要列出all无法访问的all commits only in other branches

仅在分支中提交的提交集。我们举一个简单的例子:

             master

             |

A------------B

  \

   \

    C--------D--------E

                      |

                      branch

这里的目标是获得D和E,提交不在任何其他分支中。

git rev-list --all ^branch只给B

现在,git rev-list --all --not B就是我们的目标。这也是git rev-list -all ^B - 我们希望所有提交都无法从B中获取。在我们的例子中,它是D和E.这就是我们想要的。

希望这能解释命令如何正常工作。

评论后编辑:

git init
echo foo1 >> foo.txt
git add foo.txt
git commit -am "initial valid commit"
git checkout -b merge-only
echo bar >> bar.txt
git add bar.txt
git commit -am "bad commit directly on merge-only"
git checkout master
echo foo2 >> foo.txt 
git commit -am "2nd valid commit on master"

完成上述步骤后,如果您执行git rev-list --all --not $(git rev-list --all ^merge-only),您将收到您正在寻找的提交 - "bad commit directly on merge-only"

但是一旦你在步骤git merge master中完成了最后一步,命令将不会给出预期的输出。因为到目前为止还没有在merge中没有的提交,因为master中的一个额外提交也已合并为仅合并。因此git rev-list --all ^branch会给出空结果,因此git rev-list -all --not $(git rev-list --all ^branch)会在仅合并中提供所有提交。

答案 5 :(得分:7)

@Prakash回答有效。为了清楚起见......

git checkout feature-branch
git log master..HEAD

列出了功能分支上的提交,但没有列出上游分支(通常是主分支)。

答案 6 :(得分:2)

接受答案的另一种变体,与master

一起使用

git log origin/master --not $(git branch -a | grep -Fv master)

过滤除master之外的任何分支中发生的所有提交。

相关问题