Repository: dolthub/dolt
File: go/libraries/doltcore/dbfactory/git_remote.go (Go)

Code before:
	if err != nil {
		return nil, nil, nil, err
	}
	if !ok {
		return nil, nil, nil, fmt.Errorf("%s is required for git remotes", GitCacheRootParam)
	}
	cacheBase := filepath.Join(cacheRoot, DoltDir, "git-remote-cache")

	cacheRepo, err := cacheRepoPath(cacheBase, remoteURL.String(), ref)
	if err != nil {
		return nil, nil, nil, err
	}

	remoteName := resolveGitRemoteName(params)

	// Serialize cache repo setup across goroutines and processes.
	hashDir := filepath.Dir(cacheRepo)
	if err := os.MkdirAll(hashDir, 0o755); err != nil {
		return nil, nil, nil, err
	}
	initLock := fslock.New(filepath.Join(hashDir, "init.lock"))
	if err := initLock.Lock(); err != nil {
		return nil, nil, nil, err
	}
	defer func() {
		err = errors.Join(err, initLock.Unlock())
	}()

	if err := ensureBareRepo(ctx, cacheRepo); err != nil {
		return nil, nil, nil, err
	}

	// Ensure the configured git remote exists and points to the underlying git remote URL.
	if err := ensureGitRemoteURL(ctx, cacheRepo, remoteName, remoteURL.String()); err != nil {
		return nil, nil, nil, err
	}
	if err := ensureRemoteHasBranches(ctx, cacheRepo, remoteName, remoteURL.String()); err != nil {
		return nil, nil, nil, err
	}

	q := nbs.NewUnlimitedMemQuotaProvider()
	cs, err := nbs.NewGitStore(ctx, nbf.VersionString(), cacheRepo, ref, blobstore.GitBlobstoreOptions{RemoteName: remoteName}, defaultMemTableSize, q)
	if err != nil {
		return nil, nil, nil, err
	}

	vrw := types.NewValueStore(cs)
	ns := tree.NewNodeStore(cs)
	db := datas.NewTypesDatabase(vrw, ns)
	return db, vrw, ns, nil
}

Review comment (bug):
What does it mean if initLock.Unlock errors?  Are we going to get a deadlock in the future if Unlock returns an error?  If so you may want to panic rather than waiting for a deadlock to happen and having to track it back to this error.

Code after:
	if err != nil {
		return nil, nil, nil, err
	}
	if !ok {
		return nil, nil, nil, fmt.Errorf("%s is required for git remotes", GitCacheRootParam)
	}
	cacheBase := filepath.Join(cacheRoot, DoltDir, "git-remote-cache")

	cacheRepo, err := cacheRepoPath(cacheBase, remoteURL.String(), ref)
	if err != nil {
		return nil, nil, nil, err
	}

	remoteName := resolveGitRemoteName(params)

	// Serialize cache repo setup across goroutines and processes.
	hashDir := filepath.Dir(cacheRepo)
	if err := os.MkdirAll(hashDir, 0o755); err != nil {
		return nil, nil, nil, err
	}
	initLock := fslock.New(filepath.Join(hashDir, "init.lock"))
	if err := initLock.Lock(); err != nil {
		return nil, nil, nil, err
	}
	defer func() {
		if unlockErr := initLock.Unlock(); unlockErr != nil {
			panic(fmt.Sprintf("failed to unlock %s: %v", filepath.Join(hashDir, "init.lock"), unlockErr))
		}
	}()

	if err := ensureBareRepo(ctx, cacheRepo); err != nil {
		return nil, nil, nil, err
	}

	// Ensure the configured git remote exists and points to the underlying git remote URL.
	if err := ensureGitRemoteURL(ctx, cacheRepo, remoteName, remoteURL.String()); err != nil {
		return nil, nil, nil, err
	}
	if err := ensureRemoteHasBranches(ctx, cacheRepo, remoteName, remoteURL.String()); err != nil {
		return nil, nil, nil, err
	}

	q := nbs.NewUnlimitedMemQuotaProvider()
	cs, err := nbs.NewGitStore(ctx, nbf.VersionString(), cacheRepo, ref, blobstore.GitBlobstoreOptions{RemoteName: remoteName}, defaultMemTableSize, q)
	if err != nil {
		return nil, nil, nil, err
	}

	vrw := types.NewValueStore(cs)
	ns := tree.NewNodeStore(cs)
	db := datas.NewTypesDatabase(vrw, ns)