如何在Go中禁用git clone的凭证提示?
我试图在Go中运行git clone
的等价物,但是如果提示输入来自stdin(例如,如果ssh密钥未在远程存储库中设置),则我想退出该命令。有没有办法做到这一点?现在它只会阻止输入。如何在Go中禁用git clone的凭证提示?
UPDATE:特殊的git解决方案。
由于v 2.3 git支持环境设置GIT_TERMINAL_PROMPT=0
,它表示不要求凭据但失败。
func main() {
cmd := exec.Command("git", "clone", "https://github.com/some/non-existing-repo")
os.Setenv("GIT_SSH_COMMAND", "ssh -oBatchMode=yes") //
cmd.Env = append(os.Environ(), "GIT_TERMINAL_PROMPT=1", "GIT_SSH_COMMAND='ssh -oBatchMode=yes'")
cmd.Stdout = os.Stdout
err := cmd.Run()
if err != nil {
log.Println("Error: ", err)
}
}
这很好,唯一的问题是,即使没有提示输入,仍然会调用Read(),所以它在技术上会中止git clone op,即使没有提示输入密码 – sreya
我几乎写了这个答案,但我首先双重检查了文档。这确实不行。我无法想出一个可行的解决方案,但我也没有很努力......(为什么这个标记被接受,如果它不起作用?) –
我检查了 - 是'git'试图读取stdin甚至不需要。所以我们需要一种方法来区分这种情况。 –
SSH解决方法:
接受的答案只会以http克隆工作。如果你想使用ssh的方式来做到这一点下面的工作:
//disables stdin prompts for username/password. If passwordless-ssh isn't configured we want to fail
os.Setenv("GIT_SSH_COMMAND", "ssh -oBatchMode=yes")
cmd := exec.Command(name, args...)
return cmd.CombinedOutput()
man git
条目GIT_SSH_COMMAND
如果这些环境变量的设置,那么git的提取和混帐推将使用 当他们需要连接到远程系统时,使用指定的命令而不是ssh。命令将会给 两个或四个参数:URL中的用户名@主机(或主机)和要在该远程系统上执行的shell命令(可选地,前面加上-p(字面上))和 端口当它指定了默认的SSH端口以外的URL。
$ GIT_SSH_COMMAND优先于$ GIT_SSH,并由shell解释,允许包含 附加参数。另一方面,$ GIT_SSH必须是 程序的路径(如果需要其他参数,它可以是包装程序的外壳脚本)。
通常通过您的个人.ssh/config文件配置任何所需的选项会更容易。 有关更多详细信息,请参阅您的ssh文档。
man git
条目GIT_TERMINAL_PROMPT
如果该环境变量被设置为0,git会不在终端上提示(例如,当 要求HTTP认证)。
如何使用git代替原生golang解决方案。这将意味着你的程序不会需要git,你不会有stdin和git二进制文件的问题。从https://godoc.org/gopkg.in/src-d/go-git.v4检出此示例。另外一个好处是文档非常好,这是来自该项目的examples页面。它也支持ssh协议。这是一个git的full comparison vs这个项目。
import (
"fmt"
"os"
"gopkg.in/src-d/go-git.v4"
. "gopkg.in/src-d/go-git.v4/_examples"
)
// Basic example of how to clone a repository using clone options.
func main() {
url := "https://github.com/some/non-existing-repo"
directory := "/foo/bar"
// Clone the given repository to the given directory
Info("git clone %s %s --recursive", url, directory)
r, err := git.PlainClone(directory, false, &git.CloneOptions{
URL: url,
RecurseSubmodules: git.DefaultSubmoduleRecursionDepth,
})
CheckIfError(err)
}
您是否尝试过将'nil'传递给Stdin? https://golang.org/pkg/os/exec/#Cmd另外请用CommandContext和StdinPipe检查下面的例子。 –
@EugeneLisitsky是通过零没有做任何事情。 golang.org/pkg/os/exec/#Cmd.StdinPipe好像关闭stdinPipe应该保持命令不被阻塞我仍然会被提示输入密码。 – sreya
请发表您的解决方案作为答案,而不是编辑问题请参阅[游览] –