-
-
Notifications
You must be signed in to change notification settings - Fork 2k
Lazygit is 'suspended' when running a custom command #4320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Damn. We were hoping this would be fixed with #4126 (and it seems for most users it did help). No idea why it still doesn't work for you. If we can't find any other way of fixing this, we may have to add a config option to disable the interactive shell behavior. As a workaround for now, you might try if launching lazygit like this solves it: lg()
{
export SHELL=xyz
lazygit
} |
Thank you for your promptly response @stefanhaller! |
Additional context: I ran Then lazygit was suspended (still no logs). When running
|
@stefanhaller Quick & Dirty Fix: Current behavior: Behavior with Unfortunately, it doesn't seem like a similar fix can be used when invoking Possible General Fix(es):
This is an interesting problem! When I have more time during the week I'll take a closer look at how custom commands are currently implemented and see if I can put together a PR to address the issue. [OT]: |
Thanks for the breakdown and the documentation links. It does sound like this could finally help shed some more light on the issue. I think I understand what's going on now; however, I still don't understand why this only happens for some people and not others, and apparently only sometimes (even before we added the |
The code that runs the shell command is here. As you can see, it simply calls |
I tried tackling this problem again this evening and, unfortunately, I still haven't figured it out. I do have some observations/notes though: I think you're 100% right about this being a timing issue but I don't think the problem is that the interactive shell is still around in some cases. I attached a debugger to a running process and tried stepping through to see where the process was getting suspended. The suspension happened here which kind of makes sense since I decided to try starting the process without a controlling terminal by adding the following to subprocess.SysProcAttr = &syscall.SysProcAttr{Noctty: true}
err := subprocess.Run() This actually ended up sort of working. The process no longer got suspended but there were a couple of side effects:
+ /usr/bin/bash -i -c ls
bash: cannot set terminal process group (104851): Inappropriate ioctl for device
bash: no job control in this shell
CODE-OF-CONDUCT.md CONTRIBUTING.md Dockerfile LICENSE Makefile README.md VISION.md cmd demo docs go.mod go.sum lazygit main.go pkg schema scripts test vendor
Press enter to return to lazygit
So not giving the subprocess a controlling terminal doesn't fix the issue but the experiment did lead me to a new possible explanation. Under certain conditions when a custom command is run and the subprocess exits it, for whatever reason, hands the controlling terminal back to I'll need to do some more experimenting but I wanted write down some of my thoughts while they're still fresh. I'll give this another go when I have some more time. |
I guess it must be something like that. If this is the case, and the "temporarily" is true, I wonder if we could simply wait until we are the foreground process again. Something along these lines: diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index aa44aa92c..8ceaa14d8 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -11,6 +11,9 @@ import (
"sort"
"strings"
"sync"
+ "time"
+
+ "golang.org/x/sys/unix"
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazycore/pkg/boxlayout"
@@ -974,6 +977,13 @@ func (gui *Gui) runSubprocess(cmdObj oscommands.ICmdObj) error { //nolint:unpara
subprocess.Stderr = io.Discard
subprocess.Stdin = nil
+ i := 0
+ for unix.Getpid() != unix.Getpgrp() {
+ time.Sleep(time.Millisecond)
+ i++
+ }
+ fmt.Fprintf(os.Stdout, "Had to sleep %d ms\n", i)
+
if gui.integrationTest == nil && (gui.Config.GetUserConfig().PromptToReturnFromSubprocess || err != nil) {
fmt.Fprintf(os.Stdout, "\n%s", style.FgGreen.Sprint(gui.Tr.PressEnterToReturn))
In my experiments this always printed "0 ms", but that's not a surprise because I could never reproduce the issue on my machine. I'm curious what this prints for you. I'm not actually suggesting we do something like this, though. For example, when users start lazygit from a wrapper script (or using Also, during experimentation I only now realized how much of a performance problem it is to launch an interactive shell. For many people it may not make as much of a difference, but on my system, calling So I would now propose to revert the whole interactive shell approach, and instead have some user configuration that allows people to tell lazygit about a shell startup file containing their alias definitions. It's a shame that it no longer works without any configuration, but I don't see any better solution at this point. Unfortunately this isn't totally trivial either, as it requires calling See #4385 for an implemenation of this. |
- **PR Description** In version 0.45.0 we started to use an interactive shell for running shell commands (see #4159). The idea was that this allows users to use their aliases and shell functions in lazygit without having to do any additional configuration. Unfortunately, this hasn't worked out well. For some users this resulted in lazygit hanging in the background upon trying to return from the shell command; we tried various fixes for this (see #4126, #4159, and #4350), but some users still have this problem (e.g. #4320). Also, starting an interactive shell can be a lot slower than starting a non-interactive one, depending on how much happens in the `.bashrc` or `.zshrc` file. For example, on my machine calling `zsh -ic true` takes 600ms, whereas `zsh -c true` takes less than 2ms. This is too high of a price to pay for using shell aliases, especially when _all_ users have to pay it, even those who don't care about using their aliases in lazygit. This PR reverts all commits related to interactive shells, and instead introduces a different approach: we let users specify a shell aliases file that will be sourced before running a command. The downside is that it doesn't work transparently out of the box, but requires configuration, and it may also require that users restructure their shell startup file(s) if they currently only have a single big one. The advantage is that only users who actually want to use aliases or functions are affected, and that we can now use this mechanism not only for shell commands, but also for custom commands and for calling the editor (some users have asked for this in the past).
Describe the bug
When I run any custom command, lazygit will be suspended with the last bit of output being
Press enter to return to lazyget
If I run lazy git from other program, for example, neovim, lazygit will just hangs permanently (because of the suspension, I think)
The custom command is
git pull --all
. Full output.To Reproduce
Steps to reproduce the behavior:
git fetch --all
Expected behavior
Lazygit is not suspended and I am brought back to the tty.
Screenshots
Version info:
Lazygit: commit=101bbb0ac56a1cf594301f45bda22c551f1aa870, build date=2025-02-22T11:33:02Z, build source=binaryRelease, version=0.47.1, os=darwin, arch=arm64, git version=2.39.5 (Apple Git-154)
git: git version 2.39.5 (Apple Git-154)
Additional context
If I run
fg
after lazygit is suspended, I'm brought back the lazygit instance and can quit the program with a shortcutq
.The text was updated successfully, but these errors were encountered: