Skip to content

Commit 07f78f6

Browse files
andrewleechclaude
andcommitted
Fix Docker builds for git worktrees by mounting main .git directory
When building from a git worktree, the .git file contains a path to the actual .git directory. The Docker container needs access to the main .git directory to properly resolve git information and update submodules. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 3a4cc19 commit 07f78f6

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

src/mpbuild/build.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,38 @@
1414
from . import board_database, find_mpy_root
1515
from .board_database import Board
1616

17+
18+
def get_git_directory(mpy_dir: Path) -> Path | None:
19+
"""
20+
Get the actual .git directory path, handling both regular repos and worktrees.
21+
22+
Args:
23+
mpy_dir: Path to the MicroPython repository root
24+
25+
Returns:
26+
Path to the actual .git directory, or None if not found
27+
"""
28+
git_path = mpy_dir / ".git"
29+
30+
if not git_path.exists():
31+
return None
32+
33+
if git_path.is_dir():
34+
# Regular git repository
35+
return git_path
36+
elif git_path.is_file():
37+
# Git worktree - .git file contains path to actual .git directory
38+
try:
39+
git_file_content = git_path.read_text().strip()
40+
if git_file_content.startswith("gitdir: "):
41+
gitdir_path = git_file_content[8:] # Remove "gitdir: " prefix
42+
return Path(gitdir_path).resolve()
43+
except (OSError, ValueError):
44+
pass
45+
46+
return None
47+
48+
1749
ARM_BUILD_CONTAINER = "micropython/build-micropython-arm"
1850
BUILD_CONTAINERS = {
1951
"stm32": ARM_BUILD_CONTAINER,
@@ -107,6 +139,16 @@ def docker_build_cmd(
107139

108140
mpy_dir = str(port.directory_repo)
109141

142+
# Handle git worktrees by mounting the main .git directory
143+
git_volume_mount = ""
144+
git_dir = get_git_directory(Path(mpy_dir))
145+
if git_dir and not git_dir.is_relative_to(Path(mpy_dir)):
146+
# For worktrees, mount the main .git directory (parent of worktrees/)
147+
main_git_dir = (
148+
git_dir.parent.parent
149+
) # /path/to/.git/worktrees/name -> /path/to/.git
150+
git_volume_mount = f"-v {main_git_dir}:{main_git_dir} "
151+
110152
# Dynamically find all ttyACM and ttyUSB devices
111153
tty_devices = []
112154
for pattern in ["/dev/ttyACM*", "/dev/ttyUSB*"]:
@@ -125,6 +167,7 @@ def docker_build_cmd(
125167
f"{'-it ' if docker_interactive else ''}"
126168
f"{device_flags}" # provides access to USB and serial devices for deploy
127169
f"-v {mpy_dir}:{mpy_dir} -w {mpy_dir} " # mount micropython dir with same path so elf/map paths match host
170+
f"{git_volume_mount}" # mount actual .git directory for worktrees
128171
f"--user {uid}:{gid} " # match running user id so generated files aren't owned by root
129172
f"-e HOME=/tmp " # set HOME to /tmp for container
130173
f"{build_container} "

0 commit comments

Comments
 (0)