重定向 'git clone' 的标准输出/标准错误/标准输入

8

我想编写一个程序,它将克隆远程Git存储库,然后执行一系列其他操作。问题是,“git clone”会要求输入密码。当我打开管道到stdin/out/err以运行“git clone”时,它并不起作用,因为它在TTY上运行git-remote-http,并提示输入密码。

我想从我的程序中传递密码。我正在使用Python和subprocess中的Popen。下面的代码无法正常工作。

Popen(['git', 'clone', 'https://my.git.repo/repo.git'], shell=False, stdin=PIPE, stdout=PIPE, stderr=PIPE)

我该如何实现这个目标?

如果您切换到SSH,可以使用ssh-agent避免输入密码提示。 - Douglas Leeder
也许你可以使用 https://username:password@host ? - Douglas Leeder
我无法切换到ssh,也不想使用用户名:密码语法,因为它会将此url与明文密码存储在.git / config中。 - Kylo
3个回答

2
如果你不想使用评论者提到的挑战式认证,我会使用pexpect来自动化这种交互。

这正是我所需要的。但是有一个问题。我如何访问子进程的返回代码?因为如果我执行child.wait(),由于未读取的输出,它会永远阻塞;而如果我执行child.expect(pexpect.EOF),然后再执行child.wait(),我会得到一个异常,指出子进程已经退出。 - Kylo
1
好的。我找到了。在 child.expect(pexpect.EOF) 之后,我调用了 child.close()。 - Kylo

2
您可以通过 git clone https://foo:bar@my.git.repo/repo.git 命令获取数据,然后使用命令 git remote set-url origin https://my.git.repo/repo.git 清除密码。但是,在克隆开始和 URL 更改之间存在竞态条件。

1

如果您愿意使用库,可以尝试使用Dulwich

from dulwich import porcelain
porcelain.clone("https://example.com/repo.git", username="youruser", password="yourpassword")

这个似乎没有存储用户名或密码(我在.git目录中搜索了使用的密码,但没有发现任何东西)。

来源

因为找到一个最新的Git库而没有任何明显问题是相当麻烦的,所以我想列出我的来源供将来参考:

  1. 2009年PTBNL的回答“Python Git模块经验?[已关闭]”推荐使用Dulwich等工具。
  2. 2019年Trishayyyy的回答“在Python代码中使用Git命令”仍然推荐使用Dulwich(和PyGit)。
  3. Dulwich porcelain文档关于clone,遗憾的是没有提到身份验证是否可能。
  4. harvin的回答“dulwich-从远程repo进行克隆身份验证”提到使用username:password@语法,确实可以在Dulwich clone中进行身份验证。
  5. 受最后一个链接回答的启发,我进一步检查了源代码,并偶然发现了usernamepassword参数。我在我的回答中记录了这一点,回答了“dulwich-从远程repo进行克隆身份验证”的问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接