gh stack rebase --continue doesn't report new conflicts hit while resuming a multi-commit branch rebase
- Ngôn ngữ chính
- Go
- Star
- 1.5k
- Fork
- 70
- Merge trung bình
- 1 ngày 8 giờ
- Pull request đã merge (30 ngày)
- 7
Mô tả
## 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
Hướng dẫn đóng góp
Hướng nghiên cứu
Start in cmd/rebase.go at continueRebase and compare its in-progress path with printConflictDetailsWithContinue. Then trace git.RebaseContinue in internal/git/gitops.go and tryAutoResolveRebase in internal/git/git.go; reproduce the multi-commit conflict flow with gh stack rebase --continue. Done means a later conflict reports the current Conflicted files block instead of only the generic error.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- git, go
- Lĩnh vực
- cli
- Loại issue
- Lỗi
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức độ hoạt động
- Ít trao đổi
- Độ rõ ràng
- Khá rõ ràng
- Mức phù hợp với người mới
- 72/100