---
name: taw-git
description: 'Advanced git: create branches, open PRs (auto-generated body from diff + commits), fast-forward merge, recover mistakes. Triggers: "create PR", "open pull request", "tao branch", "merge", "tao PR", "git branch", "rebase".'
---

# taw-git — Branch, PR, Merge, Recover

For single-commit staging → use `taw-commit` instead.
For history lookup → use `taw-trace`.

## When to invoke

Trigger phrases (VN + EN):
- "tao branch moi" / "new branch" / "tạo nhánh mới"
- "mo PR" / "create pull request" / "push len github" / "open pr"
- "merge branch vao main" / "merge feature"
- "huy commit" / "revert" / "undo last commit" / "quay lai"

## Sub-commands

### 1. `branch <name>` — Create & switch

Branch naming with type prefix matching `taw-commit` conventions:

| Prefix | For |
|---|---|
| `feature/` | new user-visible feature |
| `fix/` | bug fix |
| `refactor/` | restructure, no behaviour change |
| `chore/` | deps, config, env |
| `hotfix/` | urgent production fix |
| `experiment/` | throwaway spike |

Workflow:
```bash
git fetch origin
git switch main
git pull --ff-only origin main
git switch -c <prefix>/<name>
```

If `main` is dirty (uncommitted work) → abort + VN: "taw: main đang có thay đổi chưa commit. Lưu trước rồi mới tạo branch."

### 2. `pr [base]` — Open pull request with smart body

Default base: `main`. Uses `gh` CLI against **remote** refs (unpushed commits visible on GitHub).

**Preflight:**
```bash
command -v gh >/dev/null || { echo "taw: gh CLI not installed. brew install gh"; exit 1; }
gh auth status >/dev/null 2>&1 || { echo "taw: gh not logged in. Run: gh auth login"; exit 1; }
git remote get-url origin >/dev/null 2>&1 || { echo "taw: no origin remote"; exit 1; }
```

**Push current branch if not on remote:**
```bash
HEAD_BRANCH="$(git rev-parse --abbrev-ref HEAD)"
[ "$HEAD_BRANCH" = "main" ] && { echo "taw: không mở PR từ main"; exit 1; }
git push -u origin "$HEAD_BRANCH"
```

**Gather PR content** (smart generation — not just commit dump):

```bash
BASE="${1:-main}"
git fetch origin "$BASE"
git log "origin/$BASE..origin/$HEAD_BRANCH" --pretty="- %s" > /tmp/taw-pr-commits.txt
git diff "origin/$BASE...origin/$HEAD_BRANCH" --stat > /tmp/taw-pr-stat.txt
```

**Check for existing PR template:**
```bash
cat .github/PULL_REQUEST_TEMPLATE.md 2>/dev/null || \
cat .github/pull_request_template.md 2>/dev/null
```

If project template exists → fill its sections. Else use taw's default template below.

**Extract issue references:**
```bash
git log origin/$BASE..origin/$HEAD_BRANCH --pretty=%B | \
  command grep -oE '#[0-9]+|[Cc]loses #[0-9]+|[Ff]ixes #[0-9]+' | sort -u
echo "$HEAD_BRANCH" | command grep -oE '[0-9]+' | head -1
```

**PR title** — reuse the most significant commit subject (feat > fix > refactor > chore). Strip trailing `[P<n>]` tags. Max 72 chars.

**PR body** (default template when no project template):
```markdown
## Summary

<1-3 bullets — WHAT and WHY, not commit dump>
- {outcome 1}
- {outcome 2}

## Changes

<Grouped by area, not files>
- **{area}** — {what changed there in plain terms}

## Test Plan

- [ ] {step 1 — usually run dev server, navigate to /route}
- [ ] {step 2 — golden-path action}
- [ ] {step 3 — edge case or failure mode}
- [ ] Run `npm test` — all pass
- [ ] Run `npm run build` — succeeds

## Screenshots / Recording

<placeholder — drag image or `gh pr comment` with video link>

## Related

Closes #<N>  |  Refs: <link>

---
🤖 PR body generated by taw-git
```

**Open the PR:**
```bash
gh pr create \
  --base "$BASE" \
  --head "$HEAD_BRANCH" \
  --title "$TITLE" \
  --body-file /tmp/taw-pr-body.md \
  --web   # opens browser to edit before submit — safer
```

For immediate submit: drop `--web`.

**Without `gh` fallback:** emit URL user pastes:
```
taw: tạo PR tại đây, paste body từ /tmp/taw-pr-body.md:
https://github.com/<owner>/<repo>/compare/<base>...<head>?expand=1
```

**Post-create:**
```
taw: PR opened — https://github.com/<owner>/<repo>/pull/<N>
  Assign reviewer: gh pr edit <N> --add-reviewer <user>
  Add labels:      gh pr edit <N> --add-label <label>
```

### 3. `merge [from]` — Fast-forward merge into main

Only fast-forward. Non-ff requires manual review.

```bash
FROM="${1:-$(git rev-parse --abbrev-ref HEAD)}"
git switch main
git pull --ff-only origin main
git merge --ff-only "$FROM" || {
  echo "taw: merge không phải fast-forward. Rebase '$FROM' lên main trước, hoặc merge thủ công."
  exit 1
}
git push origin main
```

Offer to delete merged branch:
```
taw: merged $FROM → main. Xoá branch '$FROM'? (y/N)
```
On y:
```bash
git branch -d "$FROM"
git push origin --delete "$FROM"
```

### 4. `undo` — Recover from last commit

Interactive. Ask scenario:

| Scenario | Command | Effect |
|---|---|---|
| Đổi ý, sửa message | `git commit --amend` | Rewrites last commit msg |
| Bỏ commit, giữ file edit | `git reset --soft HEAD~1` | Changes → staging |
| Bỏ commit + unstage | `git reset HEAD~1` | Changes → working tree |
| Xoá hẳn (NGUY HIỂM) | `git reset --hard HEAD~1` | **All work gone** — confirm twice |

Refuse `--hard` if commit touched >10 files or >200 lines UNLESS user types exact SHA.

Refuse any amend/reset if commit is pushed to protected branch (`main | master | production`). Instead suggest `git revert <sha>` (safe inverse commit).

## Safety rules

- NEVER `git push --force` to `main | master | production`. Force-push only to user-owned feature branches, with explicit confirmation.
- NEVER `git clean -fd` (can delete untracked work).
- NEVER `gh pr merge --admin` (bypasses branch protection).
- Before destructive op: `taw: sẽ chạy <cmd>. SHA hiện tại: <sha>. Xác nhận? (y/N)`
- If `git status` shows unmerged paths → refuse, tell user to resolve first.
- Diff sensitive-info scan (reuse `taw-commit` patterns) before opening PR — block if token/secret appears in branch diff.

## References (public specs — not copied, cited)

- Conventional Commits: https://www.conventionalcommits.org/en/v1.0.0/
- GitHub CLI: https://cli.github.com/manual/
- Pro Git book: https://git-scm.com/book

## Output style

- Short prose in user's input language (VN default)
- Every user-visible line prefixed "taw:"
- Raw git/gh commands verbatim (English) — power users learn
- No emoji
