Skip to content

Commit dd4fbd5

Browse files
nejchJohnVillalovos
authored andcommitted
feat: add support for merge_base API
1 parent 13d4927 commit dd4fbd5

File tree

4 files changed

+47
-1
lines changed

4 files changed

+47
-1
lines changed

docs/cli-examples.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,12 @@ Define the status of a commit (as would be done from a CI tool for example):
302302
--target-url http://server/build/123 \
303303
--description "Jenkins build succeeded"
304304
305+
Get the merge base for two or more branches, tags or commits:
306+
307+
.. code-block:: console
308+
309+
gitlab project repository-merge-base --id 1 --refs bd1324e2f,main,v1.0.0
310+
305311
Artifacts
306312
---------
307313

docs/gl_objects/projects.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@ Compare two branches, tags or commits::
231231
for file_diff in result['diffs']:
232232
print(file_diff)
233233

234+
Get the merge base for two or more branches, tags or commits::
235+
236+
commit = project.repository_merge_base(['main', 'v1.2.3', 'bd1324e2f'])
237+
234238
Get a list of contributors for the repository::
235239

236240
contributors = project.repository_contributors()

gitlab/v4/objects/repositories.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import gitlab
1111
from gitlab import cli
1212
from gitlab import exceptions as exc
13-
from gitlab import utils
13+
from gitlab import types, utils
1414

1515
if TYPE_CHECKING:
1616
# When running mypy we use these as the base classes
@@ -246,6 +246,32 @@ def repository_archive(
246246
result, streamed, action, chunk_size, iterator=iterator
247247
)
248248

249+
@cli.register_custom_action("Project", ("refs",))
250+
@exc.on_http_error(exc.GitlabGetError)
251+
def repository_merge_base(
252+
self, refs: List[str], **kwargs: Any
253+
) -> Union[Dict[str, Any], requests.Response]:
254+
"""Return a diff between two branches/commits.
255+
256+
Args:
257+
refs: The refs to find the common ancestor of. Multiple refs can be passed.
258+
**kwargs: Extra options to send to the server (e.g. sudo)
259+
260+
Raises:
261+
GitlabAuthenticationError: If authentication is not correct
262+
GitlabGetError: If the server failed to perform the request
263+
264+
Returns:
265+
The common ancestor commit (*not* a RESTObject)
266+
"""
267+
path = f"/projects/{self.encoded_id}/repository/merge_base"
268+
query_data, _ = utils._transform_types(
269+
data={"refs": refs},
270+
custom_types={"refs": types.ArrayAttribute},
271+
transform_data=True,
272+
)
273+
return self.manager.gitlab.http_get(path, query_data=query_data, **kwargs)
274+
249275
@cli.register_custom_action("Project")
250276
@exc.on_http_error(exc.GitlabDeleteError)
251277
def delete_merged_branches(self, **kwargs: Any) -> None:

tests/functional/api/test_repository.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,13 @@ def test_revert_commit(project):
174174
with pytest.raises(gitlab.GitlabRevertError):
175175
# Two revert attempts should raise GitlabRevertError
176176
commit.revert(branch="main")
177+
178+
179+
def test_repository_merge_base(project):
180+
refs = [commit.id for commit in project.commits.list(all=True)]
181+
182+
commit = project.repository_merge_base(refs)
183+
assert commit["id"] in refs
184+
185+
with pytest.raises(gitlab.GitlabGetError, match="Provide at least 2 refs"):
186+
commit = project.repository_merge_base(refs[0])

0 commit comments

Comments
 (0)