# Gitaly note: JV: will probably be migrated indirectly by migrating the call sites. module Gitlab module Git class RevList include Gitlab::Git::Popen attr_reader :oldrev, :newrev, :path_to_repo def initialize(path_to_repo:, newrev:, oldrev: nil) @oldrev = oldrev @newrev = newrev @path_to_repo = path_to_repo end # This method returns an array of new commit references def new_refs execute([*base_args, newrev, '--not', '--all']) end # Finds newly added objects # Returns an array of shas # # Can skip objects which do not have a path using required_path: true # This skips commit objects and root trees, which might not be needed when # looking for blobs # # When given a block it will yield objects as a lazy enumerator so # the caller can limit work done instead of processing megabytes of data def new_objects(require_path: nil, not_in: nil, &lazy_block) args = [*base_args, newrev, *not_in_refs(not_in), '--objects'] get_objects(args, require_path: require_path, &lazy_block) end def all_objects(require_path: nil, &lazy_block) args = [*base_args, '--all', '--objects'] get_objects(args, require_path: require_path, &lazy_block) end # This methods returns an array of missed references # # Should become obsolete after https://gitlab.com/gitlab-org/gitaly/issues/348. def missed_ref execute([*base_args, '--max-count=1', oldrev, "^#{newrev}"]) end private def not_in_refs(references) return ['--not', '--all'] unless references return [] if references.empty? references.prepend('--not') end def execute(args) output, status = popen(args, nil, Gitlab::Git::Env.to_env_hash) unless status.zero? raise "Got a non-zero exit code while calling out `#{args.join(' ')}`: #{output}" end output.split("\n") end def lazy_execute(args, &lazy_block) popen(args, nil, Gitlab::Git::Env.to_env_hash, lazy_block: lazy_block) end def base_args [ Gitlab.config.git.bin_path, "--git-dir=#{path_to_repo}", 'rev-list' ] end def get_objects(args, require_path: nil) if block_given? lazy_execute(args) do |lazy_output| objects = objects_from_output(lazy_output, require_path: require_path) yield(objects) end else object_output = execute(args) objects_from_output(object_output, require_path: require_path) end end def objects_from_output(object_output, require_path: nil) object_output.map do |output_line| sha, path = output_line.split(' ', 2) next if require_path && path.blank? sha end.reject(&:nil?) end end end end