---
phase: 25-commit-and-branch-flags
plan: 02
type: execute
wave: 2
depends_on: ["25-01"]
files_modified:
  - tests/test_commit_flags.py
  - tests/test_branch_flags.py
autonomous: true

must_haves:
  truths:
    - "All 8 COMM requirements have E2E test coverage"
    - "All 9 BRAN requirements have E2E test coverage"
    - "Tests verify actual behavior, not just that commands run"
    - "Existing commit and branch tests continue to pass"
  artifacts:
    - path: "tests/test_commit_flags.py"
      provides: "E2E tests for COMM-01 through COMM-08"
      contains: "TestCommitAmend"
    - path: "tests/test_branch_flags.py"
      provides: "E2E tests for BRAN-01 through BRAN-09"
      contains: "TestBranchShowCurrent"
  key_links:
    - from: "tests/test_commit_flags.py"
      to: "cmd_commit.py"
      via: "run_gitsl(['commit', '--amend'])"
      pattern: "run_gitsl.*commit.*--amend"
    - from: "tests/test_branch_flags.py"
      to: "cmd_branch.py"
      via: "run_gitsl(['branch', '--show-current'])"
      pattern: "run_gitsl.*branch.*--show-current"
---

<objective>
Create comprehensive E2E tests for all Phase 25 requirements (COMM-01 through COMM-08 and BRAN-01 through BRAN-09).

Purpose: Verify that all commit and branch flag translations work correctly with real Sapling repositories.

Output: New test files tests/test_commit_flags.py and tests/test_branch_flags.py with complete coverage.
</objective>

<execution_context>
@~/.claude/get-shit-done/workflows/execute-plan.md
@~/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/25-commit-and-branch-flags/25-RESEARCH.md
@.planning/phases/25-commit-and-branch-flags/25-01-SUMMARY.md

# Implementations being tested
@cmd_commit.py
@cmd_branch.py

# Test patterns to follow
@tests/test_commit.py
@tests/test_branch.py
@tests/test_status_flags.py
@tests/test_add_flags.py
@tests/conftest.py
</context>

<tasks>

<task type="auto">
  <name>Task 1: Create E2E tests for commit flags (COMM-01 through COMM-08)</name>
  <files>tests/test_commit_flags.py</files>
  <action>
Create tests/test_commit_flags.py with comprehensive E2E tests for all commit flag requirements.

**Test Structure (follow test_add_flags.py pattern):**

```python
"""E2E tests for git commit flags (COMM-01 through COMM-08).

Tests:
- COMM-01: --amend translates to sl amend
- COMM-02: --no-edit combined with amend uses existing message
- COMM-03: -F/--file translates to sl commit -l
- COMM-04: --author translates to sl commit -u
- COMM-05: --date translates to sl commit -d
- COMM-06: -v/--verbose shows warning
- COMM-07: -s/--signoff adds Signed-off-by trailer
- COMM-08: -n/--no-verify shows warning
"""

import shutil
import tempfile
from pathlib import Path

import pytest

from conftest import run_gitsl
from helpers.commands import run_command


sl_available = shutil.which("sl") is not None
pytestmark = [
    pytest.mark.skipif(not sl_available, reason="Sapling (sl) not installed"),
    pytest.mark.commit_flags,
]
```

**Test Classes:**

**COMM-01: TestCommitAmend**
```python
class TestCommitAmend:
    """COMM-01: --amend translates to sl amend."""

    def test_amend_modifies_last_commit(self, sl_repo_with_commit: Path):
        """git commit --amend modifies the last commit."""
        # Modify a file
        readme = sl_repo_with_commit / "README.md"
        readme.write_text("modified content\n")
        run_command(["sl", "add", "README.md"], cwd=sl_repo_with_commit)

        # Amend the commit
        result = run_gitsl(["commit", "--amend", "-m", "Amended message"],
                          cwd=sl_repo_with_commit)
        assert result.exit_code == 0

        # Verify message was changed
        log = run_command(["sl", "log", "-l", "1", "--template", "{desc}"],
                         cwd=sl_repo_with_commit)
        assert "Amended message" in log.stdout

    def test_amend_includes_new_changes(self, sl_repo_with_commit: Path):
        """git commit --amend includes newly staged changes."""
        # Add new file
        (sl_repo_with_commit / "new.txt").write_text("new content\n")
        run_command(["sl", "add", "new.txt"], cwd=sl_repo_with_commit)

        # Amend
        result = run_gitsl(["commit", "--amend", "-m", "Added new file"],
                          cwd=sl_repo_with_commit)
        assert result.exit_code == 0

        # Verify new file is in the commit
        show = run_command(["sl", "show", "--stat"], cwd=sl_repo_with_commit)
        assert "new.txt" in show.stdout
```

**COMM-02: TestCommitNoEdit**
```python
class TestCommitNoEdit:
    """COMM-02: --no-edit with amend uses existing message."""

    def test_amend_no_edit_preserves_message(self, sl_repo_with_commit: Path):
        """git commit --amend --no-edit keeps original message."""
        # Get original message
        log_before = run_command(["sl", "log", "-l", "1", "--template", "{desc}"],
                                cwd=sl_repo_with_commit)
        original_msg = log_before.stdout.strip()

        # Modify file and amend with --no-edit
        readme = sl_repo_with_commit / "README.md"
        readme.write_text("more content\n")
        run_command(["sl", "add", "README.md"], cwd=sl_repo_with_commit)

        result = run_gitsl(["commit", "--amend", "--no-edit"],
                          cwd=sl_repo_with_commit)
        assert result.exit_code == 0

        # Verify message unchanged
        log_after = run_command(["sl", "log", "-l", "1", "--template", "{desc}"],
                               cwd=sl_repo_with_commit)
        assert log_after.stdout.strip() == original_msg
```

**COMM-03: TestCommitFile**
```python
class TestCommitFile:
    """COMM-03: -F/--file translates to sl commit -l."""

    def test_commit_with_file_message(self, sl_repo: Path):
        """git commit -F <file> uses message from file."""
        # Create file and message file
        (sl_repo / "test.txt").write_text("content\n")
        run_command(["sl", "add", "test.txt"], cwd=sl_repo)

        msg_file = sl_repo / "commit_msg.txt"
        msg_file.write_text("Message from file\n")

        result = run_gitsl(["commit", "-F", str(msg_file)], cwd=sl_repo)
        assert result.exit_code == 0

        # Verify message
        log = run_command(["sl", "log", "-l", "1", "--template", "{desc}"],
                         cwd=sl_repo)
        assert "Message from file" in log.stdout

    def test_commit_with_file_long_form(self, sl_repo: Path):
        """git commit --file=<file> works with long form."""
        (sl_repo / "test2.txt").write_text("content\n")
        run_command(["sl", "add", "test2.txt"], cwd=sl_repo)

        msg_file = sl_repo / "msg2.txt"
        msg_file.write_text("Long form message\n")

        result = run_gitsl(["commit", f"--file={msg_file}"], cwd=sl_repo)
        assert result.exit_code == 0

        log = run_command(["sl", "log", "-l", "1", "--template", "{desc}"],
                         cwd=sl_repo)
        assert "Long form message" in log.stdout
```

**COMM-04: TestCommitAuthor**
```python
class TestCommitAuthor:
    """COMM-04: --author translates to sl commit -u."""

    def test_commit_with_custom_author(self, sl_repo: Path):
        """git commit --author sets commit author."""
        (sl_repo / "test.txt").write_text("content\n")
        run_command(["sl", "add", "test.txt"], cwd=sl_repo)

        result = run_gitsl(["commit", "-m", "Test",
                           "--author=Custom Author <custom@example.com>"],
                          cwd=sl_repo)
        assert result.exit_code == 0

        # Verify author
        log = run_command(["sl", "log", "-l", "1", "--template", "{author}"],
                         cwd=sl_repo)
        assert "Custom Author" in log.stdout
        assert "custom@example.com" in log.stdout
```

**COMM-05: TestCommitDate**
```python
class TestCommitDate:
    """COMM-05: --date translates to sl commit -d."""

    def test_commit_with_custom_date(self, sl_repo: Path):
        """git commit --date sets commit date."""
        (sl_repo / "test.txt").write_text("content\n")
        run_command(["sl", "add", "test.txt"], cwd=sl_repo)

        result = run_gitsl(["commit", "-m", "Test",
                           "--date=2024-01-15 12:00:00"],
                          cwd=sl_repo)
        assert result.exit_code == 0

        # Verify date (sl stores as unix timestamp, check year)
        log = run_command(["sl", "log", "-l", "1", "--template", "{date|isodate}"],
                         cwd=sl_repo)
        assert "2024" in log.stdout
```

**COMM-06: TestCommitVerbose**
```python
class TestCommitVerbose:
    """COMM-06: -v/--verbose shows warning about different semantics."""

    def test_verbose_shows_warning(self, sl_repo: Path):
        """git commit -v prints note about different semantics."""
        (sl_repo / "test.txt").write_text("content\n")
        run_command(["sl", "add", "test.txt"], cwd=sl_repo)

        result = run_gitsl(["commit", "-v", "-m", "Test"], cwd=sl_repo)
        # Should succeed and show note
        assert result.exit_code == 0
        assert "note" in result.stderr.lower() or "verbose" in result.stderr.lower()
```

**COMM-07: TestCommitSignoff**
```python
class TestCommitSignoff:
    """COMM-07: -s/--signoff adds Signed-off-by trailer."""

    def test_signoff_adds_trailer(self, sl_repo: Path):
        """git commit -s adds Signed-off-by line."""
        (sl_repo / "test.txt").write_text("content\n")
        run_command(["sl", "add", "test.txt"], cwd=sl_repo)

        result = run_gitsl(["commit", "-m", "Test commit", "-s"], cwd=sl_repo)
        assert result.exit_code == 0

        # Verify Signed-off-by trailer in message
        log = run_command(["sl", "log", "-l", "1", "--template", "{desc}"],
                         cwd=sl_repo)
        assert "Signed-off-by:" in log.stdout

    def test_signoff_long_form(self, sl_repo: Path):
        """git commit --signoff also adds trailer."""
        (sl_repo / "test2.txt").write_text("content\n")
        run_command(["sl", "add", "test2.txt"], cwd=sl_repo)

        result = run_gitsl(["commit", "-m", "Test", "--signoff"], cwd=sl_repo)
        assert result.exit_code == 0

        log = run_command(["sl", "log", "-l", "1", "--template", "{desc}"],
                         cwd=sl_repo)
        assert "Signed-off-by:" in log.stdout
```

**COMM-08: TestCommitNoVerify**
```python
class TestCommitNoVerify:
    """COMM-08: -n/--no-verify shows warning about hooks."""

    def test_no_verify_shows_warning(self, sl_repo: Path):
        """git commit --no-verify prints warning."""
        (sl_repo / "test.txt").write_text("content\n")
        run_command(["sl", "add", "test.txt"], cwd=sl_repo)

        result = run_gitsl(["commit", "--no-verify", "-m", "Test"], cwd=sl_repo)
        # Should succeed with warning
        assert result.exit_code == 0
        assert "warning" in result.stderr.lower() or "no-verify" in result.stderr.lower()

    def test_no_verify_short_form(self, sl_repo: Path):
        """git commit -n also shows warning."""
        (sl_repo / "test2.txt").write_text("content\n")
        run_command(["sl", "add", "test2.txt"], cwd=sl_repo)

        result = run_gitsl(["commit", "-n", "-m", "Test"], cwd=sl_repo)
        assert result.exit_code == 0
```
  </action>
  <verify>
Run the new commit flags tests:
```bash
pytest tests/test_commit_flags.py -v

# Also run existing commit tests to ensure no regressions
pytest tests/test_commit.py -v
```
  </verify>
  <done>
tests/test_commit_flags.py covers all 8 COMM requirements with E2E tests that verify actual sl behavior, not just command execution.
  </done>
</task>

<task type="auto">
  <name>Task 2: Create E2E tests for branch flags (BRAN-01 through BRAN-09)</name>
  <files>tests/test_branch_flags.py</files>
  <action>
Create tests/test_branch_flags.py with comprehensive E2E tests for all branch flag requirements.

**Test Structure:**

```python
"""E2E tests for git branch flags (BRAN-01 through BRAN-09).

Tests:
- BRAN-01: -m translates to sl bookmark -m (rename)
- BRAN-02: -a/--all shows all bookmarks including remote
- BRAN-03: -r/--remotes shows remote bookmarks only
- BRAN-04: -v/--verbose shows commit info with each branch
- BRAN-05: -l/--list lists branches matching pattern
- BRAN-06: --show-current shows current branch name
- BRAN-07: -t/--track sets up upstream tracking
- BRAN-08: -f/--force forces branch operations
- BRAN-09: -c/--copy copies a branch
"""

import shutil
from pathlib import Path

import pytest

from conftest import run_gitsl
from helpers.commands import run_command


sl_available = shutil.which("sl") is not None
pytestmark = [
    pytest.mark.skipif(not sl_available, reason="Sapling (sl) not installed"),
    pytest.mark.branch_flags,
]
```

**Test Classes:**

**BRAN-01: TestBranchRename**
```python
class TestBranchRename:
    """BRAN-01: -m translates to sl bookmark -m (rename)."""

    def test_branch_rename(self, sl_repo_with_commit: Path):
        """git branch -m old new renames bookmark."""
        # Create a bookmark
        run_command(["sl", "bookmark", "old-name"], cwd=sl_repo_with_commit)

        result = run_gitsl(["branch", "-m", "old-name", "new-name"],
                          cwd=sl_repo_with_commit)
        assert result.exit_code == 0

        # Verify rename
        bookmarks = run_command(["sl", "bookmark"], cwd=sl_repo_with_commit)
        assert "new-name" in bookmarks.stdout
        assert "old-name" not in bookmarks.stdout

    def test_branch_rename_current(self, sl_repo_with_commit: Path):
        """git branch -m old new works on current branch."""
        run_command(["sl", "bookmark", "current-branch"], cwd=sl_repo_with_commit)

        result = run_gitsl(["branch", "-m", "current-branch", "renamed-branch"],
                          cwd=sl_repo_with_commit)
        assert result.exit_code == 0

        bookmarks = run_command(["sl", "bookmark"], cwd=sl_repo_with_commit)
        assert "renamed-branch" in bookmarks.stdout
```

**BRAN-02: TestBranchAll**
```python
class TestBranchAll:
    """BRAN-02: -a/--all shows all bookmarks including remote."""

    def test_branch_all(self, sl_repo_with_commit: Path):
        """git branch -a shows all bookmarks."""
        run_command(["sl", "bookmark", "local-branch"], cwd=sl_repo_with_commit)

        result = run_gitsl(["branch", "-a"], cwd=sl_repo_with_commit)
        assert result.exit_code == 0
        assert "local-branch" in result.stdout

    def test_branch_all_long_form(self, sl_repo_with_commit: Path):
        """git branch --all also works."""
        run_command(["sl", "bookmark", "test-branch"], cwd=sl_repo_with_commit)

        result = run_gitsl(["branch", "--all"], cwd=sl_repo_with_commit)
        assert result.exit_code == 0
        assert "test-branch" in result.stdout
```

**BRAN-03: TestBranchRemotes**
```python
class TestBranchRemotes:
    """BRAN-03: -r/--remotes shows remote bookmarks only."""

    def test_branch_remotes(self, sl_repo_with_commit: Path):
        """git branch -r shows remote bookmarks."""
        # Note: In a local test repo, there may be no remotes
        result = run_gitsl(["branch", "-r"], cwd=sl_repo_with_commit)
        # Should succeed (even if empty)
        assert result.exit_code == 0

    def test_branch_remotes_long_form(self, sl_repo_with_commit: Path):
        """git branch --remotes also works."""
        result = run_gitsl(["branch", "--remotes"], cwd=sl_repo_with_commit)
        assert result.exit_code == 0
```

**BRAN-04: TestBranchVerbose**
```python
class TestBranchVerbose:
    """BRAN-04: -v/--verbose shows commit info with each branch."""

    def test_branch_verbose(self, sl_repo_with_commit: Path):
        """git branch -v shows commit info."""
        run_command(["sl", "bookmark", "feature"], cwd=sl_repo_with_commit)

        result = run_gitsl(["branch", "-v"], cwd=sl_repo_with_commit)
        assert result.exit_code == 0
        # Should show bookmark with commit hash or description
        assert "feature" in result.stdout
        # Verbose output should have more content than just the name
        # (commit hash or description)

    def test_branch_verbose_long_form(self, sl_repo_with_commit: Path):
        """git branch --verbose also works."""
        run_command(["sl", "bookmark", "test"], cwd=sl_repo_with_commit)

        result = run_gitsl(["branch", "--verbose"], cwd=sl_repo_with_commit)
        assert result.exit_code == 0
        assert "test" in result.stdout
```

**BRAN-05: TestBranchList**
```python
class TestBranchList:
    """BRAN-05: -l/--list lists branches matching pattern."""

    def test_branch_list_with_pattern(self, sl_repo_with_commit: Path):
        """git branch -l pattern filters branches."""
        run_command(["sl", "bookmark", "feature-one"], cwd=sl_repo_with_commit)
        run_command(["sl", "bookmark", "feature-two"], cwd=sl_repo_with_commit)
        run_command(["sl", "bookmark", "bugfix-one"], cwd=sl_repo_with_commit)

        result = run_gitsl(["branch", "-l", "feature*"], cwd=sl_repo_with_commit)
        assert result.exit_code == 0
        assert "feature-one" in result.stdout
        assert "feature-two" in result.stdout
        # bugfix should not appear (doesn't match pattern)

    def test_branch_list_no_pattern(self, sl_repo_with_commit: Path):
        """git branch --list without pattern shows all."""
        run_command(["sl", "bookmark", "main"], cwd=sl_repo_with_commit)

        result = run_gitsl(["branch", "--list"], cwd=sl_repo_with_commit)
        assert result.exit_code == 0
        assert "main" in result.stdout
```

**BRAN-06: TestBranchShowCurrent**
```python
class TestBranchShowCurrent:
    """BRAN-06: --show-current shows current branch name."""

    def test_show_current_branch(self, sl_repo_with_commit: Path):
        """git branch --show-current prints current bookmark."""
        run_command(["sl", "bookmark", "current"], cwd=sl_repo_with_commit)

        result = run_gitsl(["branch", "--show-current"], cwd=sl_repo_with_commit)
        assert result.exit_code == 0
        assert "current" in result.stdout.strip()

    def test_show_current_no_branch(self, sl_repo_with_commit: Path):
        """git branch --show-current with no active bookmark returns empty."""
        # Don't create any bookmarks - should be detached
        result = run_gitsl(["branch", "--show-current"], cwd=sl_repo_with_commit)
        assert result.exit_code == 0
        # May be empty or show nothing (matches git behavior for detached HEAD)
```

**BRAN-07: TestBranchTrack**
```python
class TestBranchTrack:
    """BRAN-07: -t/--track sets up upstream tracking."""

    def test_branch_track(self, sl_repo_with_commit: Path):
        """git branch -t passes through tracking flag."""
        # Note: Tracking in Sapling is different from git
        # This test just verifies the flag is accepted
        run_command(["sl", "bookmark", "main"], cwd=sl_repo_with_commit)

        result = run_gitsl(["branch", "feature", "-t", "main"],
                          cwd=sl_repo_with_commit)
        # May or may not succeed depending on sl version/config
        # Key is that the flag is passed through, not rejected
```

**BRAN-08: TestBranchForce**
```python
class TestBranchForce:
    """BRAN-08: -f/--force forces branch operations."""

    def test_branch_force_move(self, sl_repo_with_commit: Path):
        """git branch -f moves existing bookmark."""
        # Create bookmark and another commit
        run_command(["sl", "bookmark", "to-move"], cwd=sl_repo_with_commit)
        (sl_repo_with_commit / "new.txt").write_text("new\n")
        run_command(["sl", "add", "new.txt"], cwd=sl_repo_with_commit)
        run_command(["sl", "commit", "-m", "Second commit"], cwd=sl_repo_with_commit)

        # Force move bookmark to current commit
        result = run_gitsl(["branch", "-f", "to-move"], cwd=sl_repo_with_commit)
        assert result.exit_code == 0

    def test_branch_force_long_form(self, sl_repo_with_commit: Path):
        """git branch --force also works."""
        run_command(["sl", "bookmark", "existing"], cwd=sl_repo_with_commit)

        result = run_gitsl(["branch", "--force", "existing"], cwd=sl_repo_with_commit)
        assert result.exit_code == 0
```

**BRAN-09: TestBranchCopy**
```python
class TestBranchCopy:
    """BRAN-09: -c/--copy copies a branch."""

    def test_branch_copy(self, sl_repo_with_commit: Path):
        """git branch -c old new creates copy of bookmark."""
        run_command(["sl", "bookmark", "original"], cwd=sl_repo_with_commit)

        result = run_gitsl(["branch", "-c", "original", "copy"],
                          cwd=sl_repo_with_commit)
        assert result.exit_code == 0

        # Both bookmarks should exist
        bookmarks = run_command(["sl", "bookmark"], cwd=sl_repo_with_commit)
        assert "original" in bookmarks.stdout
        assert "copy" in bookmarks.stdout

    def test_branch_copy_same_commit(self, sl_repo_with_commit: Path):
        """git branch -c creates bookmark at same commit."""
        run_command(["sl", "bookmark", "source"], cwd=sl_repo_with_commit)

        # Get commit hash where source points
        source_commit = run_command(
            ["sl", "log", "-r", "bookmark(source)", "--template", "{node|short}"],
            cwd=sl_repo_with_commit
        )

        result = run_gitsl(["branch", "-c", "source", "dest"],
                          cwd=sl_repo_with_commit)
        assert result.exit_code == 0

        # Dest should point to same commit
        dest_commit = run_command(
            ["sl", "log", "-r", "bookmark(dest)", "--template", "{node|short}"],
            cwd=sl_repo_with_commit
        )
        assert source_commit.stdout.strip() == dest_commit.stdout.strip()

    def test_branch_copy_long_form(self, sl_repo_with_commit: Path):
        """git branch --copy also works."""
        run_command(["sl", "bookmark", "orig"], cwd=sl_repo_with_commit)

        result = run_gitsl(["branch", "--copy", "orig", "dup"],
                          cwd=sl_repo_with_commit)
        assert result.exit_code == 0

        bookmarks = run_command(["sl", "bookmark"], cwd=sl_repo_with_commit)
        assert "orig" in bookmarks.stdout
        assert "dup" in bookmarks.stdout

    def test_branch_copy_nonexistent_fails(self, sl_repo_with_commit: Path):
        """git branch -c with nonexistent source fails."""
        result = run_gitsl(["branch", "-c", "nonexistent", "copy"],
                          cwd=sl_repo_with_commit)
        assert result.exit_code != 0
```
  </action>
  <verify>
Run the new branch flags tests:
```bash
pytest tests/test_branch_flags.py -v

# Also run existing branch tests to ensure no regressions
pytest tests/test_branch.py -v
```
  </verify>
  <done>
tests/test_branch_flags.py covers all 9 BRAN requirements with E2E tests that verify actual sl behavior.
  </done>
</task>

<task type="auto">
  <name>Task 3: Run full test suite and verify coverage</name>
  <files></files>
  <action>
Run the complete test suite to verify:
1. All new tests pass
2. All existing tests still pass (no regressions)
3. Coverage for all 17 requirements (8 COMM + 9 BRAN)

Commands to run:
```bash
# Run new flag tests
pytest tests/test_commit_flags.py tests/test_branch_flags.py -v

# Run existing tests to verify no regressions
pytest tests/test_commit.py tests/test_branch.py -v

# Run full test suite
pytest tests/ -v --tb=short

# Generate coverage report for cmd_commit.py and cmd_branch.py
pytest tests/test_commit_flags.py tests/test_branch_flags.py tests/test_commit.py tests/test_branch.py --cov=. --cov-report=term-missing
```

Expected results:
- All tests pass
- No regressions in existing tests
- Coverage shows new flag code paths are exercised
  </action>
  <verify>
```bash
# Verify all tests pass
pytest tests/test_commit_flags.py tests/test_branch_flags.py tests/test_commit.py tests/test_branch.py -v
```
  </verify>
  <done>
All Phase 25 tests pass including new commit/branch flag tests and existing tests. No regressions.
  </done>
</task>

</tasks>

<verification>
After completing all tasks:

1. Run all new tests:
```bash
pytest tests/test_commit_flags.py tests/test_branch_flags.py -v
```

2. Verify existing tests still pass:
```bash
pytest tests/test_commit.py tests/test_branch.py -v
```

3. Run full test suite:
```bash
pytest tests/ -v
```

4. Check test coverage for Phase 25 requirements:
- [ ] COMM-01: TestCommitAmend (2 tests)
- [ ] COMM-02: TestCommitNoEdit (1 test)
- [ ] COMM-03: TestCommitFile (2 tests)
- [ ] COMM-04: TestCommitAuthor (1 test)
- [ ] COMM-05: TestCommitDate (1 test)
- [ ] COMM-06: TestCommitVerbose (1 test)
- [ ] COMM-07: TestCommitSignoff (2 tests)
- [ ] COMM-08: TestCommitNoVerify (2 tests)
- [ ] BRAN-01: TestBranchRename (2 tests)
- [ ] BRAN-02: TestBranchAll (2 tests)
- [ ] BRAN-03: TestBranchRemotes (2 tests)
- [ ] BRAN-04: TestBranchVerbose (2 tests)
- [ ] BRAN-05: TestBranchList (2 tests)
- [ ] BRAN-06: TestBranchShowCurrent (2 tests)
- [ ] BRAN-07: TestBranchTrack (1 test)
- [ ] BRAN-08: TestBranchForce (2 tests)
- [ ] BRAN-09: TestBranchCopy (4 tests)
</verification>

<success_criteria>
1. tests/test_commit_flags.py exists with tests for all 8 COMM requirements
2. tests/test_branch_flags.py exists with tests for all 9 BRAN requirements
3. All new tests pass when run with pytest
4. All existing commit and branch tests continue to pass
5. No regressions in the full test suite
6. Each requirement has at least one test that verifies actual behavior
</success_criteria>

<output>
After completion, create `.planning/phases/25-commit-and-branch-flags/25-02-SUMMARY.md`
</output>
