Skip to content

Create branch

create_branch

Create-branch hook action.

Creates a session branch in the working directory. Branch name is resolved with priority: branch param > ticket params > {prefix}/{session_id}.

CreateBranchHook dataclass

Create a session branch.

Branch name priority:

  1. branch param (direct override)
  2. ticket_id + ticket_title params → branch_name_from_ticket()
  3. {prefix}/{session_id} (legacy fallback)

Skips gracefully when the working directory is not a git repository.

Source code in packages/axm-git/src/axm_git/hooks/create_branch.py
@dataclass
class CreateBranchHook:
    """Create a session branch.

    Branch name priority:

    1. ``branch`` param (direct override)
    2. ``ticket_id`` + ``ticket_title`` params → ``branch_name_from_ticket()``
    3. ``{prefix}/{session_id}`` (legacy fallback)

    Skips gracefully when the working directory is not a git repository.
    """

    def execute(self, context: dict[str, Any], **params: Any) -> HookResult:
        """Execute the hook action.

        Args:
            context: Session context dictionary (must contain ``session_id``).
            **params: Optional ``branch``, ``ticket_id``, ``ticket_title``,
                ``ticket_labels``, ``prefix`` (default ``"axm"``).

        Returns:
            HookResult with ``branch`` in metadata on success.
        """
        working_dir = _resolve_working_dir(params, context)
        session_id: str = context["session_id"]

        if not params.get("enabled", True):
            return HookResult.ok(skipped=True, reason="git disabled")

        git_root = find_git_root(working_dir)
        if git_root is None:
            return HookResult.ok(skipped=True, reason="not a git repo")

        branch = self._resolve_branch(params, session_id)

        result = run_git(["checkout", "-b", branch], git_root)
        if result.returncode != 0:
            return HookResult.fail(f"git checkout -b failed: {result.stderr}")

        return HookResult.ok(branch=branch)

    @staticmethod
    def _resolve_branch(params: dict[str, Any], session_id: str) -> str:
        """Resolve branch name from params with fallback to session_id."""
        if branch := params.get("branch"):
            return str(branch)

        ticket_id = params.get("ticket_id")
        ticket_title = params.get("ticket_title")
        if ticket_id and ticket_title:
            labels = params.get("ticket_labels", [])
            return branch_name_from_ticket(ticket_id, ticket_title, labels)

        prefix = params.get("prefix", "axm")
        return f"{prefix}/{session_id}"
execute(context, **params)

Execute the hook action.

Parameters:

Name Type Description Default
context dict[str, Any]

Session context dictionary (must contain session_id).

required
**params Any

Optional branch, ticket_id, ticket_title, ticket_labels, prefix (default "axm").

{}

Returns:

Type Description
HookResult

HookResult with branch in metadata on success.

Source code in packages/axm-git/src/axm_git/hooks/create_branch.py
def execute(self, context: dict[str, Any], **params: Any) -> HookResult:
    """Execute the hook action.

    Args:
        context: Session context dictionary (must contain ``session_id``).
        **params: Optional ``branch``, ``ticket_id``, ``ticket_title``,
            ``ticket_labels``, ``prefix`` (default ``"axm"``).

    Returns:
        HookResult with ``branch`` in metadata on success.
    """
    working_dir = _resolve_working_dir(params, context)
    session_id: str = context["session_id"]

    if not params.get("enabled", True):
        return HookResult.ok(skipped=True, reason="git disabled")

    git_root = find_git_root(working_dir)
    if git_root is None:
        return HookResult.ok(skipped=True, reason="not a git repo")

    branch = self._resolve_branch(params, session_id)

    result = run_git(["checkout", "-b", branch], git_root)
    if result.returncode != 0:
        return HookResult.fail(f"git checkout -b failed: {result.stderr}")

    return HookResult.ok(branch=branch)