lazygit
lazygit copied to clipboard
Continuing a revert after fixing a merge conflict does not work
When attempting to revert a commit that results in a conflict, there is no way to continue the revert after resolving the conflict (ie. git revert --continue
):
Given that this works in lazygit for other similar flows like rebasing, I'd expect this one to also be feasible.
interesting, it never occurred to me that that git revert would have its own continue/abort/skip commands. This should be easy to support by extending the genericMergeCommand
function in pkg/gui/controllers/helpers/merge_and_rebase_helper.go
but that's on my refactor branch which I still haven't quite merged
Just ran into this as well. Not a huge deal to break out of lazygit every now and then, and now have my $0.02 FWIW 😄
I have run into this too in the past. And it's not just revert, there are other commands that have the same issue (cherry-pick
and am
are the ones I can think of off the top of my head). To be fair, these can't be invoked from within lazygit itself, so they are maybe less important to support.
The code I referred to in my last comment is now merged so this is unblocked.
Fleshing out what's specifically required here: we need a way of knowing whether we're mid-cherry-pick or mid-revert so that we can issue the right command to continue.
The important code is in pkg/gui/controllers/helpers/merge_and_rebase_helper.go
, specifically genericMergeCommand
:
commandType := ""
switch status {
case enums.REBASE_MODE_MERGING:
commandType = "merge"
case enums.REBASE_MODE_REBASING:
commandType = "rebase"
default:
// shouldn't be possible to land here
}
In pkg/commands/git_commands/status.go
we have:
func (self *StatusCommands) IsInNormalRebase() (bool, error) {
return self.os.FileExists(filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-apply"))
}
func (self *StatusCommands) IsInInteractiveRebase() (bool, error) {
return self.os.FileExists(filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge"))
}
// IsInMergeState states whether we are still mid-merge
func (self *StatusCommands) IsInMergeState() (bool, error) {
return self.os.FileExists(filepath.Join(self.repoPaths.WorktreeGitDirPath(), "MERGE_HEAD"))
}
And now we need to add one for cherry-pick/revert i.e. looking for CHERRY_PICK_HEAD and REVERT_HEAD.
In pkg/commands/types/enums/enums.go
we have our RebaseMode
enum:
type RebaseMode int
const (
// this means we're neither rebasing nor merging
REBASE_MODE_NONE RebaseMode = iota
// this means normal rebase as opposed to interactive rebase
REBASE_MODE_NORMAL
REBASE_MODE_INTERACTIVE
// REBASE_MODE_REBASING is a general state that captures both REBASE_MODE_NORMAL and REBASE_MODE_INTERACTIVE
REBASE_MODE_REBASING
REBASE_MODE_MERGING
)
And as you can see it's being used for two different things in pkg/commands/git_commands/status.go
:
func (self *StatusCommands) RebaseMode() (enums.RebaseMode, error) {
ok, err := self.IsInNormalRebase()
if err == nil && ok {
return enums.REBASE_MODE_NORMAL, nil
}
ok, err = self.IsInInteractiveRebase()
if err == nil && ok {
return enums.REBASE_MODE_INTERACTIVE, err
}
return enums.REBASE_MODE_NONE, err
}
func (self *StatusCommands) WorkingTreeState() enums.RebaseMode {
rebaseMode, _ := self.RebaseMode()
if rebaseMode != enums.REBASE_MODE_NONE {
return enums.REBASE_MODE_REBASING
}
merging, _ := self.IsInMergeState()
if merging {
return enums.REBASE_MODE_MERGING
}
return enums.REBASE_MODE_NONE
}
These are used in a few places so we would need to go to each place and see if it needs to be updated to support new enum values. I think we should be encapsulating some details e.g.
func (self RebaseMode) CanContinue() bool {
return self == REBASE_MODE_NORMAL || self == REBASE_MODE_INTERACTIVE || self == REBASE_MODE_CHERRY_PICK || self == REBASE_MODE_REVERT
}
func (self RebaseMode) CanAbort() bool {
...
}
func (self RebaseMode) Command() string {
switch self {
case REBASE_MODE_NORMAL, REBASE_MODE_INTERACTIVE:
return "rebase"
case REBASE_MODE_REVERT:
return "revert"
case REBASE_MODE_CHERRY_PICK:
return "cherry-pick"
case REBASE_MODE_MERGING:
return "merge"
}
}
So that we don't need to be listing all the different variants throughout the code.
I would suggest to support git am
as well, while we're at it.