简体   繁体   中英

Pushing a git repo to GitHub using Python's subprocess returns exit code 128

I'm currently trying to write a module of my own for using git. For this reason I would like to avoid using GitPython.

My code for pushing at the moment is as follows:

class Git(object):
    def __call_git(self,*args):
        a = [self.path+"git"] + list(args)
        return subprocess.check_output(a,stdin=subprocess.PIPE)
    def push(self,username,password,remote="origin",branch="master"):
        url = self.__call_git("remote","get-url",remote).replace("\n","")
        url = "".join(["https://",username,":",password,"@",url[8:]])
        output = self.__call_git("push","--repo",url,branch)
        return output

This tries to push to git by executing the command git push --repo https://username:password@github.com/repo.git to avoid having to work with stdin to pass the username and password to git. This works on the command line, but whenever I try running this code, I get the following output:

Traceback (most recent call last):
  File "<pyshell#81>", line 1, in <module>
    g.push("username","password")
  File "/home/git.py", line 68, in push
    output = self.__call_git("push","--repo",url,branch)
  File "/home/git.py", line 37, in __call_git
    return subprocess.check_output(a,stdin=subprocess.PIPE)
  File "/usr/lib/python2.7/subprocess.py", line 574, in check_output
    raise CalledProcessError(retcode, cmd, output=output)
CalledProcessError: Command '['git', 'push', '--repo', 'https://username:password@github.com/repo.git', 'master']' returned non-zero exit status 128

Git seems to react this way whenever the push command is involved, even for something like git push . Using something like subprocess.Popen and setting stdin=PIPE,stdout=PIPE,stderr=PIPE , process.poll() still gives 128 and process.stdout.read() gives nothing.

Can anyone explain why this is happening, and provide a solution to my problem?

---EDIT---

Following some advice from here , I've run a bunch of git commands with GIT_TRACE=1 . I've seen that git push is the only command that I am using so far that has a trace: run_command line.

19:57:21.694468 run-command.c:334       trace: run_command: 'git-remote-https'

This makes me suspect the cause may lie in something else from the link above.

I cannot run git push origin master from subprocess, even with the environment. I think it has to do with a race condition created by the lfs pre-push hook. Subprocess calls git push , git push calls git lfs , git push ends before lfs or lfs kills the stdout/return code. Git push works normally in the command line, so one would think that invoking it through suprocess would work the same, since the module literally sends the same commands to a shell environment.

While the issue does not lie in lfs for me, perhaps it lies in that call to git-remote-https ?

When I've had problems with running git using subprocess I've had to add shell=True to my subprocess function call.In your case:

subprocess.check_output(...other args, shell=True)

You may want to read the security considerations found in the subprocess docs before you do that though.

Subprocess Security Considerations

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM