dockerimg: add only git objects to docker image

Instead of copying the entire working directory
(including uncommitted changes, hooks, and config files),
create a bare git repository and use git clone --reference.

This approach:
- Avoids copying uncommitted changes, hooks, and local config files
- Works correctly with git worktrees and submodules
- Reduces Docker image size substantially
- Maintains all git history and functionality

Fixes boldsoftware/sketch#190

Co-Authored-By: sketch <hello@sketch.dev>
Change-ID: s6af36147e2c4df00k
diff --git a/dockerimg/githttp.go b/dockerimg/githttp.go
index b7203c0..ecd46a1 100644
--- a/dockerimg/githttp.go
+++ b/dockerimg/githttp.go
@@ -7,7 +7,9 @@
 	"log/slog"
 	"net/http"
 	"net/http/cgi"
+	"os"
 	"os/exec"
+	"path/filepath"
 	"runtime"
 	"strings"
 	"time"
@@ -107,6 +109,12 @@
 		}
 	}
 
+	// Dumb hack for bare repos: if the path starts with .git, and there is no .git, strip it off.
+	path := r.URL.Path
+	if _, err := os.Stat(filepath.Join(g.gitRepoRoot, path)); os.IsNotExist(err) {
+		path = strings.TrimPrefix(path, "/.git") // turn /.git/info/refs into /info/refs
+	}
+
 	w.Header().Set("Cache-Control", "no-cache")
 	h := &cgi.Handler{
 		Path: gitBin,
@@ -114,7 +122,7 @@
 		Dir:  g.gitRepoRoot,
 		Env: []string{
 			"GIT_PROJECT_ROOT=" + g.gitRepoRoot,
-			"PATH_INFO=" + r.URL.Path,
+			"PATH_INFO=" + path,
 			"QUERY_STRING=" + r.URL.RawQuery,
 			"REQUEST_METHOD=" + r.Method,
 			"GIT_HTTP_EXPORT_ALL=true",