---
name: glab-mr-rebase
description: >
  Rebase a single MR on its target branch, auto-resolving conflicts when possible,
  then push the rewritten branch. Stops after push — does not restart pipelines.
  Use when the user says /glab-mr-rebase, 'rebase cette MR', 'rebase ma MR',
  'rebase la branche sur main', 'résous les conflits', or wants to bring an MR
  up to date with its target branch.
argument-hint: "[optional: MR !IID — defaults to the MR for the current branch]"
allowed-tools:
  - Read
  - Edit
  - Glob
  - Grep
  - Bash
---

Rebase a single merge request on its target branch and push, auto-resolving conflicts when possible.

## Required tools

- `glab`

Run `pysae-ai-tools tools require <tools>` before starting; if it exits non-zero, abort and report the install command from stderr to the user.

## Mode detection

```bash
CTX=$(pysae-ai-tools internal detect-context $ARGUMENTS_REFS)
IS_CI=$(echo "$CTX" | jq -r '.is_ci')
MR_IID=$(echo "$CTX" | jq -r '.mr_iid // empty')
```

If `MR_IID` is empty, inform the user and stop.

## Step 1 : Resolve MR metadata

Fetch the MR to get the source and target branches:
```bash
MR_JSON=$(glab mr view <MR_IID> --output json)
```
Extract `source_branch` and `target_branch`.

**Capture the pre-rebase approval state** so we can restore it after a force-push:
```bash
WAS_APPROVED=$(echo "$MR_JSON" | jq -r '(.approved_by | length) > 0')
```
GitLab projects with « Reset approvals on push » enabled drop every approval when the branch is rewritten (force-push after rebase / merge fallback). We re-add ours in step 3 if needed.

## Step 2 : Rebase

### 2.1 — Checkout and fetch
```bash
git fetch origin
git checkout <source_branch>
git pull origin <source_branch>
```

### 2.2 — Rebase on target branch
```bash
git rebase origin/<target_branch>
```

### 2.3 — Handle conflicts

**If rebase succeeds** → go to step 2.5.

**If rebase has conflicts**, resolve them automatically (no `AskUserQuestion`) and track how many commits produce conflicts:
1. Read each conflicting file
2. Resolve the conflict (keep the intent of both sides)
3. `git add <file>`
4. `git rebase --continue`
5. If the next commit also has conflicts, increment the conflict commit counter
6. **If 3 or more commits have produced conflicts** → the branch has diverged too much for a clean rebase. Abort and fallback to merge:
   ```bash
   git rebase --abort
   git merge origin/<target_branch> --no-edit
   ```
   If the merge also has conflicts, resolve them.
7. Otherwise, continue resolving until the rebase completes

### 2.4 — Push
```bash
git push --force-with-lease origin <source_branch>
```

`--force-with-lease` is required after rebase (history was rewritten). It is safe because it refuses to push if the remote has commits we don't know about.

## Step 3 : Restore approval if lost

If `WAS_APPROVED` was `true` (captured in step 1), re-check the MR after the push and restore the approval if it was reset:
```bash
POST_APPROVED=$(glab mr view <MR_IID> --output json | jq -r '(.approved_by | length) > 0')
```

If `WAS_APPROVED` is `true` and `POST_APPROVED` is `false` (« Reset approvals on push » fired), **invoke `/glab-mr-approve !<MR_IID> --auto` immediately, without asking the user** — the `--auto` flag tells the approve skill to skip the manual-testing confirmation since the MR was already validated before the rebase.

If both are `true` (approval survived) or both are `false` (was never approved), skip this step.

Mention the re-approval in the step 4 report when it happened.

## Step 4 : Report

Use a single line with three slots: status, MR ref + branch, strategy. Pick the strategy label that matches what actually happened:

- `rebase sans conflit` — rebase succeeded without any conflict
- `rebase, conflits résolus` — rebase succeeded after auto-resolving conflicts
- `merge fallback, conflits résolus` — rebase aborted (too divergent), merge used instead
- `échec, intervention manuelle requise` — rebase + merge fallback both failed (push skipped)

Format (append `, approval restaurée` when /glab-mr-approve was re-invoked in step 3):
```
✓ !<IID> <source_branch> — <strategy label>, push fait[, approval restaurée]
✗ !<IID> <source_branch> — échec, intervention manuelle requise
```

Examples:
```
✓ !42 feat/add-export — rebase sans conflit, push fait
✓ !38 fix/login-bug — rebase, conflits résolus, push fait, approval restaurée
✓ !27 refactor/auth — merge fallback, conflits résolus, push fait, approval restaurée
✗ !35 chore/big-bang — échec, intervention manuelle requise
```

## Gotchas

- **`--force-with-lease`** — toujours `--force-with-lease`, jamais `--force`. Protège contre l'écrasement de commits poussés entre-temps.
- **Branches protégées** — si le push est refusé, reporter l'erreur sans retry.
- **Pipelines** — ce skill ne relance pas de pipeline. Pour ça, utiliser `/glab-mr-refresh` ou `/ci-run`.

## Rules

- **Language**: messages en français, commandes git/glab en anglais
- **Never force push without `--force-with-lease`**
- **Auto-resolve conflicts** — pas de `AskUserQuestion`, ni en local ni en CI
- **Auto-restore approval** — si l'approval saute après force-push, ré-invoquer `/glab-mr-approve --auto` sans confirmation

$ARGUMENTS
