From 3507b09a5d07cd1c1d3a4c4304b078c42a362b42 Mon Sep 17 00:00:00 2001 From: Michael Bridgen Date: Thu, 26 Jan 2023 22:25:32 +0000 Subject: [PATCH] Support clones from Azure DevOps In general, go-git can't clone from Azure DevOps, because the latter requires the capabilities multi_ack and multi_ack_detailed, which aren't implemented. However, there's now a workaround, which boils down to this: pretend, for the initial clone, that those capabilities _are_ supported, and expect them not to be used. (See https://github.com/go-git/go-git/pull/613 for more on this workaround.) Signed-off-by: Michael Bridgen --- sdk/go.mod | 2 +- sdk/go/auto/git.go | 16 ++++++++++++++++ sdk/go/auto/git_test.go | 2 ++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/sdk/go.mod b/sdk/go.mod index 7272ae82face..8d85bf4cca79 100644 --- a/sdk/go.mod +++ b/sdk/go.mod @@ -40,7 +40,7 @@ require ( ) require ( - github.com/go-git/go-git/v5 v5.4.2 + github.com/go-git/go-git/v5 v5.5.1 github.com/pkg/term v1.1.0 github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 diff --git a/sdk/go/auto/git.go b/sdk/go/auto/git.go index 3e9cfa2086dc..68b7a12b4dab 100644 --- a/sdk/go/auto/git.go +++ b/sdk/go/auto/git.go @@ -23,6 +23,8 @@ import ( git "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability" + "github.com/go-git/go-git/v5/plumbing/transport" "github.com/go-git/go-git/v5/plumbing/transport/http" "github.com/go-git/go-git/v5/plumbing/transport/ssh" ) @@ -111,12 +113,26 @@ func setupGitRepo(ctx context.Context, workDir string, repoArgs *GitRepo) (strin cloneOptions.ReferenceName = refName } + // Azure DevOps requires multi_ack and multi_ack_detailed capabilities, which go-git doesn't + // implement. But: it's possible to do a full clone by saying it's _not_ _un_supported, in which + // case the library happily functions so long as it doesn't _actually_ get a multi_ack packet. See + // https://github.com/go-git/go-git/blob/v5.5.1/_examples/azure_devops/main.go. + oldUnsupportedCaps := transport.UnsupportedCapabilities + // This check is crude, but avoids having another dependency to parse the git URL. + if strings.Contains(repoArgs.URL, "dev.azure.com") { + transport.UnsupportedCapabilities = []capability.Capability{ + capability.ThinPack, + } + } + // clone repo, err := git.PlainCloneContext(ctx, workDir, false, cloneOptions) if err != nil { return "", fmt.Errorf("unable to clone repo: %w", err) } + transport.UnsupportedCapabilities = oldUnsupportedCaps + if repoArgs.CommitHash != "" { // checkout commit if specified w, err := repo.Worktree() diff --git a/sdk/go/auto/git_test.go b/sdk/go/auto/git_test.go index 19c34362bed5..5bc39678d822 100644 --- a/sdk/go/auto/git_test.go +++ b/sdk/go/auto/git_test.go @@ -33,6 +33,7 @@ func TestGitClone(t *testing.T) { Name: "testo", Email: "testo@example.com", }, + AllowEmptyCommits: true, }) assert.NoError(t, err) @@ -63,6 +64,7 @@ func TestGitClone(t *testing.T) { Name: "testo", Email: "testo@example.com", }, + AllowEmptyCommits: true, }) assert.NoError(t, err)