Missing stderr in exception
So, I can call:
git.Repo.clone_from(repo, path)
and this raises a very helpful GitCommandError exception with the stderr.
But, if I pass the progress parameter:
git.Repo.clone_from(repo, path, progress_func)
this also raises a GitCommandError exception, but stderr is blank. progress_func was never called with anything, so it's not like stderr ended up there instead.
I now have no idea what the error is. I expect to get stderr regardless of whether progress is used or not.
I believe what happens is that the progress parser tries to read stderr as progress, and discards anything that it doesn't understand. You can implement a custom parser as it can see all processed lines nonetheless. To me this is an inconvenience that can be worked around with reasonable effort, but as always, a fix would be a highly appreciated PR.
I'm not sure exactly what you mean.
So, I'm running something like this:
def progress_func(op_code, cur_count, max_count=None, message=""):
print("FOO")
print(message)
git.Repo.clone_from(repo, path, progress_func)
Nothing is printed, progress_func is never called, but the exception is raised.
How would I utilise a custom parser in this scenario?
There is a class called RemoteProgress which you can derive from and implement _parse_progress_line(), which sees all lines ever passed to it. See the code.
OK, using a regular subclass, I'm able to grab the messages from error_lines. Something like: " ".join(progress.error_lines)
That will work for now.
Good to hear! I will leave this issue open, in case someone would like to address it in some way.
Just ran into the same issue within https://github.com/datalad/datalad/pull/2876 . Here is my complete example to demonstrate the issue:
from git import RemoteProgress, Repo
url = "http://github.com/gitpython-developers/GitPython"
try:
Repo.clone_from(url, "/dev/null")
except Exception as e:
print("No progress - Exception %s with stderr: %r" % (e, e.stderr))
class phandler(RemoteProgress):
def update(self, *args):
print("UPDATE: %s" % (args,))
try:
Repo.clone_from(url, "/dev/null", progress=phandler())
except Exception as e:
print("With progress - Exception %s with stderr: %r" % (e, e.stderr))
which produces
$ /usr/bin/python3.6 /home/yoh/deb/gits/python-git/demo-progress.py
No progress - Exception Cmd('git') failed due to: exit code(128)
cmdline: git clone -v http://github.com/gitpython-developers/GitPython /dev/null
stderr: 'fatal: destination path '/dev/null' already exists and is not an empty directory.
' with stderr: "\n stderr: 'fatal: destination path '/dev/null' already exists and is not an empty directory.\n'"
With progress - Exception Cmd('git') failed due to: exit code(128)
cmdline: git clone --progress -v http://github.com/gitpython-developers/GitPython /dev/null with stderr: ''
Good to know that there is progress.error_lines but IMHO those should be populated into the exception's .stderr by GitPython itself