Command hangs: `run(pipeline(`git diff`, stderr=err, stdout=out), wait=true)`

(Found while debugging DrWatson.jl)

Setup (git repo with changed file):

# julia 1.9.3, Commit bed2cd540a1 (2023-08-24 14:43 UTC)
shell> mkdir JuliaGitWithPipeHangs
shell> cd JuliaGitWithPipeHangs
shell> git init
Initialized empty Git repository in /mnt/data/git/tmp/JuliaGitWithPipeHangs/.git/
julia> using Random; write("tmp.txt", string(rand(MersenneTwister(42), 10000)))
shell> git add tmp.txt
shell> git commit -m"commit"
julia> using Random; write("tmp.txt", string(rand(MersenneTwister(42), 100)))

At this point, running git diff in the shell works fine. Also

julia> run(`git diff`)

works. However, it opens a “less” view in Zshell, which might be what causes the problem here:

julia> out = Pipe(); err = Pipe(); run(pipeline(`git diff`, stderr=err, stdout=out), wait=true)

This just hangs. I suspect the Z-shell “less” mode is responsible. How can I make sure that it is and fix the problem? Does anyone else see this behavior?

If I open bash and run Julia from bash, it’s not able to run ls from shell> mode (no output), which might have to do with how the shell is configured, which I also haven’t seen before and don’t know how to fix at the moment.

Edit: The problem does go away when using bash as a shell. Which leaves the question: how to make it work without changing the shell?

My first instinct was to just use LibGit2.jl to get the diffs, however, that doesn’t seem to be possible (it can only list the changed files)?!?

You have a couple of misconceptions:

  • Julia commands have nothing to do with your shell. run doesn’t “shell-out”, it spawns a child process directly.

  • When you call git diff, it’s git (not zsh) the program that decides to use a pager.

If you don’t want to use a pager with git, maybe you could use the --no-pager option:

git --no-pager diff
2 Likes

Thanks for the help! I agree with both your points. The shell does not matter (global configurations might). Also thanks for the --no-pager advice.

The problem now is that adding --no-pager didn’t help and there must be another reason why the run call with pipes hangs. I don’t have any ideas right now…

I moved the question to julia - Command hangs: `run(pipeline(`git --no-pager diff`, stderr=err, stdout=out), wait=true)` - Stack Overflow. Please do not respond here any longer.