首页 > 解决方案 > GitHub/GitLab REST API - 将分支直接合并到 Master

问题描述

假设我们有 Master、develop、feature1、feature2、feature3、bugfixing1、bugfixing2 等分支...

GitLab/GitHub 是否提供 API 让我们知道哪些分支直接合并到了 Master 分支中?

注意:我们正在尝试实现一个工具来确定哪些分支直接合并到主分支中。与 Git 交谈的一种方式是 REST API。

例子:

非常感谢你。

标签: gitrestapigithubgitlab

解决方案


TL;博士

不要为此使用 REST API。1 Git 没有。使用git branch --merged. 但请注意它的实际作用


1如果您确实使用了一个,请注意它几乎可以肯定只是使用git branch --merged或内部等效项。另外,请注意托管服务器 A 上的 REST API 与托管服务器 B 上的不同,后者与托管服务器 C 上的不同。托管服务器 D 没有针对它的 API。但是 Git 可以在本地完成它,并且无论您的托管服务器如何,这都可以工作。


Git 中的分支不存在。

好吧,这显然不是真的:它们确实存在。但在一个非常重要的方面,它们并不重要。只有提交才是真正重要的。分支名称主要用于查找提交。合并是通过合并提交来完成的,即使您在流程中使用了分支名称。所以诀窍是先问关于提交的问题。只有稍后,你得到这个答案之后,你才应该开始想知道分支名称。

因此,通常不可能说出合并了哪个分支。但是很容易判断是否合并了某个特定的提交。而且,一个分支名称,比如masteror develop总是准确地标识一个提交。这只是master标识随时间变化的特定提交。develop标识的特定提交也是如此,feature2标识的特定提交也是如此,依此类推。

从图形上看,这些东西可能看起来像这样:

       I--J   <-- feature1
      /
...--H   <-- master
      \
       K--L   <-- feature2

在这里,既没有 feature1 也没有 feature2合并到master。这是因为由 name 标识的提交feature1,即 commit J—<code>J 代表它的实际哈希 ID,它是一些大而丑陋的字母和数字字符串 — 不是commit的祖先H,它是由名字master。但是,master 合并到feature1中,因为 commitH是 commit 的祖先J。同样,master被合并到feature2.

如果我们现在使用:

git checkout master
git merge --ff-only feature1
git merge --no-ff feature2

在命令行上,一切正常,我们得到一个新的合并提交 M,所以名称master现在指向这个合并提交:

       I--J   <-- feature1
      /    \
...--H      M   <-- master
      \    /
       K--L   <-- feature2

请注意我们所做的只是向绘图添加一个提交:新提交M指向现有提交JL. 分支名称master现在标识 commit M,而不是 commit H

由于JL都是 的祖先M,但M不是其中任何一个的祖先,因此分支feature1feature2现在合并到master. 请注意,此时,我们可以删除名称feature1

       I--J
      /    \
...--H      M   <-- master
      \    /
       K--L   <-- feature2

CommitJ仍然是 commit 的祖先M,所以commit被合并了。但是分支feature1不再存在。使用Git没关系,但是现在,标识作为其祖先的提交的分支名称M列表不再包括feature1. 我们可以这样做feature2

       I--J
      /    \
...--H      M   <-- master
      \    /
       K--L

我们现在可以创建一个的分支名称,例如feature/short,指向 commit J

       I--J   <-- feature/short
      /    \
...--H      M   <-- master
      \    /
       K--L

CommitJ仍然是 commit 的祖先M,所以 branchfeature/short合并到 branch master

Git 本身——不是 GitHub 也不是 GitLab,只是普通的旧 Git——可以告诉你哪些分支名称指向的提交是某个其他分支名称的祖先:

git branch --merged master

首先找到 commit M,然后遍历所有分支名称(在这种情况下,feature/short是唯一剩下的其他分支名称)以查看这些分支名称标识的提交是否是 commit 的祖先M。目前,这是真的feature/short,所以git branch --merged将列出feature/short

但是,如果我们git checkout feature/short对其进行新的提交,我们会得到:

       I--J---N   <-- feature/short
      /    \
...--H      M   <-- master
      \    /
       K--L

CommitN不是commit的祖先所以 branch没有合并到 branch 。运行将不再列出。Mfeature/shortmastergit branch --merged masterfeature/short

远程跟踪名称

要从您自己的 Git 存储库而不是某些托管服务 API 执行此操作,您将需要从托管服务克隆 Git 存储库。当您进行这样的克隆时,除非您使用--mirror, 2您的 Git 将重命名 它们的分支。您将拥有一系列远程跟踪名称,而不是分支名称,其形式为origin/masterorigin/developorigin/feature1等。

在将他们的提交复制到您的存储库并将其分支名称重命名为您的远程跟踪名称后,您自己的 Git 将在您的存储库中创建一个分支名称,指向您从他们那里获得的现有提交之一。默认情况下,您的 Git 将创建master指向与它们相同的提交的origin/master. 但是,随着时间的推移,它们的分支名称会发生​​变化:它们将指向更新的、更好用的提交。您将需要运行:

git fetch

或者:

git fetch --prune

让您的 Git 接收他们的新提交并更新您的远程跟踪名称。使用--prune将确保您的 Git删除旧的、陈旧的远程跟踪名称:例如,在他们的 Git 删除了他们的 之后feature/short,您的 Git 将继续拥有origin/feature/short,直到您在打开修剪的情况下进行提取。然后你的 Git 会注意到他们没有feature/short删除你的origin/feature/short.

您在这里要做的是使用:

git branch --merged -r origin/master

-r选项告诉git branch您查看您的远程跟踪名称而不是您的分支名称。origin/master告诉你的 Git 使用你的-origin/master他们master在你最后一次获取的更新时 - 识别的提交。因此,现在您将获得一个类似远程跟踪名称的列表origin/feature1origin/master这些名称指向作为您所指向的提交的祖先的提交origin/master


2您不太可能想使用--mirror.


推荐阅读