diff --git a/backend/internal/git/sync.go b/backend/internal/git/sync.go index 0b4e45e..12f1283 100644 --- a/backend/internal/git/sync.go +++ b/backend/internal/git/sync.go @@ -170,6 +170,24 @@ func (r *Repo) Push(branch string) error { return err } +// HasCommits reports whether the repository has any commit (false on +// a freshly initialised, unborn branch). +func (r *Repo) HasCommits() bool { + r.mu.Lock() + defer r.mu.Unlock() + _, err := r.run("rev-parse", "--verify", "HEAD") + return err == nil +} + +// RemoteBranchExists reports whether origin/branch is known locally +// (run Fetch first for a fresh answer). +func (r *Repo) RemoteBranchExists(branch string) bool { + r.mu.Lock() + defer r.mu.Unlock() + _, err := r.run("rev-parse", "--verify", "refs/remotes/origin/"+branch) + return err == nil +} + // MergeInProgress reports whether a merge has been started but not // yet committed or aborted. func (r *Repo) MergeInProgress() bool { diff --git a/backend/internal/graph/gitsync.go b/backend/internal/graph/gitsync.go index a7af047..5a13d7a 100644 --- a/backend/internal/graph/gitsync.go +++ b/backend/internal/graph/gitsync.go @@ -186,6 +186,20 @@ func (s *Server) backgroundSync() { record(fmt.Errorf("fetch: %w", err), false) return } + // Bootstrap: an empty wiki (no commits yet) adopts the remote live + // branch automatically, so a fresh instance needs no manual reset. + if !repo.HasCommits() { + if repo.RemoteBranchExists(gs.LiveBranch) { + _, err := repo.ResetToRemote(gs.LiveBranch, syncAuthor, syncEmail) + if err != nil { + record(fmt.Errorf("bootstrap från remote: %w", err), true) + } else { + log.Printf("[gitsync] empty wiki bootstrapped from origin/%s", gs.LiveBranch) + record(nil, false) + } + return + } + } current, err := repo.CurrentBranch() if err != nil || current != gs.LiveBranch { // Someone is working on another branch; leave it alone.