简体   繁体   中英

git push through python subprocess.Popen() with authentication

I am trying to use git with python subprocess.Popen()

So far this is my code

import subprocess

gitPath = 'C:/path/to/git/cmd.exe'
repoPath = 'C:/path/to/my/repo'
repoUrl = 'https://www.github.com/login/repo'

#list to set directory and working tree
dirList = ['--git-dir='+repoPath+'/.git','--work-tree='+repoPath]

#init git
subprocess.Popen([gitPath] + ['init',repoPath],cwd=repoPath)

#add remote
subprocess.Popen([gitPath] + dirList + ['remote','add','origin',repoUrl],cwd=repoPath)

#Check status, returns files to be committed etc, so a working repo exists there
subprocess.Popen([gitPath] + dirList + ['status'],cwd=repoPath)

#Adds all files in folder
subprocess.Popen([gitPath] + dirList + ['add','.'],cwd=repoPath)

#Push, gives error:
subprocess.Popen([gitPath] + dirList + ['push','origin','master],cwd=repoPath)

This works, except for the last command. That's where I get this error:

bash.exe: warning: could not find /tmp, please create!
fatal: 'git' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Of course I wouldn't expect it to work, since I did not put my login details anywhere in the code. I do not have any idea how I can add it though. I have a folder /.ssh in the C:/users/myUser directory. I tried changing the last line of my code to this:

env = {'HOME' : 'C:/users/myUser'}
subprocess.Popen([gitPath] + dirList + ['push','origin','master'],cwd=repoPath,env=env)

in the hope of git finding the /.ssh folder, but without any luck. I also tried without 'dirList', but it didn't matter. I also tried changing the name 'origin' into an url, but that also didn't work.

I do not mind if I am using the.ssh keys I already created, or if I have to use a method with login/password. I am not looking to use a git library though.

There might be a race condition in this script. Earlier subprocess might not finish while a next one errors out because a git command depends on the previous ones. Instead it is possible to start a subprocess and wait until it is finished with subprocess.run() or subprocess.check_ouput() . Might still need adjustment depending on layout

import subprocess
import shutil

# get a location of git
gitPath = shutil.which('git')
repoPath = 'C:/path/to/my/repo'
repoUrl = 'https://www.github.com/login/repo'

# list to set directory and working tree
dirList = ['--git-dir='+repoPath+'/.git', '--work-tree='+repoPath]

# init git
subprocess.run([gitPath] + ['init', repoPath], cwd=repoPath)

# add remote
subprocess.run([gitPath] + dirList + ['remote', 'add', 'origin', repoUrl], cwd=repoPath)

# check status, returns files to be committed etc, so a working repo exists there
subprocess.run([gitPath] + dirList + ['status'], cwd=repoPath)

# adds all files in folder
subprocess.run([gitPath] + dirList + ['add', '.'], cwd=repoPath)

# push
subprocess.run([gitPath] + dirList + ['push', 'origin', 'main'], cwd=repoPath)

For credentials could use Windows Credential Manager , cache, manager, --global , etc. - depends on what's needed.

git config --global credential.helper cache
# or in python
subprocess.run([gitPath] + ['config', 'credential.helper', 'cache', repoPath], cwd=repoPath)

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