Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 21 additions & 12 deletions libs/git/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ type RepositoryInfo struct {
WorktreeRoot string
}

// gitInfo holds the fields we read from get-status's git_info. Only id and path
// are reliable: branch/commit/url are absent for git-in-data-plane folders (and
// deprecated on the workspace API), so those are read from the Repos API by id.
type gitInfo struct {
Branch string `json:"branch"`
HeadCommitID string `json:"head_commit_id"`
Path string `json:"path"`
URL string `json:"url"`
ID int64 `json:"id"`
Path string `json:"path"`
}

type response struct {
Expand Down Expand Up @@ -100,17 +101,25 @@ func fetchRepositoryInfoAPI(ctx context.Context, path string, w *databricks.Work
return result, err
}

// Check if GitInfo is present and extract relevant fields
gi := response.GitInfo
if gi != nil {
fixedPath := ensureWorkspacePrefix(gi.Path)
result.OriginURL = gi.URL
result.LatestCommit = gi.HeadCommitID
result.CurrentBranch = gi.Branch
result.WorktreeRoot = fixedPath
} else {
if gi == nil {
log.Infof(ctx, "Failed to load git info from %s", apiEndpoint)
return result, nil
}
result.WorktreeRoot = ensureWorkspacePrefix(gi.Path)

// get-status omits branch/commit/url for git-in-data-plane folders; only
// classic Repos return them inline, and those fields are being deprecated on
// the workspace API. Read them from the Repos API by id, which is
// authoritative for both folder types.
repo, err := w.Repos.GetByRepoId(ctx, gi.ID)
if err != nil {
log.Warnf(ctx, "failed to load git metadata from Repos API for %s: %s", result.WorktreeRoot, err)
return result, nil
}
result.OriginURL = repo.Url
result.LatestCommit = repo.HeadCommitId
result.CurrentBranch = repo.Branch

return result, nil
}
Expand Down
70 changes: 70 additions & 0 deletions libs/git/info_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package git

import (
"net/http"
"net/http/httptest"
"strings"
"testing"

"github.com/databricks/databricks-sdk-go"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestFetchRepositoryInfoAPIReadsMetadataFromReposAPI(t *testing.T) {
// git-in-data-plane folders: get-status returns only id+path in git_info, so
// branch/commit/url must be recovered from the Repos API by id.
var statusPath string
reposCalled := false
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/api/2.0/workspace/get-status":
statusPath = r.URL.Query().Get("path")
_, _ = w.Write([]byte(`{"object_type":"DIRECTORY","git_info":{"id":123,"path":"/Repos/alice/proj"}}`))
case "/api/2.0/repos/123":
reposCalled = true
_, _ = w.Write([]byte(`{"id":123,"branch":"main","head_commit_id":"abc123","url":"https://github.com/databricks/bundle-examples"}`))
default:
http.Error(w, "unexpected path: "+r.URL.Path, http.StatusNotFound)
}
}))
defer srv.Close()

w := databricks.Must(databricks.NewWorkspaceClient(&databricks.Config{Host: srv.URL, Token: "dummy"}))

info, err := fetchRepositoryInfoAPI(t.Context(), "/Workspace/Repos/alice/proj/sub/dir", w)
require.NoError(t, err)

assert.Equal(t, "/Workspace/Repos/alice/proj/sub/dir", statusPath)
assert.True(t, reposCalled, "Repos API should be called to load git metadata")
assert.Equal(t, "/Workspace/Repos/alice/proj", info.WorktreeRoot)
assert.Equal(t, "main", info.CurrentBranch)
assert.Equal(t, "abc123", info.LatestCommit)
assert.Equal(t, "https://github.com/databricks/bundle-examples", info.OriginURL)
}

func TestFetchRepositoryInfoAPINotAGitFolder(t *testing.T) {
// Outside any git folder get-status returns no git_info, so the result is
// empty and the Repos API is never called.
reposCalled := false
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if strings.HasPrefix(r.URL.Path, "/api/2.0/repos/") {
reposCalled = true
}
if r.URL.Path == "/api/2.0/workspace/get-status" {
_, _ = w.Write([]byte(`{"object_type":"DIRECTORY"}`))
return
}
// Ignore the SDK's host-metadata probe and anything else.
_, _ = w.Write([]byte(`{}`))
}))
defer srv.Close()

w := databricks.Must(databricks.NewWorkspaceClient(&databricks.Config{Host: srv.URL, Token: "dummy"}))

info, err := fetchRepositoryInfoAPI(t.Context(), "/Workspace/Users/alice/notebook", w)
require.NoError(t, err)

assert.False(t, reposCalled, "Repos API should not be called when the path is not a git folder")
assert.Equal(t, RepositoryInfo{}, info)
}
Loading