Support git partial clones with sparse checkouts
This commit is contained in:
		
							parent
							
								
									2bec760529
								
							
						
					
					
						commit
						7df90eb7e1
					
				@ -15,7 +15,7 @@ class URL < Delegator
 | 
			
		||||
                :verified, :using,
 | 
			
		||||
                :tag, :branch, :revisions, :revision,
 | 
			
		||||
                :trust_cert, :cookies, :referer, :header, :user_agent,
 | 
			
		||||
                :data
 | 
			
		||||
                :data, :only_paths
 | 
			
		||||
 | 
			
		||||
    extend Forwardable
 | 
			
		||||
    def_delegators :uri, :path, :scheme, :to_s
 | 
			
		||||
@ -36,6 +36,7 @@ class URL < Delegator
 | 
			
		||||
        header:     T.nilable(String),
 | 
			
		||||
        user_agent: T.nilable(T.any(Symbol, String)),
 | 
			
		||||
        data:       T.nilable(T::Hash[String, String]),
 | 
			
		||||
        only_paths: T.nilable(T::Array[String]),
 | 
			
		||||
      ).void
 | 
			
		||||
    }
 | 
			
		||||
    def initialize(
 | 
			
		||||
@ -51,7 +52,8 @@ class URL < Delegator
 | 
			
		||||
      referer: nil,
 | 
			
		||||
      header: nil,
 | 
			
		||||
      user_agent: nil,
 | 
			
		||||
      data: nil
 | 
			
		||||
      data: nil,
 | 
			
		||||
      only_paths: nil
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
      @uri = URI(uri)
 | 
			
		||||
@ -69,6 +71,7 @@ class URL < Delegator
 | 
			
		||||
      specs[:header]     = @header     = header
 | 
			
		||||
      specs[:user_agent] = @user_agent = user_agent || :default
 | 
			
		||||
      specs[:data]       = @data       = data
 | 
			
		||||
      specs[:only_paths] = @only_paths = only_paths
 | 
			
		||||
 | 
			
		||||
      @specs = specs.compact
 | 
			
		||||
    end
 | 
			
		||||
@ -156,6 +159,7 @@ class URL < Delegator
 | 
			
		||||
      header:          T.nilable(String),
 | 
			
		||||
      user_agent:      T.nilable(T.any(Symbol, String)),
 | 
			
		||||
      data:            T.nilable(T::Hash[String, String]),
 | 
			
		||||
      only_paths:      T.nilable(T::Array[String]),
 | 
			
		||||
      caller_location: Thread::Backtrace::Location,
 | 
			
		||||
      dsl:             T.nilable(Cask::DSL),
 | 
			
		||||
      block:           T.nilable(T.proc.params(arg0: T.all(String, BlockDSL::PageWithURL)).returns(T.untyped)),
 | 
			
		||||
@ -175,6 +179,7 @@ class URL < Delegator
 | 
			
		||||
    header: nil,
 | 
			
		||||
    user_agent: nil,
 | 
			
		||||
    data: nil,
 | 
			
		||||
    only_paths: nil,
 | 
			
		||||
    caller_location: T.must(caller_locations).fetch(0),
 | 
			
		||||
    dsl: nil,
 | 
			
		||||
    &block
 | 
			
		||||
@ -202,6 +207,7 @@ class URL < Delegator
 | 
			
		||||
        header:     header,
 | 
			
		||||
        user_agent: user_agent,
 | 
			
		||||
        data:       data,
 | 
			
		||||
        only_paths: only_paths,
 | 
			
		||||
      )
 | 
			
		||||
    end
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
@ -814,6 +814,7 @@ class GitDownloadStrategy < VCSDownloadStrategy
 | 
			
		||||
    super
 | 
			
		||||
    @ref_type ||= :branch
 | 
			
		||||
    @ref ||= "master"
 | 
			
		||||
    @only_paths = meta[:only_paths]
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # @see AbstractDownloadStrategy#source_modified_time
 | 
			
		||||
@ -880,6 +881,14 @@ class GitDownloadStrategy < VCSDownloadStrategy
 | 
			
		||||
    (cached_location/".gitmodules").exist?
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def partial_clone_sparse_checkout?
 | 
			
		||||
    return false if @only_paths.nil?
 | 
			
		||||
 | 
			
		||||
    # There is some support for partial clones prior to 2.20, but we avoid using it
 | 
			
		||||
    # due to performance issues
 | 
			
		||||
    Version.create(Utils::Git.version) >= Version.create("2.20.0")
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  sig { returns(T::Array[String]) }
 | 
			
		||||
  def clone_args
 | 
			
		||||
    args = %w[clone]
 | 
			
		||||
@ -889,6 +898,8 @@ class GitDownloadStrategy < VCSDownloadStrategy
 | 
			
		||||
      args << "--branch" << @ref
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    args << "--no-checkout" << "--filter=blob:none" if partial_clone_sparse_checkout?
 | 
			
		||||
 | 
			
		||||
    args << "-c" << "advice.detachedHead=false" # silences detached head warning
 | 
			
		||||
    args << @url << cached_location
 | 
			
		||||
  end
 | 
			
		||||
@ -922,6 +933,13 @@ class GitDownloadStrategy < VCSDownloadStrategy
 | 
			
		||||
    command! "git",
 | 
			
		||||
             args:  ["config", "advice.detachedHead", "false"],
 | 
			
		||||
             chdir: cached_location
 | 
			
		||||
 | 
			
		||||
    if partial_clone_sparse_checkout?
 | 
			
		||||
      command! "git",
 | 
			
		||||
               args:  ["config", "origin.partialclonefilter", "blob:none"],
 | 
			
		||||
               chdir: cached_location
 | 
			
		||||
      configure_sparse_checkout
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  sig { params(timeout: T.nilable(Time)).void }
 | 
			
		||||
@ -950,6 +968,9 @@ class GitDownloadStrategy < VCSDownloadStrategy
 | 
			
		||||
             args:    ["config", "homebrew.cacheversion", cache_version],
 | 
			
		||||
             chdir:   cached_location,
 | 
			
		||||
             timeout: timeout&.remaining
 | 
			
		||||
 | 
			
		||||
    configure_sparse_checkout if partial_clone_sparse_checkout?
 | 
			
		||||
 | 
			
		||||
    checkout(timeout: timeout)
 | 
			
		||||
    update_submodules(timeout: timeout) if submodules?
 | 
			
		||||
  end
 | 
			
		||||
@ -1020,6 +1041,15 @@ class GitDownloadStrategy < VCSDownloadStrategy
 | 
			
		||||
      dot_git.atomic_write("gitdir: #{relative_git_dir}\n")
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def configure_sparse_checkout
 | 
			
		||||
    command! "git",
 | 
			
		||||
             args:  ["config", "core.sparseCheckout", "true"],
 | 
			
		||||
             chdir: cached_location
 | 
			
		||||
 | 
			
		||||
    sparse_checkout_paths = @only_paths.join("\n") + "\n"
 | 
			
		||||
    (git_dir/"info"/"sparse-checkout").atomic_write(sparse_checkout_paths)
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
# Strategy for downloading a Git repository from GitHub.
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user