GitPython icon indicating copy to clipboard operation
GitPython copied to clipboard

Missing stderr in exception

Open Dreamsorcerer opened this issue 8 years ago • 6 comments

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.

Dreamsorcerer avatar Mar 01 '17 15:03 Dreamsorcerer

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.

Byron avatar Mar 02 '17 06:03 Byron

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?

Dreamsorcerer avatar Mar 02 '17 15:03 Dreamsorcerer

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.

Byron avatar Mar 03 '17 06:03 Byron

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.

Dreamsorcerer avatar Mar 08 '17 11:03 Dreamsorcerer

Good to hear! I will leave this issue open, in case someone would like to address it in some way.

Byron avatar Apr 09 '17 06:04 Byron

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

yarikoptic avatar Sep 27 '18 13:09 yarikoptic