diff --git a/lib/ruby_lsp/tapioca/addon.rb b/lib/ruby_lsp/tapioca/addon.rb index e227ce75d..1ee563d62 100644 --- a/lib/ruby_lsp/tapioca/addon.rb +++ b/lib/ruby_lsp/tapioca/addon.rb @@ -28,6 +28,7 @@ def initialize @file_checksums = {} #: Hash[String, String] @lockfile_diff = nil #: String? @outgoing_queue = nil #: Thread::Queue? + @last_known_git_head = read_git_head #: String? end # @override @@ -126,6 +127,19 @@ def workspace_did_change_watched_files(changes) @rails_runner_client.trigger_reload + # If git HEAD changed, this is a branch switch (or rebase/pull). Skip DSL generation + # since the server state may be stale. Only reload was needed. + if git_head_changed? + queue = @outgoing_queue + if queue + queue << Notification.window_log_message( + "Tapioca add-on: detected branch switch, skipping DSL generation", + type: Constant::MessageType::INFO, + ) + end + return + end + if needs_compiler_reload @rails_runner_client.delegate_notification( server_addon_name: "Tapioca", @@ -175,6 +189,24 @@ def send_usage_telemetry(feature_name) }) end + #: -> bool + def git_head_changed? + current_head = read_git_head + changed = @last_known_git_head && current_head && @last_known_git_head != current_head + @last_known_git_head = current_head + !!changed + end + + #: -> String? + def read_git_head + git_head_path = File.join(Dir.pwd, ".git", "HEAD") + return unless File.exist?(git_head_path) + + File.read(git_head_path).strip + rescue SystemCallError + nil + end + #: (Hash[Symbol, untyped] change, String path) -> bool def file_updated?(change, path) queue = @outgoing_queue #: as !nil