diff --git a/pygittools/tui/branches.py b/pygittools/tui/branches.py
index 0c655bf..2ec9b20 100644
--- a/pygittools/tui/branches.py
+++ b/pygittools/tui/branches.py
@@ -8,7 +8,22 @@ from pygit2 import Commit, GitError, Repository, reference_is_valid_name
 def current_branch_name(repo: Repository) -> str:
 	if repo.head_is_detached:
 		return "(detached)"
-	return repo.head.shorthand or "(detached)"
+	try:
+		name = repo.head.shorthand
+	except GitError:
+		name = _unborn_branch_name(repo)
+	return name or "(detached)"
+
+
+def _unborn_branch_name(repo: Repository) -> str:
+	try:
+		target = repo.lookup_reference("HEAD").target
+	except GitError:
+		return "(detached)"
+	prefix = "refs/heads/"
+	if isinstance(target, str) and target.startswith(prefix):
+		return target.removeprefix(prefix)
+	return "(detached)"
 
 
 def list_local_branches(repo: Repository) -> list[str]:
@@ -34,9 +49,12 @@ def create_branch_from_current(repo: Repository, name: str) -> tuple[bool, str]:
 	if branch in repo.branches.local:
 		return False, f"Branch already exists: {branch}"
 	try:
-		commit = repo.head.peel(Commit)
-		repo.branches.create(branch, commit)
-		repo.checkout(ref_name)
+		if repo.head_is_unborn:
+			repo.set_head(ref_name)
+		else:
+			commit = repo.head.peel(Commit)
+			repo.branches.create(branch, commit)
+			repo.checkout(ref_name)
 	except GitError as exc:
 		message = str(exc).strip()
 		return False, message or "Failed to create branch"
diff --git a/pygittools/tui/branches_test.py b/pygittools/tui/branches_test.py
index 4b7faec..9456e55 100644
--- a/pygittools/tui/branches_test.py
+++ b/pygittools/tui/branches_test.py
@@ -22,6 +22,22 @@ def test_current_branch_name_when_detached(committed_repo: Repository) -> None:
 	assert current_branch_name(committed_repo) == "(detached)"
 
 
+def test_current_branch_name_when_unborn(repo: Repository) -> None:
+	assert repo.head_is_unborn
+	target = repo.lookup_reference("HEAD").target
+	assert isinstance(target, str)
+	assert current_branch_name(repo) == target.removeprefix("refs/heads/")
+
+
+def test_create_branch_from_unborn_head(repo: Repository) -> None:
+	ok, error = create_branch_from_current(repo, "main")
+	assert ok is True
+	assert error == ""
+	assert current_branch_name(repo) == "main"
+	assert repo.head_is_unborn
+	assert "main" not in list_local_branches(repo)
+
+
 def test_list_local_branches_sorted(committed_repo: Repository) -> None:
 	commit = committed_repo.get(committed_repo.head.target)
 	committed_repo.branches.create("feature", commit)
diff --git a/pygittools/tui/pages_test.py b/pygittools/tui/pages_test.py
index 4b04dfe..965b430 100644
--- a/pygittools/tui/pages_test.py
+++ b/pygittools/tui/pages_test.py
@@ -1,16 +1,18 @@
 from __future__ import annotations
 
 import json
+from collections.abc import Callable
 from pathlib import Path
 from unittest.mock import MagicMock
 
 import pytest
-from pygit2 import Oid, Repository, Signature
+from pygit2 import Commit, Oid, Repository, Signature
 
 from pygittools.tasks import BOARD_REF_PREFIX, EMPTY_TREE_OID_HEX, TASK_REF_PREFIX, Board, Task
+from pygittools.tui.branches import current_branch_name
 from pygittools.tui.pages.branches import BranchPickerPage, branch_picker_page
 from pygittools.tui.pages.help import HelpPage, help_page
-from pygittools.tui.pages.home import home_page
+from pygittools.tui.pages.home import HomePage, home_page
 from pygittools.tui.pages.no_repo import NoRepoPage
 from pygittools.tui.pages.projects import ProjectsPage, projects_page
 from pygittools.tui.pages.task_editor import TaskEditorPage
@@ -55,6 +57,77 @@ def test_home_page_push_help(page_ctx: PageContext) -> None:
 	assert isinstance(result.next_page, HelpPage)
 
 
+def test_home_page_draws_detached_head(committed_repo: Repository) -> None:
+	commit = committed_repo.get(committed_repo.head.target)
+	committed_repo.set_head(commit.id)
+	ctx = PageContext(repo=committed_repo, repo_path=Path(committed_repo.path))
+	page = home_page()
+	page.on_enter(ctx)
+	page.draw(0, 20, 80)
+	assert current_branch_name(committed_repo) == "(detached)"
+	assert "j/k move" in page.status_text()
+	page.set_active_tab("log")
+	page.draw(0, 20, 80)
+	assert "No commits" not in page.status_text()
+
+
+def test_empty_repo_can_create_branch_and_commit(repo: Repository) -> None:
+	assert repo.head_is_unborn
+	assert list(repo.branches.local) == []
+	ctx = PageContext(repo=repo, repo_path=Path(repo.path))
+	page = home_page()
+	assert isinstance(page, HomePage)
+	page.on_enter(ctx)
+	page.draw(0, 20, 80)
+	page.set_active_tab("log")
+	page.draw(0, 20, 80)
+	assert page.status_text() == "No commits — j/k move"
+	page.set_active_tab("status")
+	page.draw(0, 20, 80)
+
+	page.handle_key(KEY_UP)
+	opened = page.handle_key(KEY_ENTER)
+	assert opened.action == PageAction.PUSH
+	assert isinstance(opened.next_page, BranchPickerPage)
+	picker = opened.next_page
+	picker.on_enter(ctx)
+	picker.draw(0, 20, 80)
+	for char in "feature":
+		picker.handle_key(ord(char))
+	created = picker.handle_key(KEY_ENTER)
+	assert created.action == PageAction.POP
+	assert current_branch_name(repo) == "feature"
+
+	workdir = repo.workdir
+	assert workdir is not None
+	(Path(workdir) / "hello.txt").write_text("hello\n", encoding="utf-8")
+	page.draw(0, 20, 80)
+	page.handle_key(KEY_DOWN)
+	_press_until(page, KEY_DOWN, lambda hint: hint.startswith("Enter stage —"))
+	page.handle_key(KEY_ENTER)
+	_press_until(page, KEY_UP, lambda hint: "type message" in hint.casefold())
+	for char in "init":
+		page.handle_key(ord(char))
+	page.handle_key(KEY_ENTER)
+
+	assert not repo.head_is_unborn, page.changes.status_hint()
+	assert current_branch_name(repo) == "feature"
+	assert "feature" in repo.branches.local
+	assert repo.head.peel(Commit).message.splitlines()[0] == "init"
+	page.set_active_tab("log")
+	page.draw(0, 20, 80)
+	assert "No commits" not in page.status_text()
+
+
+def _press_until(page: HomePage, key: int, ready: Callable[[str], bool]) -> None:
+	for _ in range(12):
+		hint = page.status_text()
+		if ready(hint):
+			return
+		page.handle_key(key)
+	raise AssertionError(page.status_text())
+
+
 def test_home_page_draw_without_context() -> None:
 	page = home_page()
 	page.draw(0, 10, 80)
diff --git a/pygittools/tui/worktree.py b/pygittools/tui/worktree.py
index 73f61cd..5ca6abd 100644
--- a/pygittools/tui/worktree.py
+++ b/pygittools/tui/worktree.py
@@ -4,7 +4,7 @@ from __future__ import annotations
 
 import subprocess
 
-from pygit2 import Commit, IndexEntry, Repository
+from pygit2 import Commit, GitError, Index, IndexEntry, Repository, Tree
 from pygit2.enums import FileStatus
 
 from pygittools.hooks_push import git_executable
@@ -62,12 +62,7 @@ def stage_paths(repo: Repository, paths: list[str]) -> None:
 
 def unstage_path(repo: Repository, path: str) -> None:
 	index = repo.index
-	head_tree = repo.head.peel(Commit).tree
-	if path in head_tree:
-		entry = head_tree[path]
-		index.add(IndexEntry(path, entry.id, entry.filemode))
-	else:
-		index.remove(path)
+	_unstage_index_path(index, _head_tree(repo), path)
 	index.write()
 
 
@@ -75,16 +70,29 @@ def unstage_paths(repo: Repository, paths: list[str]) -> None:
 	if not paths:
 		return
 	index = repo.index
-	head_tree = repo.head.peel(Commit).tree
+	head_tree = _head_tree(repo)
 	for path in paths:
-		if path in head_tree:
-			entry = head_tree[path]
-			index.add(IndexEntry(path, entry.id, entry.filemode))
-		else:
-			index.remove(path)
+		_unstage_index_path(index, head_tree, path)
 	index.write()
 
 
+def _head_tree(repo: Repository) -> Tree | None:
+	if repo.head_is_unborn:
+		return None
+	try:
+		return repo.head.peel(Commit).tree
+	except GitError:
+		return None
+
+
+def _unstage_index_path(index: Index, head_tree: Tree | None, path: str) -> None:
+	if head_tree is not None and path in head_tree:
+		entry = head_tree[path]
+		index.add(IndexEntry(path, entry.id, entry.filemode))
+	else:
+		index.remove(path)
+
+
 def commit_staged(repo: Repository, message: str) -> tuple[bool, str]:
 	"""Create a commit via the git CLI so client hooks run. Returns (ok, error)."""
 	trimmed = message.strip()
diff --git a/pygittools/tui/worktree_test.py b/pygittools/tui/worktree_test.py
index 10ff96b..abbb731 100644
--- a/pygittools/tui/worktree_test.py
+++ b/pygittools/tui/worktree_test.py
@@ -111,6 +111,16 @@ def test_unstage_tracked_file(committed_repo: Repository) -> None:
 	assert "tracked.txt" not in staged
 
 
+def test_unstage_new_file_on_unborn_head(repo: Repository) -> None:
+	path = Path(repo.workdir) / "hello.txt"
+	path.write_text("hello\n", encoding="utf-8")
+	stage_path(repo, "hello.txt")
+	unstage_path(repo, "hello.txt")
+	staged, _, untracked = categorize_status(repo)
+	assert staged == []
+	assert "hello.txt" in untracked
+
+
 def test_unstage_new_file_removes_from_index(committed_repo: Repository) -> None:
 	path = Path(committed_repo.workdir) / "new.txt"
 	path.write_text("x\n", encoding="utf-8")
