Skip to content

Commit

Permalink
Add support for slide-out=no in branch qualifiers (#793)
Browse files Browse the repository at this point in the history
  • Loading branch information
amalota authored Feb 6, 2023
1 parent ca74774 commit 0a8b636
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 14 deletions.
1 change: 1 addition & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## New in git-machete 3.15.0

- improved: formatting in `git machete` command prompts and outputs
- added: `slide-out=no` branch qualifier that control the slide-out behaviour of `git machete traverse`

## New in git-machete 3.14.3

Expand Down
10 changes: 5 additions & 5 deletions docs/source/cli_help/traverse.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,16 @@ It will pick up the walk from the current branch (unless ``--start-from=`` or ``
Unlike with e.g. ``git rebase``, there is no special ``--continue`` flag, as ``traverse`` is stateless
(doesn't keep a state of its own like ``git rebase`` does in ``.git/rebase-apply/``).

The rebase and push behavior of ``traverse`` can also be customized for each branch separately using *branch qualifiers*.
There are ``rebase=no`` and ``push=no`` qualifiers that can be used to opt out of default behavior (rebasing and pushing).
The qualifier can appear anywhere in the annotation but needs to be separated by a whitespace from any other character, e.g. ``some_annotation_text rebase=no push=no``.
Qualifiers can only be overwritten by manually editing ``.git/machete`` file or modifying it with ``git machete e[dit]`` or by updating annotations with ``git machete anno``.
The rebase, push and slide-out behaviors of ``traverse`` can also be customized for each branch separately using *branch qualifiers*.
There are ``rebase=no``, ``push=no`` and ``slide-out=no`` qualifiers that can be used to opt out of default behavior (rebasing, pushing and sliding the branch out of the dependency tree).
The qualifier can appear anywhere in the annotation but needs to be separated by a whitespace from any other character, e.g. ``some_annotation_text rebase=no push=no slide-out=no``.
Qualifiers can only be overwritten by manually editing ``.git/machete`` file or modifying it with ``git machete e[dit]``, or by updating annotations with ``git machete anno``.
Example machete file with branch qualifiers:

.. code-block::
master
develop rebase=no
develop rebase=no slide-out=no
my-branch PR #123
someone-elses-branch PR #124 rebase=no push=no
branch-for-local-experiments push=no
Expand Down
18 changes: 14 additions & 4 deletions git_machete/annotation.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import re
from typing import Callable

from git_machete import utils

Expand All @@ -13,11 +12,16 @@ def __init__(self, annotation: str):
self._annotation_without_qualifiers = annotation
self._rebase_text = ''
self._push_text = ''
self._slide_out_text = ''
self.rebase = True
self.push = True
self.slide_out = None

match_pattern: Callable[[str], str] = lambda text: f'.*\\b{text}=no\\b.*'
sub_pattern: Callable[[str], str] = lambda text: f'[ ]?{text}=no[ ]?'
def match_pattern(text: str) -> str:
return f'.*\\b{text}=no\\b.*'

def sub_pattern(text: str) -> str:
return f'[ ]?{text}=no[ ]?'

rebase_match = re.match(match_pattern('rebase'), annotation)
if rebase_match:
Expand All @@ -31,11 +35,17 @@ def __init__(self, annotation: str):
self._push_text = 'push=no'
self._annotation_without_qualifiers = re.sub(sub_pattern('push'), ' ', self._annotation_without_qualifiers)

slide_out_match = re.match(match_pattern('slide-out'), annotation)
if slide_out_match:
self.slide_out = False
self._slide_out_text = 'slide-out=no'
self._annotation_without_qualifiers = re.sub(sub_pattern('slide-out'), ' ', self._annotation_without_qualifiers)

def get_annotation_text_without_qualifiers(self) -> str:
return self._annotation_without_qualifiers.strip()

def get_qualifiers_text(self) -> str:
return f'{self._rebase_text.strip()} {self._push_text.strip()}'.replace(' ', ' ').strip()
return f'{self._rebase_text} {self._push_text} {self._slide_out_text}'.replace(' ', ' ').strip()


class Annotation:
Expand Down
2 changes: 2 additions & 0 deletions git_machete/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,8 @@ def traverse(

needs_slide_out: bool = self.__is_merged_to_upstream(
branch, opt_no_detect_squash_merges=opt_no_detect_squash_merges)
if needs_slide_out and branch in self.annotations:
needs_slide_out = self.annotations[branch].qualifiers.slide_out
s, remote = self.__git.get_strict_remote_sync_status(branch)
if s in (
SyncToRemoteStatuses.BEHIND_REMOTE,
Expand Down
10 changes: 5 additions & 5 deletions git_machete/generated_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1017,14 +1017,14 @@
Unlike with e.g. `git rebase`, there is no special `--continue` flag, as `traverse` is stateless
(doesn't keep a state of its own like `git rebase` does in `.git/rebase-apply/`).
The rebase and push behavior of `traverse` can also be customized for each branch separately using branch qualifiers.
There are `rebase=no` and `push=no` qualifiers that can be used to opt out of default behavior (rebasing and pushing).
The qualifier can appear anywhere in the annotation but needs to be separated by a whitespace from any other character, e.g. `some_annotation_text rebase=no push=no`.
Qualifiers can only be overwritten by manually editing `.git/machete` file or modifying it with `git machete e[dit]` or by updating annotations with `git machete anno`.
The rebase, push and slide-out behaviors of `traverse` can also be customized for each branch separately using branch qualifiers.
There are `rebase=no`, `push=no` and `slide-out=no` qualifiers that can be used to opt out of default behavior (rebasing, pushing and sliding the branch out of the dependency tree).
The qualifier can appear anywhere in the annotation but needs to be separated by a whitespace from any other character, e.g. `some_annotation_text rebase=no push=no slide-out=no`.
Qualifiers can only be overwritten by manually editing `.git/machete` file or modifying it with `git machete e[dit]`, or by updating annotations with `git machete anno`.
Example machete file with branch qualifiers:
<dim>
master
develop rebase=no
develop rebase=no slide-out=no
my-branch PR #123
someone-elses-branch PR #124 rebase=no push=no
branch-for-local-experiments push=no
Expand Down
4 changes: 4 additions & 0 deletions tests/mockers.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ def write_to_file(self, file_name: str, file_content: str) -> "GitRepositorySand
f.write(file_content)
return self

def merge(self, branch_name: str) -> "GitRepositorySandbox":
self.execute(f'git merge {branch_name}')
return self


class MockGitHubAPIState:
def __init__(self, pulls: List[Dict[str, Any]], issues: List[Dict[str, Any]] = None) -> None:
Expand Down
42 changes: 42 additions & 0 deletions tests/test_traverse.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,3 +472,45 @@ def test_traverse_qualifiers_no_rebase_no_push(self, mocker: Any) -> None:
o-ignore-trailing *
""",
)

def test_traverse_qualifiers_no_slide_out(self, mocker: Any) -> None:
mocker.patch('git_machete.utils.run_cmd', mock_run_cmd) # to hide git outputs in tests
self.setup_discover_standard_tree()

body: str = \
"""
develop
\tallow-ownership-link
\t\tbuild-chain
\tcall-ws slide-out=no
\t\tdrop-constraint
master
\thotfix/add-trigger
\t\tignore-trailing
"""

body = dedent(body).strip()
rewrite_definition_file(body)
self.repo_sandbox.check_out('develop').merge('call-ws')

launch_command("traverse", "-Wy")
assert_command(
["status"],
"""
develop *
|
o-allow-ownership-link
| |
| o-build-chain
|
m-call-ws slide-out=no
|
o-drop-constraint
master
|
o-hotfix/add-trigger
|
o-ignore-trailing
""",
)

0 comments on commit 0a8b636

Please sign in to comment.