@@ -443,6 +443,27 @@ def test_install_ref_rejected_for_registered_repo(self, registry, devbase_root):
443443 with pytest .raises (PluginError , match = "Cannot use @v2.0" ):
444444 install_plugin (registry , "testorg/testrepo:myplugin@v2.0" )
445445
446+ def test_install_ref_rejected_for_name_only (self , registry , devbase_root ):
447+ """@ref on a name-only install is rejected too.
448+
449+ Without the guard, `devbase plugin install myplugin@v1` would parse
450+ to (repo='', plugin_name='myplugin', ref='v1'), enter the
451+ find_plugin_in_repos branch and silently drop the ref in
452+ _install_from_repo(), installing the default branch instead.
453+ """
454+ url = "https://github.com/testorg/testrepo.git"
455+ _make_repo_dir (devbase_root , "testorg/testrepo" , [
456+ {"name" : "myplugin" , "path" : "myplugin" , "projects" : ["myproj" ]},
457+ ])
458+ _register_repo (registry , "testorg/testrepo" , url , [
459+ {"name" : "myplugin" , "path" : "myplugin" },
460+ ])
461+
462+ with pytest .raises (PluginError , match = "Cannot use @v1" ):
463+ install_plugin (registry , "myplugin@v1" )
464+ # registry must not have installed the plugin from the default branch
465+ assert registry .get ("myplugin" ) is None
466+
446467 def test_install_legacy_repo_without_local_path (self , registry , devbase_root ):
447468 """Legacy repos (no local_path) are auto-migrated to persistent clone."""
448469 url = "https://github.com/testorg/testrepo.git"
0 commit comments