Skip to content

Raising of GitCommandError fails in archive function if stdout was a cStringIO object #619

Closed

Description

@wohauser

I tried to check out an archive for a not existing path from the repository and I expect a GitCommandError exception.

I got following TypeError exception:
"Expected bytes or text, but got <cStringIO.StringO object at 0x7fabac6f97a0>"

I did following:
fpt = StringIO()
-- (used as a temporary storage for the tar archive)
self._repository.archive(fpt, treeish=version_identifier, format="tar", path=sub_path)
-- (where sub_path points to an not existing path)

The cause of the problem was, the Constructor of the GitCommandError could not handle the cStringIO object. (a normal file pointer may be faulty too).
I suppose it should set its stdout variable to None in case of not handled types. Or it should be adjusted when raising the exception.

Activity

  1. Byron commented on Apr 9, 2017

    @Byron
    Member

    Using the latest version of GitPython (39335e6) on OSX on python 2.7, I was unable to reproduce the issue.

    screen shot 2017-04-09 at 16 38 38

    Please feel free to provide more information to help reproducing it - maybe this functionality is platform dependent. In the meanwhile, I am closing this issue.

  2. wohauser commented on Apr 12, 2017

    @wohauser
    Author

    Try it with a path filter using a path that not exists in the repo.

    e.g.

    r.archive(fpt,format="tar",path="tttt")
    
    results in 
      File "<stdin>", line 1, in <module>
      File "/usr/local/lib/python2.7/dist-packages/git/repo/base.py", line 969, in archive
        self.git.archive(treeish, *path, **kwargs)
      File "/usr/local/lib/python2.7/dist-packages/git/cmd.py", line 425, in <lambda>
        return lambda *args, **kwargs: self._call_process(name, *args, **kwargs)
      File "/usr/local/lib/python2.7/dist-packages/git/cmd.py", line 877, in _call_process
        return self.execute(call, **exec_kwargs)
      File "/usr/local/lib/python2.7/dist-packages/git/cmd.py", line 688, in execute
        raise GitCommandError(command, status, stderr_value, stdout_value)
      File "/usr/local/lib/python2.7/dist-packages/git/exc.py", line 74, in __init__
        super(GitCommandError, self).__init__(command, status, stderr, stdout)
      File "/usr/local/lib/python2.7/dist-packages/git/exc.py", line 54, in __init__
        self.stdout = stdout and u"\n  stdout: '%s'" % safe_decode(stdout) or ''
      File "/usr/local/lib/python2.7/dist-packages/git/compat.py", line 74, in safe_decode
        raise TypeError('Expected bytes or text, but got %r' % (s,))
    TypeError: Expected bytes or text, but got <cStringIO.StringO object at 0x7f17a2ec36c0>
    

    Using:
    Name: GitPython
    Version: 2.1.3

    python 2.7

    On Ubuntu 16.04.2 LTS

  3. wohauser commented on Apr 20, 2017

    @wohauser
    Author

    The error is the same using the version you tested (39335e6)

  4. wohauser commented on May 16, 2017

    @wohauser
    Author

    Ping

  5. Byron commented on Jun 10, 2017

    @Byron
    Member

    I tried to reproduce it again, and in python2.6 I get other errors than in python 3. In any case it does not work at least when done interactively. There are a few tests which obviously don't fail, but they don't try it on a path filter that yields no files.
    It should be relatively straightforward to reproduce the issue in case you are interested.

    screen shot 2017-06-10 at 20 12 46

  6. the-owl commented on Jul 16, 2018

    @the-owl

    I'm having a similar issue. It seems that this bug is generic and affects all git commands: calling any git command that returns error while output_stream is set leads to this TypeError. Simple example (run this in any git repo, python 2.7):

    import git
    import tempfile
    
    repo = git.Repo.init('.')
    tf = tempfile.TemporaryFile()
    repo.git.checkout('non-existent-branch', output_stream=tf)
    

    On my machine (Python 2.7.14, Linux, GitPython 2.1.10) this script produces the following output:

    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/lib/python2.7/site-packages/git/cmd.py", line 548, in <lambda>
        return lambda *args, **kwargs: self._call_process(name, *args, **kwargs)
      File "/usr/lib/python2.7/site-packages/git/cmd.py", line 1014, in _call_process
        return self.execute(call, **exec_kwargs)
      File "/usr/lib/python2.7/site-packages/git/cmd.py", line 825, in execute
        raise GitCommandError(command, status, stderr_value, stdout_value)
      File "/usr/lib/python2.7/site-packages/git/exc.py", line 78, in __init__
        super(GitCommandError, self).__init__(command, status, stderr, stdout)
      File "/usr/lib/python2.7/site-packages/git/exc.py", line 58, in __init__
        self.stdout = stdout and u"\n  stdout: '%s'" % safe_decode(stdout) or ''
      File "/usr/lib/python2.7/site-packages/git/compat.py", line 74, in safe_decode
        raise TypeError('Expected bytes or text, but got %r' % (s,))
    TypeError: Expected bytes or text, but got <open file '<fdopen>', mode 'w+b' at 0x7fc0914d1300>
    

    https://github.com/gitpython-developers/GitPython/blob/master/git/cmd.py#L797
    This line looks suspicious: while stderr_value is set to result of proc.stderr.read(), stdout_value is set to output_stream object.

  7. Byron commented on Jul 23, 2018

    @Byron
    Member

    @the-owl Thanks for your input! It looks like your code-example is perfect for a small unit-test due it it being perfectly isolated. The parameter docs clearly state that a file-like object is expected, and the example above should work.
    Maybe a fix is rather straightforward, would you want to have a go at it?

  8. added 2 commits that reference this issue on Jul 24, 2018
    e661339
    2011c5d
  9. the-owl commented on Jul 24, 2018

    @the-owl

    @Byron Yes, the fix is really straightforward - just a single line in cmd.py. I've sent a PR that fixes the issue, along with a test that fails without the fix: #782

  10. added a commit that references this issue on Apr 28, 2025
    b3d9b8d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions