git 是否可以从 Github 网站或 API 获取合并到一个分支的列表?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21623699/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 17:42:32  来源:igfitidea点击:

Is it possible to get a list of merges into a branch from the Github website OR API?

gitgithubbranching-and-merginggithub-api

提问by andy

In our workflow, no "direct" commits are made into the master branch. The master branch only receives merges from Pull Requests.

在我们的工作流程中,没有对主分支进行“直接”提交。master 分支只接收来自 Pull Requests 的合并。

We can think of each merge then as a new feature added to the master branch.

我们可以将每次合并视为添加到主分支的新功能。

So I'd like to get a list of merges into master, as a way to visualize the blocks of features added into the product over time.

所以我想得到一个合并到 master 的列表,作为一种可视化随着时间的推移添加到产品中的功能块的方法。

Does git or the Github API expose this query, or do I have to parse raw commits?

git 或 Github API 是否公开此查询,或者我是否必须解析原始提交?

回答by Fábio Batista

I use the following script:

我使用以下脚本:

git log --merges --first-parent master \
        --pretty=format:"%h %<(10,trunc)%aN %C(white)%<(15)%ar%Creset %C(red bold)%<(15)%D%Creset %s"

Explaining each argument:

解释每个论点:

  • --merges: only "merge" commits (more than 1 parent);
  • --first-parent master: only merges applied to master. This removes the entries where someone merged masterinto their branches;
  • --pretty-format: applies the following formatting:
    • %h: the commit short hash;
    • %<(10,trunc)%aN: author name, truncated at 10 chars;
    • %<(15)%ar: the relative commit time, padded to 15 chars;
    • %<(15)%D: the tag names, also padded to 15 chars;
    • %s: first line of the commit message.
  • --merges:仅“合并”提交(超过 1 个父项);
  • --first-parent master: 仅合并应用于master. 这将删除某人合并master到其分支的条目;
  • --pretty-format:应用以下格式:
    • %h:提交短哈希;
    • %<(10,trunc)%aN:作者姓名,截断为 10 个字符;
    • %<(15)%ar: 相对提交时间,填充为 15 个字符;
    • %<(15)%D:标签名称,也填充为 15 个字符;
    • %s:提交消息的第一行。

The result is pretty satisfying:

结果非常令人满意:

terminal image of the command output

命令输出的终端图像

回答by nulltoken

Git exposes such feature through the git logcommand. This command accepts some switches that filter the rendered commits according to the number of parents commits.

Git 通过git log命令公开了这样的特性。此命令接受一些开关,这些开关根据父提交的数量过滤呈现的提交。

One of them would fit your request:

其中之一将符合您的要求:

  • --mergesPrint only merge commits. This is exactly the same as --min-parents=2.
  • --merges只打印合并提交。这与--min-parents=2.

The following shows the merge commits (ie. commits with more than one parent) reachable from the vNextbranch of the LibGit2Sharpproject

下面显示了可从LibGit2Sharp项目的vNext分支访问的合并提交(即具有多个父级的提交)

$ git log vNext --merges --oneline
090b2de Merge pull request #348 from jamill/credential_callback_fix
0332c35 Merge pull request #260 from ben/great-renaming
3191c1b Merge pull request #239 from ben/libgit2-upgrade-81eecc3
1d544e8 Merge branch 'vNext'
238d259 Merge remote-tracking branch 'origin/master'

Update

更新

Leveraging the same output through the GitHub API is possible, but would be somewhat more complex.

通过 GitHub API 利用相同的输出是可能的,但会稍微复杂一些。

This would require to retrieve all the commits from a branch, paginating through all the results (in order to retrieve all the commits meta data) while filtering out the ones that only expose only one parent node.

这将需要从分支中检索所有提交,对所有结果进行分页(以便检索所有提交元数据),同时过滤掉仅公开一个父节点的提交。

As a starting point, the following url shows the latest 30 commmits of the vNextbranch.

作为起点,以下 url 显示了vNext分支的最新 30 次提交。

回答by VonC

If you want to focus on merge commits which are the result of pull requests being merged, you might consider the new Git 2.27 (Q2 2020) git log --show-pullsoption.

如果您想专注于合并拉取请求的结果的合并提交,您可以考虑新的 Git 2.27(2020 年第二季度)git log --show-pulls选项。

"git log" has learned "--show-pulls" that helps pathspec limited history views; a merge commit that takes the whole change from a side branch, which is normally omitted from the output, is shown in addition to the commits that introduce real changes.

git log”已经学会了“ --show-pulls”,这有助于路径规范限制历史视图;除了引入实际更改的提交之外,还显示了从侧分支获取整个更改的合并提交(通常从输出中省略)。

See commit 8d049e1(10 Apr 2020) by Derrick Stolee (derrickstolee).
(Merged by Junio C Hamano -- gitster--in commit 9af3a7c, 22 Apr 2020)

请参阅Derrick Stolee ( )提交的 8d049e1(2020 年 4 月 10 日(由Junio C Hamano合并-- --提交 9af3a7c 中,2020 年 4 月 22 日)derrickstolee
gitster

revision: --show-pulls adds helpful merges

Signed-off-by: Derrick Stolee

The default file history simplification of "git log -- <path>" or "git rev-list -- <path>" focuses on providing the smallest set of commits that first contributed a change.
The revision walk greatly restricts the set of walked commits by visiting only the first TREESAME parent of a merge commit, when one exists. This means that portions of the commit-graph are not walked, which can be a performance benefit, but can also "hide" commits that added changes but were ignored by a merge resolution.

revision: --show-pulls 添加有用的合并

签字人:德里克·斯托利

" git log -- <path>" 或 " git rev-list -- <path>"的默认文件历史简化侧重于提供首先贡献更改的最小提交集。
当一个合并提交存在时,修订遍历通过仅访问合并提交的第一个 TREESAME 父项来极大地限制遍历提交的集合。这意味着提交图的部分不会被遍历,这可能是一个性能优势,但也可以“隐藏”添加更改但被合并解决方案忽略的提交。

(TREESAME: no discernible difference for the pathspec among the respective trees; "the same between trees")

TREESAME:各个树之间的路径规格没有明显差异;“树之间相同”)

The --full-historyoption modifies this by walking all commits and reporting a merge commit as "interesting" if it has anyparent that is not TREESAME.
This tends to be an over-representation of important commits, especially in an environment where most merge commits are created by pull request completion.

Suppose we have a commit Aand we create a commit Bon top that changes our file.
When we merge the pull request, we create a merge commit M.
If no one else changed the file in the first-parent history between Mand A, then Mwill not be TREESAME to its first parent, but will be TREESAME to B. Thus, the simplified history will be "B". However, M will appear in the --full-historymode.

However, suppose that a number of topics T1, T2, ..., Tnwere created based on commits C1, C2, ..., Cnbetween Aand Mas follows:

A----C1----C2--- ... ---Cn----M------P1---P2--- ... ---Pn
 \     \     \            \  /      /    /            /
  \     \__.. \            \/ ..__T1    /           Tn
   \           \__..       /\     ..__T2           /
    \_____________________B  \____________________/

If the commits T1, T2, ... Tndid not change the file, then all of P1through Pnwill be TREESAME to their first parent, but not TREESAME to their second.
This means that all of those merge commits appear in the --full-historyview, with edges that immediately collapse into the lower history without introducing interesting single-parent commits.

The --simplify-mergesoption was introduced to remove these extra merge commits.
By noticing that the rewritten parents are reachable from their first parents, those edges can be simplified away.
Finally, the commits now look like single-parent commits that are TREESAME to their "only" parent. Thus, they are removed and this issue does not cause issues anymore.

However, this also ends up removing the commit Mfrom the history view!
Even worse, the --simplify-mergesoption requires walking the entire history before returning a single result.

Many Git users are using Git alongside a Git service that provides code storage alongside a code review tool commonly called "Pull Requests" or "Merge Requests" against a target branch.

When these requests are accepted and merged, they typically create a merge commit whose first parent is the previous branch tip and the second parent is the tip of the topic branch used for the request.
This presents a valuable order to the parents, but also makes that merge commit slightly special. Users may want to see not only which commits changed a file, but which pull requests merged those commits into their branch.
In the previous example, this would mean the users want to see the merge commit "M" in addition to the single- parent commit "C".

Users are even more likely to want these merge commits when they use pull requests to merge into a feature branch before merging that feature branch into their trunk.

In some sense, users are asking for the "first" merge commit to bring in the change to their branch. As long as the parent order is consistent, this can be handled with the following rule:

"Include a merge commit if it is not TREESAME to its first parent, but is TREESAME to a later parent."

These merges look like the merge commits that would result from running "git pull <topic>" on a main branch.
Thus, the option to show these commits is called "--show-pulls".
This has the added benefit of showing the commits created by closing a pull request or merge request on any of the Git hosting and code review platforms.

To test these options, extend the standard test example to include a merge commit that is not TREESAME to its first parent. It is surprising that that option was not already in the example, as it is instructive.

In particular, this extension demonstrates a common issue with file history simplification. When a user resolves a merge conflict using "-Xours" or otherwise ignoring one side of the conflict, they create a TREESAME edge that probably should not be TREESAME.
This leads users to become frustrated and complain that "my change disappeared!"

In my experience, showing them history with --full-historyand --simplify-mergesquickly reveals the problematic merge.
As mentioned, this option is expensive to compute.

The --show-pullsoption mightshow the merge commit (usually titled "resolving conflicts") more quickly.
Of course, this depends on the user having the correct parent order, which is backwards when using "git pull master" from a topic branch.

There are some special considerations when combining the --show-pullsoption with --simplify-merges.
This requires adding a new PULL_MERGEobject flag to store the information from the initial TREESAME comparisons. This helps avoid dropping those commits in later filters. This is covered by a test, including how the parents can be simplified. Since "struct object" has already ruined its 32-bit alignment by using 33 bits across parsed, type, and flags member, let's not make it worse.

--full-history选项通过遍历所有提交并将合并提交报告为“有趣”来修改它,如果它有任何不是 TREESAME 的父提交。
这往往是对重要提交的过度表示,尤其是在大多数合并提交是通过拉取请求完成创建的环境中。

假设我们有一个提交,A并且我们B在顶部创建了一个提交来更改我们的文件。
当我们合并拉取请求时,我们创建了一个合并提交M
如果没有其他人在M和之间更改第一父历史记录中的文件A,则不M会将 TREESAME 变为其第一个父,而是将 TREESAME 变为B。因此,简化的历史将是“ B”。但是,M 将出现在--full-history模式中。

但是,假设有许多主题T1, T2, ...,Tn是基于 commits C1, C2, ..., Cnbetween Aand之间创建的,M如下所示:

A----C1----C2--- ... ---Cn----M------P1---P2--- ... ---Pn
 \     \     \            \  /      /    /            /
  \     \__.. \            \/ ..__T1    /           Tn
   \           \__..       /\     ..__T2           /
    \_____________________B  \____________________/

如果 commits T1, T2, ...Tn没有改变文件,那么所有的P1通过Pn将是 TREESAME 到他们的第一个父级,但不是 TREESAME 到他们的第二个。
这意味着所有这些合并提交都出现在--full-history视图中,边缘会立即折叠到较低的历史记录中,而不会引入有趣的单父提交。

--simplify-merges引入了该选项以删除这些额外的合并提交。
通过注意到重写的父节点可以从它们的第一个父节点到达,这些边缘可以被简化。
最后,提交现在看起来像单父提交,它们对它们的“唯一”父提交是 TREESAME。因此,它们被删除,这个问题不再引起问题。

但是,这最终也会M从历史视图中删除提交!
更糟糕的是,该--simplify-merges选项需要在返回单个结果之前遍历整个历史记录。

许多 Git 用户将 Git 与 Git 服务一起使用,该服务提供代码存储以及针对目标分支的通常称为“拉取请求”或“合并请求”的代码工具。

当这些请求被接受并合并时,它们通常会创建一个合并提交,其第一个父级是前一个分支提示,第二个父级是用于请求的主题分支的提示
这为父级提供了一个有价值的命令,但也使合并提交变得有点特殊。用户可能不仅希望看到哪些提交更改了文件,还希望看到哪些拉取请求将这些提交合并到了他们的分支中
在前面的示例中,这意味着M除了单父提交“ C”之外,用户还希望看到合并提交“ ”。

当用户在将该功能分支合并到他们的主干之前使用拉取请求合并到一个功能分支时,他们更有可能想要这些合并提交。

从某种意义上说,用户要求“第一个”合并提交以将更改引入他们的分支。只要父订单一致,就可以使用以下规则处理:

“如果它不是 TREESAME 到其第一个父级,而是 TREESAME 到后来的父级,则包括合并提交。”

这些合并看起来像在git pull <topic>主分支上运行“ ”所产生的合并提交。
因此,显示这些提交的选项称为“ --show-pulls”。
这有一个额外的好处,即显示通过在任何 Git 托管和代码平台上关闭拉取请求或合并请求创建的提交。

要测试这些选项,请扩展标准测试示例以包含对其第一个父项不是 TREESAME 的合并提交。令人惊讶的是,该选项并未出现在示例中,因为它具有指导意义。

特别是,这个扩展展示了文件历史简化的一个常见问题。当用户使用“ -Xours”或以其他方式忽略冲突的一侧解决合并冲突时,他们会创建一个可能不应该是 TREESAME 的 TREESAME 边。
这导致用户变得沮丧并抱怨“我的更改消失了!”

根据我的经验,向他们展示历史--full-history--simplify-merges迅速揭示有问题的合并。
如前所述,此选项的计算成本很高。

--show-pulls选项可能会更快地显示合并提交(通常称为“解决冲突”)。
当然,这取决于具有正确父顺序的用户,当使用git pull master来自主题分支的“ ”时,这是向后的。

将该--show-pulls选项与--simplify-merges.
这需要添加一个新的PULL_MERGE对象标志来存储来自初始 TREESAME 比较的信息。这有助于避免在以后的过滤器中删除这些提交。这包含在测试中,包括如何简化父母。由于 " struct object" 已经通过在 parsed、type 和 flags 成员中使用 33 位破坏了它的 32 位对齐,所以我们不要让它变得更糟。

PULL_MERGEis used in revision.cwith the same value (1u<<15) as REACHABLEin commit-graph.c.
The REACHABLE flag is only used when writing a commit-graph file, and a revision walk using --show-pullsdoes not happen in the same process. Care must be taken in the future to ensure this remains the case.

PULL_MERGErevision.c与in相同的值 ( 1u<<15)REACHABLE使用commit-graph.c
REACHABLE 标志仅在编写提交图文件时使用,--show-pulls并且不会在同一进程中使用修订遍历。未来必须小心,以确保这种情况仍然存在。

Update Documentation/rev-list-options.txtwith significant details around this option. This requires updating the example in the History Simplification section to demonstrate some of the problems with TREESAME second parents.

更新Documentation/rev-list-options.txt有关此选项的重要详细信息。这需要更新历史简化部分中的示例以演示 TREESAME 第二个父代的一些问题。

See a full example here.

在此处查看完整示例