---
phase: 22-log-flags
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
  - cmd_log.py
autonomous: true

must_haves:
  truths:
    - "User running git log --graph sees ASCII commit graph"
    - "User running git log --stat sees diffstat with each commit"
    - "User running git log --author=<name> sees only commits by that author"
    - "User running git log --since='date' sees only commits after that date"
    - "User running git log --name-only sees only filenames changed per commit"
    - "User running git log --pretty=oneline sees oneline format"
    - "User running git log -S warns about pickaxe not being supported"
  artifacts:
    - path: "cmd_log.py"
      provides: "Complete git log flag translation"
      min_lines: 150
  key_links:
    - from: "cmd_log.py"
      to: "sl log"
      via: "run_sl with translated args"
      pattern: "run_sl\\(sl_args\\)"
---

<objective>
Implement comprehensive git log flag translation to Sapling equivalents.

Purpose: Users can filter, format, and customize git log output using the full range of commonly-used git log flags, enabling seamless use of familiar git workflows.

Output: Extended cmd_log.py with support for 18 new flags (LOG-01 through LOG-18), plus documentation of 2 existing flags (LOG-19, LOG-20).
</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/22-log-flags/22-RESEARCH.md
@cmd_log.py
@common.py
</context>

<tasks>

<task type="auto">
  <name>Task 1: Implement Direct Pass-through and Simple Translation Flags</name>
  <files>cmd_log.py</files>
  <action>
Extend cmd_log.py handle() function to support:

**Direct pass-through flags (same flag name):**
- LOG-02: `--stat` -> `--stat`
- LOG-03: `--patch` or `-p` -> `-p`
- LOG-07: `--all` -> `--all`

**Simple translation flags:**
- LOG-01: `--graph` -> `-G`
- LOG-06: `--no-merges` -> `--no-merges` (pass through, same flag)
- LOG-08: `--follow` -> `-f`

Implementation approach:
1. Add a FLAG_TRANSLATIONS dict at module level for simple mappings
2. In the while loop, check against these mappings
3. For each matched flag, append the translated sl flag to sl_args

Example structure:
```python
# Simple flag translations
if arg == '--graph':
    sl_args.append('-G')
elif arg == '--stat':
    sl_args.append('--stat')
elif arg in ('--patch', '-p'):
    sl_args.append('-p')
elif arg == '--no-merges':
    sl_args.append('--no-merges')
elif arg == '--all':
    sl_args.append('--all')
elif arg == '--follow':
    sl_args.append('-f')
```

Keep existing -n/--max-count and --oneline handling unchanged.
  </action>
  <verify>Run `python -c "import cmd_log; print('OK')"` to verify syntax</verify>
  <done>cmd_log.py handles LOG-01, LOG-02, LOG-03, LOG-06, LOG-07, LOG-08</done>
</task>

<task type="auto">
  <name>Task 2: Implement Filter Flags with Value Parsing</name>
  <files>cmd_log.py</files>
  <action>
Add support for filter flags that take values:

**LOG-04: --author=<pattern> -> -u <pattern>**
Handle both `--author=name` and `--author name` syntaxes.

**LOG-05: --grep=<pattern> -> -k <pattern>**
Handle both `--grep=pattern` and `--grep pattern` syntaxes.

**LOG-09/LOG-10: Date range flags**
- `--since=<date>` or `--after=<date>` -> `-d ">date"`
- `--until=<date>` or `--before=<date>` -> `-d "<date"`
- When both since and until specified: `-d "date1 to date2"`

Implementation approach:
1. Track since_date and until_date variables before the loop
2. Parse value-attached flags (e.g., --author=john)
3. Parse space-separated flags (e.g., --author john)
4. After the loop, build the -d argument if any dates were specified

Example for author:
```python
elif arg.startswith('--author='):
    pattern = arg.split('=', 1)[1]
    sl_args.extend(['-u', pattern])
elif arg == '--author':
    if i + 1 < len(parsed.args):
        i += 1
        sl_args.extend(['-u', parsed.args[i]])
```

Example for dates (after loop):
```python
if since_date and until_date:
    sl_args.extend(['-d', f'{since_date} to {until_date}'])
elif since_date:
    sl_args.extend(['-d', f'>{since_date}'])
elif until_date:
    sl_args.extend(['-d', f'<{until_date}'])
```
  </action>
  <verify>Run `python -c "import cmd_log; print('OK')"` to verify syntax</verify>
  <done>cmd_log.py handles LOG-04, LOG-05, LOG-09, LOG-10</done>
</task>

<task type="auto">
  <name>Task 3: Implement Output Format Flags</name>
  <files>cmd_log.py</files>
  <action>
Add support for output format flags:

**LOG-11: --name-only**
Use sl template to output only filenames. Template: `{node|short} {desc|firstline}\n{files}\n\n`
Note: sl {files} outputs all files; this is approximate to git --name-only.

**LOG-12: --name-status**
Similar to --name-only but with status indicators. This requires post-processing or template work.
For simplicity, use a template that shows files with status: `{node|short} {desc|firstline}\n{file_adds % "A\t{file}\n"}{file_dels % "D\t{file}\n"}{file_mods % "M\t{file}\n"}\n`
Note: This approximates git's format.

**LOG-13: --decorate**
Show bookmark names on commits. Use template with {bookmarks}: `{node|short} ({bookmarks}) {desc|firstline}\n`
If no --oneline, append bookmarks to default output format.

**LOG-14: --pretty/--format**
Support preset formats and basic custom formats:
- `--pretty=oneline` -> already handled by --oneline logic
- `--pretty=short`, `--pretty=medium`, `--pretty=full` -> predefined templates
- `--format=format:<spec>` -> translate git format placeholders to sl template

Define PRETTY_PRESETS dict with sl templates for short/medium/full.
For custom format:, translate common placeholders:
- %H -> {node}
- %h -> {node|short}
- %s -> {desc|firstline}
- %an -> {author|person}
- %ae -> {author|email}
- %ad -> {date|isodate}
- %ar -> {date|age}
- %d -> {bookmarks}
- %n -> \\n

Implementation:
1. Add PRETTY_PRESETS dict at module level
2. Add translate_format_placeholders() helper function
3. Parse --pretty=X and --format=X in the loop
4. Apply template with -T flag

Track name_only, name_status, decorate as booleans; apply templates after loop.
  </action>
  <verify>Run `python -c "import cmd_log; print('OK')"` to verify syntax</verify>
  <done>cmd_log.py handles LOG-11, LOG-12, LOG-13, LOG-14</done>
</task>

<task type="auto">
  <name>Task 4: Implement Complex Flags and Warnings</name>
  <files>cmd_log.py</files>
  <action>
Add support for complex flags and warning messages:

**LOG-15: --first-parent**
Use revset to follow only first parent. This is complex in sl.
Implementation: Use `-r "first(ancestors(.))"` revset as approximation.
Note: May not be exact equivalent; document limitation.

**LOG-16: --reverse**
sl doesn't have --reverse flag. Options:
1. Use revset: sl log -r "reverse(ancestors(.))"
2. For now, implement as revset wrapper

Implementation: Add `--rev` with reverse() revset wrapper.

**LOG-17: -S<string> (pickaxe)**
Sapling has no equivalent to git's pickaxe search.
Print warning to stderr: "Warning: -S pickaxe search not supported in Sapling. Consider: sl log -p | grep 'pattern'"
Return successfully but don't pass the flag.

**LOG-18: -G<regex> (regex pickaxe)**
Same as LOG-17 - print warning, don't pass flag.

Import sys at top of file for stderr output.

Example for -S:
```python
elif arg.startswith('-S'):
    import sys
    search_term = arg[2:] if len(arg) > 2 else (parsed.args[i + 1] if i + 1 < len(parsed.args) else '')
    print(f"Warning: -S pickaxe search not supported in Sapling.", file=sys.stderr)
    print(f"Consider: sl log -p | grep '{search_term}'", file=sys.stderr)
    if len(arg) == 2 and i + 1 < len(parsed.args):
        i += 1  # Skip the search term argument
```

Update module docstring to document LOG-19 and LOG-20 (already implemented).
  </action>
  <verify>Run `python -c "import cmd_log; print('OK')"` to verify syntax</verify>
  <done>cmd_log.py handles LOG-15, LOG-16, LOG-17, LOG-18, and documents LOG-19, LOG-20</done>
</task>

</tasks>

<verification>
1. `python -c "import cmd_log; print('OK')"` - module imports without error
2. `pytest tests/test_log.py -v` - existing tests still pass
3. Manual verification with GITSL_DEBUG=1:
   - `GITSL_DEBUG=1 python gitsl.py log --graph` shows `-G` translation
   - `GITSL_DEBUG=1 python gitsl.py log --author=john` shows `-u john` translation
   - `GITSL_DEBUG=1 python gitsl.py log --since="2024-01-01"` shows `-d ">2024-01-01"` translation
</verification>

<success_criteria>
1. All 18 new log flags are handled (translated or warned)
2. Existing -n/--max-count and --oneline functionality unchanged
3. Module docstring documents LOG-19 and LOG-20 as already implemented
4. Existing tests pass
5. No syntax errors in cmd_log.py
</success_criteria>

<output>
After completion, create `.planning/phases/22-log-flags/22-01-SUMMARY.md`
</output>
