{"record":{"id":"d0ffc1382f2b8628","repo":"github-linguist/linguist","slug":"current-tree-is-deprecated","errorCode":null,"errorMessage":"current_tree is deprecated","messagePattern":"current_tree is deprecated","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"warning","filePath":"lib/linguist/repository.rb","lineNumber":137,"sourceCode":"    #\n    # Returns a map of filename => [language, size]\n    def cache\n      @cache ||= begin\n        if @old_commit_oid == @commit_oid\n          @old_stats\n        else\n          compute_stats(@old_commit_oid, @old_stats)\n        end\n      end\n    end\n\n    def read_index\n      raise NotImplementedError, \"read_index is deprecated\" unless repository.is_a? Linguist::Source::RuggedRepository\n      repository.set_attribute_source(@commit_oid)\n    end\n\n    def current_tree\n      raise NotImplementedError, \"current_tree is deprecated\" unless repository.is_a? Linguist::Source::RuggedRepository\n      repository.get_tree(@commit_oid)\n    end\n\n    protected\n    def compute_stats(old_commit_oid, cache = nil)\n      return {} if repository.get_tree_size(@commit_oid, @max_tree_size) >= @max_tree_size\n\n      repository.set_attribute_source(@commit_oid)\n      diff = repository.diff(old_commit_oid, @commit_oid)\n\n      # Clear file map and fetch full diff if any .gitattributes files are changed\n      if cache && diff.each_delta.any? { |delta| File.basename(delta.new_file[:path]) == \".gitattributes\" }\n        diff = repository.diff(nil, @commit_oid)\n        file_map = {}\n      else\n        file_map = cache ? cache.dup : {}\n      end\n","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/github-linguist/linguist/blob/b45dbe9b2825a43285bcd035861be91cc0a7299e/lib/linguist/repository.rb#L119-L155","documentation":"current_tree is the second legacy Rugged-specific helper on Linguist::Repository: it returns the commit's tree via repository.get_tree, but raises NotImplementedError ('current_tree is deprecated') whenever the injected source is not a Linguist::Source::RuggedRepository. As with read_index, the constructor only wraps raw Rugged repos; an injected custom Source::Repository leaves this path unavailable. The tree is an internal detail of stats computation — callers should use #language_stats/#cache rather than walking the tree themselves.","triggerScenarios":"1) Calling `repo.current_tree` on a Repository built around a custom Linguist::Source::Repository implementation. 2) Code ported from older linguist versions that used current_tree to enumerate blobs for analysis. 3) Specs with fake/stub sources (not RuggedRepository instances) exercising old helper calls.","commonSituations":"Version upgrades from pre-source-abstraction linguist to 5.x+ where internal helpers now guard on the source type; hosting applications injecting their own source adapter; scripts that enumerated `current_tree` blobs directly instead of using the stats API.","solutions":["Use the public API: `repo.language_stats` returns the language breakdown without needing the tree.","If you must enumerate entries, add an equivalent accessor to your custom source class and call it on `repo.repository` directly.","Gate legacy usage: `tree = repo.current_tree if repo.repository.is_a?(Linguist::Source::RuggedRepository)`.","Delete references to current_tree when upgrading — it is explicitly marked deprecated and will not be extended to other sources."],"exampleFix":"# before\nlinguist_repo.current_tree.each_blob { |b| analyze(b) }\n\n# after\nstats = linguist_repo.language_stats # { \"Ruby\" => 1234, ... }","handlingStrategy":"type-guard","validationCode":"def tree_via_source(linguist_repo)\n  src = linguist_repo.repository\n  return src.get_tree(linguist_repo.instance_variable_get(:@commit_oid)) if src.is_a?(Linguist::Source::RuggedRepository)\n  src.respond_to?(:get_tree) ? src.get_tree : nil\nend","typeGuard":"def rugged_backed?(linguist_repo)\n  linguist_repo.repository.is_a?(Linguist::Source::RuggedRepository)\nend","tryCatchPattern":"begin\n  tree = linguist_repo.current_tree\nrescue NotImplementedError => e\n  raise unless e.message =~ /current_tree is deprecated/\n  tree = nil # fall back to language_stats for whatever you needed the tree for\nend","preventionTips":["Use repo.language_stats instead of walking current_tree yourself.","If you need tree access on a custom source, expose it on your source class rather than via the deprecated helper.","Search your codebase for `current_tree` when upgrading linguist 5.x+ — these calls now guard on the source type."],"tags":["ruby","linguist","deprecation","not-implemented","upgrade"],"backgroundTag":"deprecated-api-called","analyzedSha":"b45dbe9b2825a43285bcd035861be91cc0a7299e","analyzedAt":"2026-08-21T15:30:05.145Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}