revert: remove _ convention and redundant Name() changes

Quentin Gliech and Claude Opus 4.6 (1M context) created

Revert the upload handler, ResolveRepo, Name() cache change, and
resolver guard — all unnecessary since trunk already handles default
repos via IsDefaultRepo(). The _ convention stays in the frontend URL
routing only.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Change summary

api/graphql/resolvers/repo.go       |  3 ---
api/http/git_file_upload_handler.go | 19 +++++++++++++++----
cache/multi_repo_cache.go           | 16 ++++++----------
cache/repo_cache_common.go          |  5 -----
4 files changed, 21 insertions(+), 22 deletions(-)

Detailed changes

api/graphql/resolvers/repo.go 🔗

@@ -28,9 +28,6 @@ func (repoResolver) Name(_ context.Context, obj *models.Repository) (*string, er
 		return nil, nil
 	}
 	name := obj.Repo.Name()
-	if name == "" {
-		return nil, nil
-	}
 	return &name, nil
 }
 

api/http/git_file_upload_handler.go 🔗

@@ -2,19 +2,20 @@ package http
 
 import (
 	"encoding/json"
+	"fmt"
 	"io"
 	"net/http"
 
 	"github.com/gorilla/mux"
 
+	"github.com/git-bug/git-bug/api/auth"
 	"github.com/git-bug/git-bug/cache"
 )
 
 // implement a http.Handler that will accept and store content into git blob.
 //
 // Expected gorilla/mux parameters:
-//   - "owner" : ignored (reserved for future multi-owner support); "_" for local
-//   - "repo"  : the name of the repo, or "_" for the default one
+//   - "repo" : the ref of the repo or "" for the default one
 type gitUploadFileHandler struct {
 	mrc *cache.MultiRepoCache
 }
@@ -28,9 +29,10 @@ func (gufh *gitUploadFileHandler) ServeHTTP(rw http.ResponseWriter, r *http.Requ
 	var err error
 
 	repoVar := mux.Vars(r)["repo"]
-	if repoVar == "_" {
+	switch repoVar {
+	case "":
 		repo, err = gufh.mrc.DefaultRepo()
-	} else {
+	default:
 		repo, err = gufh.mrc.ResolveRepo(repoVar)
 	}
 
@@ -39,6 +41,15 @@ func (gufh *gitUploadFileHandler) ServeHTTP(rw http.ResponseWriter, r *http.Requ
 		return
 	}
 
+	_, err = auth.UserFromCtx(r.Context(), repo)
+	if err == auth.ErrNotAuthenticated {
+		http.Error(rw, "read-only mode or not logged in", http.StatusForbidden)
+		return
+	} else if err != nil {
+		http.Error(rw, fmt.Sprintf("loading identity: %v", err), http.StatusInternalServerError)
+		return
+	}
+
 	// 100MB (github limit)
 	var maxUploadSize int64 = 100 * 1000 * 1000
 	r.Body = http.MaxBytesReader(rw, r.Body, maxUploadSize)

cache/multi_repo_cache.go 🔗

@@ -60,17 +60,13 @@ func (c *MultiRepoCache) DefaultRepo() (*RepoCache, error) {
 	panic("unreachable")
 }
 
-// ResolveRepo retrieve a repository by name or slug
-func (c *MultiRepoCache) ResolveRepo(ref string) (*RepoCache, error) {
-	// "_" is the conventional placeholder for the default repository,
-	// consistent with the REST API path convention /api/repos/_/_/...
-	if ref == "_" {
-		return c.DefaultRepo()
+// ResolveRepo retrieves a repository by name
+func (c *MultiRepoCache) ResolveRepo(name string) (*RepoCache, error) {
+	r, ok := c.repos[name]
+	if !ok {
+		return nil, fmt.Errorf("unknown repo")
 	}
-	if r, ok := c.repos[ref]; ok {
-		return r, nil
-	}
-	return nil, fmt.Errorf("unknown repo %q", ref)
+	return r, nil
 }
 
 // AllRepos returns all registered repositories. Order is not guaranteed.

cache/repo_cache_common.go 🔗

@@ -12,12 +12,7 @@ import (
 	"github.com/git-bug/git-bug/util/multierr"
 )
 
-// Name returns the registered name of this repository, or empty string for
-// the default (unnamed) repository.
 func (c *RepoCache) Name() string {
-	if c.name == defaultRepoName {
-		return ""
-	}
 	return c.name
 }