Skip to content

Commit

Permalink
Implement Branch.cherry_pick() (#7348)
Browse files Browse the repository at this point in the history
* Implement `Branch.cherry_pick()`

As a minimal wrapper around `BranchesApi.cherry_pick()`. Since the API
returns the created commit , we return the corresponding SDK wrapper
model constructed directly from the API response.

Adds an integration test cherry-picking a commit onto main, checking
metadata and message equality.

* Tweak parent_number description in cherry-pick API and Python docstring

* Add `force` option to `Branch.cherry_pick()`

In line with the cherry pick API, currently a no-op.

* Revert "Add `force` option to `Branch.cherry_pick()`"

This reverts commit fbe4027.

* Add line break to parent_number docstring to satisfy pylint

* fix generated docs

* fix generated docs 2

* fix generated docs 3

---------

Co-authored-by: Nir Ozery <[email protected]>
  • Loading branch information
nicholasjng and N-o-Z authored Jan 29, 2024
1 parent 33ae8fe commit 3943a40
Show file tree
Hide file tree
Showing 14 changed files with 57 additions and 19 deletions.
4 changes: 2 additions & 2 deletions api/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -537,8 +537,8 @@ components:
parent_number:
type: integer
description: |
when cherry-picking a merge commit, the parent number (starting from 1) relative to which to perform the diff.
The destination branch is parent 1, which is the default behaviour.
When cherry-picking a merge commit, the parent number (starting from 1) with which to perform the diff.
The default branch is parent 1.
force:
type: boolean
default: false
Expand Down
4 changes: 2 additions & 2 deletions clients/java-legacy/api/openapi.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion clients/java-legacy/docs/CherryPickCreation.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions clients/java/api/openapi.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion clients/java/docs/CherryPickCreation.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion clients/python-legacy/docs/CherryPickCreation.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 19 additions & 1 deletion clients/python-wrapper/lakefs/branch.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from lakefs.object import StoredObject
from lakefs.import_manager import ImportManager
from lakefs.reference import Reference, ReferenceType, generate_listing
from lakefs.models import Change
from lakefs.models import Change, Commit
from lakefs.exceptions import (
api_exception_handler,
ConflictException,
Expand Down Expand Up @@ -124,6 +124,24 @@ def get_commit(self):
self._commit = None
return super().get_commit()

def cherry_pick(self, reference: ReferenceType, parent_number: Optional[int] = None) -> Commit:
"""
Cherry-pick a given reference onto the branch.
:param reference: ID of the reference to cherry-pick.
:param parent_number: When cherry-picking a merge commit, the parent number (starting from 1)
with which to perform the diff. The default branch is parent 1.
:return: The cherry-picked commit at the head of the branch.
:raise NotFoundException: If either the repository or target reference do not exist.
:raise NotAuthorizedException: If the user is not authorized to perform this operation.
:raise ServerException: For any other errors.
"""
ref = reference if isinstance(reference, str) else reference.id
cherry_pick_creation = lakefs_sdk.CherryPickCreation(ref=ref, parent_number=parent_number)
with api_exception_handler():
res = self._client.sdk_client.branches_api.cherry_pick(self._repo_id, self._id, cherry_pick_creation)
return Commit(**res.dict())

def create(self, source_reference: ReferenceType, exist_ok: bool = False) -> Branch:
"""
Create a new branch in lakeFS from this object
Expand Down
20 changes: 20 additions & 0 deletions clients/python-wrapper/tests/integration/test_branch.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,26 @@ def test_revert(setup_repo):
assert fd.read() == initial_content


def test_cherry_pick(setup_repo):
_, repo = setup_repo
main_branch = repo.branch("main")
test_branch = repo.branch("testest").create("main")

initial_content = "test_content"
test_branch.object("test_object").upload(initial_content)
testcommit = test_branch.commit("test_commit", {"test_key": "test_value"}).get_commit()

cherry_picked = main_branch.cherry_pick(test_branch.head)
assert test_branch.object("test_object").exists()
# SHAs are not equal, so we exclude them from eq checks.
assert cherry_picked.message == testcommit.message
# cherry-picks have origin and source ref name attached as metadata (at minimum),
# so we only check that the additional user-supplied metadata is present.
assert set(testcommit.metadata.items()) <= set(cherry_picked.metadata.items())
# check that the cherry-pick origin is exactly testest@HEAD.
assert cherry_picked.metadata["cherry-pick-origin"] == testcommit.id


def test_reset_changes(setup_repo):
_, repo = setup_repo
test_branch = repo.branch("main")
Expand Down
2 changes: 1 addition & 1 deletion clients/python/docs/CherryPickCreation.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion clients/python/lakefs_sdk/models/cherry_pick_creation.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions docs/assets/js/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -537,8 +537,8 @@ components:
parent_number:
type: integer
description: |
when cherry-picking a merge commit, the parent number (starting from 1) relative to which to perform the diff.
The destination branch is parent 1, which is the default behaviour.
When cherry-picking a merge commit, the parent number (starting from 1) with which to perform the diff.
The default branch is parent 1.
force:
type: boolean
default: false
Expand Down

0 comments on commit 3943a40

Please sign in to comment.