fix(projects): use _branch_lane_id for non-git folders to prevent duplicate lanes (#53329)
_place_by_heuristic used the raw path as the lane key for non-git project folders, while the desktop overlay independently computed ::branch::main for the same session (since git_branch was null). The ID mismatch caused duplicate lanes — one from the backend with the folder name, one from the overlay labeled 'main'. Use _branch_lane_id(path, DEFAULT_BRANCH_LABEL) so the backend's lane key matches the overlay's expected ::branch::main scheme, eliminating the duplicate lane.
This commit is contained in:
@@ -561,3 +561,35 @@ def test_colliding_repo_basenames_disambiguate_labels():
|
||||
labels = sorted(p["label"] for p in tree["projects"])
|
||||
|
||||
assert labels == ["x/proj", "y/proj"]
|
||||
|
||||
|
||||
def test_non_git_folder_uses_branch_lane_id():
|
||||
"""#53329: _place_by_heuristic must use _branch_lane_id for non-git folders.
|
||||
|
||||
Before the fix, non-git folders got a lane key equal to the raw path,
|
||||
while the desktop overlay expected ::branch::main. This caused duplicate
|
||||
lanes (one from backend, one from overlay).
|
||||
"""
|
||||
result = pt._place_by_heuristic("/home/user/my-project")
|
||||
assert result is not None
|
||||
assert result["lane_key"] == pt._branch_lane_id(
|
||||
"/home/user/my-project", pt.DEFAULT_BRANCH_LABEL
|
||||
), (
|
||||
f"Expected lane_key to use _branch_lane_id scheme but got "
|
||||
f"{result['lane_key']!r}"
|
||||
)
|
||||
# The label should still be the folder basename
|
||||
assert result["lane_label"] == "my-project"
|
||||
# Must be marked as main lane
|
||||
assert result["is_main"] is True
|
||||
|
||||
|
||||
def test_non_git_folder_lane_matches_overlay_scheme():
|
||||
"""#53329: verify the lane key format matches what the overlay expects."""
|
||||
result = pt._place_by_heuristic("/data/work/folder-x")
|
||||
assert result is not None
|
||||
# Overlay expects: <path>::branch::main
|
||||
expected = "/data/work/folder-x::branch::main"
|
||||
assert result["lane_key"] == expected, (
|
||||
f"Expected lane_key={expected!r} but got {result['lane_key']!r}"
|
||||
)
|
||||
|
||||
@@ -221,7 +221,7 @@ def _place_by_heuristic(path: str) -> Optional[dict]:
|
||||
repo_path = _with_base_name(path, m.group(1))
|
||||
return _placement(repo_path, path, m.group(2), path, False, False)
|
||||
|
||||
return _placement(path, path, base, path, True, False)
|
||||
return _placement(path, _branch_lane_id(path, DEFAULT_BRANCH_LABEL), base, path, True, False)
|
||||
|
||||
|
||||
def _place(cwd: str, branch: str, resolve: Optional[Resolve], persisted_root: str) -> Optional[dict]:
|
||||
|
||||
Reference in New Issue
Block a user