From 09d3602cc53037e4e54c1cb79bc233f94bc734e3 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 9 Nov 2026 03:24:19 +0000 Subject: [PATCH] fs push: commit the import versions it takes from Onshape, even with nothing to push It wrote them into the local files but committed only alongside a push, so fs sync-main with nothing to push left fasteners.fs changed, and fs run-releases refused the dirty tree before making v1.1.1. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01T4daFKz4qvNwCEYcg38VKS --- fs_cli/cli.py | 17 +++++++++++++---- tests/fs_cli_test.py | 14 ++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/fs_cli/cli.py b/fs_cli/cli.py index e96bb943..5deacf2f 100644 --- a/fs_cli/cli.py +++ b/fs_cli/cli.py @@ -870,16 +870,25 @@ def commit_pushed( workspace: Workspace, pushed: list[Studio | Image], deleted: list[Studio | Image], updated: list[Studio] ) -> None: """Commits what `fs push` pushed and deleted, as it is in Onshape now (imports by path resolved to ids, and - import versions from Onshape), with fs-studios.json, so the repo matches Onshape. Nothing else is committed.""" - if not pushed and not deleted: + import versions from Onshape), and the import versions it took from Onshape for files it didn't push, with + fs-studios.json, so the repo matches Onshape. Nothing else is committed.""" + if not pushed and not deleted and not updated: return names = [pathlib.PurePosixPath(item.path).name for item in pushed] subject = ( f"Push {', '.join(names)} to Onshape" if 0 < len(names) <= 3 - else f"Push {_plural(len(names), 'file')} to Onshape" if names else "Delete tabs in Onshape" + else f"Push {_plural(len(names), 'file')} to Onshape" + if names + else "Delete tabs in Onshape" + if deleted + else "Take import versions from Onshape" + ) + lines = ( + [f"Pushed {item.path}" for item in pushed] + + [f"Deleted the tab of {item.path}" for item in deleted] + + [f"Took import versions in {item.path}" for item in updated if item not in pushed] ) - lines = [f"Pushed {item.path}" for item in pushed] + [f"Deleted the tab of {item.path}" for item in deleted] paths = [item.file for item in [*pushed, *deleted, *updated]] + [workspace.config.studios_path] # fs-studios.json as the push left it (`main` saves it again after) workspace.state.save() diff --git a/tests/fs_cli_test.py b/tests/fs_cli_test.py index 371f3141..d6aa358b 100644 --- a/tests/fs_cli_test.py +++ b/tests/fs_cli_test.py @@ -999,6 +999,20 @@ def test_pushing_a_tab_with_its_importer_keeps_the_version_onshape_gives_the_imp assert "import versions updated in Onshape" not in capsys.readouterr().out +def test_a_push_with_nothing_to_push_commits_the_import_versions_it_took(repo, onshape, capsys): + """So the tree is clean after it, as `fs run-releases` needs after `fs sync-main`.""" + git_repo(repo) + element_id = onshape.add("b.fs", importing(OLD)) + run(onshape, "pull") + commit_all(repo, "Pull") + onshape.edit(element_id, importing(NEW)) + + assert run(onshape, "push", "--force") == 0 + assert local(repo, "b.fs").read_text() == importing(NEW) + assert git_output(repo, "status", "--porcelain") == "" + assert git_output(repo, "log", "-1", "--format=%s") == "Take import versions from Onshape\n" + + def test_pushing_keeps_onshapes_import_versions(repo, onshape): element_id = onshape.add("b.fs", importing(OLD)) run(onshape, "pull")