github / github/gh-stack

gh stack rebase --continue doesn't report new conflicts hit while resuming a multi-commit branch rebase

Aperta
#430 1 commento 2 reazioni 0 assegnatari Vedi su GitHub
bug topic: cli - rebase
Lingua principale
Go
Stelle
1.5k
Fork
70
Merge medio
1g 8h
PR unite (30g)
7

Descrizione

## Summary

`gh stack rebase --continue` only prints `Conflicted files:` listing for first conflict encountered when cascading one stacked branch onto another. If resolving that conflict and continuing causes git to hit a second conflict on a later commit within the same branch's replay, the tool does not report what files are now conflicted and just returns a generic wrapped error.

This can make it look like there's only one conflicted file when there are actually more. You can only see the other conflicts by manually running `git status`.

## Steps to reproduce

1. Create a stack with a branch containing at least two commits and at least two files, where:
- Commit A modifies `file1.txt` so that there's a conflict with the (rebased) parent branch.
- Commit B later modifies `file2.txt` so that it also conflicts with the parent branch, independently of commit A.
2. Rebase the stack
3. The tool stops on commit A's conflict and correctly prints:
```
Conflicted files:
C file1.tsx (lines N–M)
```
4. Resolve `file1.txt`, stage it, run `gh stack rebase --continue` again.
5. Git internally applies commit B next, which conflicts on `file2.txt`.

## Expected behavior

Step 5 should print the same kind of `Conflicted files:` block, listing `file2.txt` with its conflict line numbers, like step 3 did for `file1.txt`.

## Actual behavior

Step 5 prints a generic error:
```
rebase continue failed — resolve remaining conflicts and try again: exit status 1
```

No indication of which file(s) are now conflicted. The only way to discover where the new conflict is is running `git status` manually.

## Proposed solution / notes

I'll be honest, not familiar with Go so this "solution" is mostly Claude. I did double check that it looks at least mostly right to me. Figured it might be helpful.

> Traced this to `cmd/rebase.go` and `internal/git/git.go`:
>
> - `printConflictDetails()` / `printConflictDetailsWithContinue()` (`cmd/rebase.go:545`) is the function that formats the `Conflicted files:` block with per-file conflict-marker line numbers (via `git.FindConflictMarkers`). It's only called from the branch-to-branch **cascade** logic, at `cmd/rebase.go:259` and `:435`.
> - `continueRebase()` (`cmd/rebase.go:312`) has a separate path for resuming an *already in-progress* `git rebase` within a single branch's multi-commit replay:
> ```go
> if git.IsRebaseInProgress() {
> rebaseOpts := git.RebaseOpts{CommitterDateIsAuthorDate: state.CommitterDateIsAuthorDate}
> if err := git.RebaseContinue(rebaseOpts); err != nil {
> return fmt.Errorf("rebase continue failed — resolve remaining conflicts and try again: %w", err)
> }
> }
> ```
> This path never calls `printConflictDetails`.
> - Following `RebaseContinue` (`internal/git/gitops.go:334`) into `tryAutoResolveRebase` (`internal/git/git.go:118`), the conflicted-files list is actually fetched — just to check whether `rerere` already auto-resolved everything — and then discarded on the way out:
> ```go
> conflicts, err := ConflictedFiles()
> if err != nil {
> return originalErr
> }
> if len(conflicts) > 0 {
> return originalErr // <-- conflicts is right here and gets thrown away
> }
> ```
>
> **Fix**: in `continueRebase`, when `git.RebaseContinue` returns an error, call `printConflictDetailsWithContinue` (using the still-in-progress rebase's current conflicted files, e.g. by calling `git.ConflictedFiles()` again, or by threading `tryAutoResolveRebase`'s local `conflicts` slice out through the error) before returning, instead of just wrapping the raw error string. That gives resume-mid-branch conflicts the same reporting as cascade-boundary conflicts.

## Environment

- `gh` version: 2.97.0 (2026-07-31)
- `gh-stack` extension: `github/gh-stack` v0.1.0
- OS: macOS Tahoe 26.5.1

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Inizia in cmd/rebase.go, in continueRebase, e confronta il relativo percorso in corso con printConflictDetailsWithContinue. Poi segui git.RebaseContinue in internal/git/gitops.go e tryAutoResolveRebase in internal/git/git.go; riproduci il flusso di conflitto con più commit usando gh stack rebase --continue. Il lavoro è completato quando un conflitto successivo segnala il blocco Conflicted files corrente invece del solo errore generico.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
git, go
Ambito
cli
Tipo di issue
Bug
Difficoltà
3/5
Tempo stimato
1-2 giorni
Stato di attività
Tranquilla
Chiarezza
Abbastanza chiara
Idoneità per principianti
72/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.