diff --git a/lib/mix/lib/mix/scm/git.ex b/lib/mix/lib/mix/scm/git.ex index ea8f1d7eebe..edc96c7ad3b 100644 --- a/lib/mix/lib/mix/scm/git.ex +++ b/lib/mix/lib/mix/scm/git.ex @@ -9,7 +9,7 @@ defmodule Mix.SCM.Git do @impl true def format(opts) do - if rev = get_opts_rev(opts) do + if rev = opts[:ref] || opts[:branch] || opts[:tag] do "#{redact_uri(opts[:git])} - #{rev}" else redact_uri(opts[:git]) @@ -22,7 +22,7 @@ defmodule Mix.SCM.Git do {:git, _, lock_rev, lock_opts} -> lock = String.slice(lock_rev, 0, 7) - case Enum.find_value([:branch, :ref, :tag], &List.keyfind(lock_opts, &1, 0)) do + case Enum.find_value([:ref, :branch, :tag], &List.keyfind(lock_opts, &1, 0)) do {:ref, _} -> lock <> " (ref)" {key, val} -> lock <> " (#{key}: #{val})" nil -> lock @@ -125,18 +125,18 @@ defmodule Mix.SCM.Git do sparse_toggle(opts) update_origin(opts[:git]) - rev = get_lock_rev(opts[:lock], opts) || get_opts_rev(opts) - # Fetch external data + branch_or_tag = opts[:branch] || opts[:tag] + ["--git-dir=.git", "fetch", "--force", "--quiet"] |> Kernel.++(progress_switch(git_version())) |> Kernel.++(tags_switch(opts[:tag])) |> Kernel.++(depth_switch(opts[:depth])) - |> Kernel.++(if rev, do: ["origin", rev], else: []) + |> Kernel.++(if branch_or_tag, do: ["origin", branch_or_tag], else: []) |> git!() # Migrate the Git repo - rev = rev || default_branch() + rev = get_lock_rev(opts[:lock], opts) || opts[:ref] || branch_or_tag || default_branch() git!(["--git-dir=.git", "checkout", "--quiet", rev]) if opts[:submodules] do @@ -250,18 +250,24 @@ defmodule Mix.SCM.Git do end defp validate_depth(opts) do - case Keyword.take(opts, [:depth]) do - [] -> - opts + case Keyword.take(opts, [:depth, :ref]) do + [_, _] -> + Mix.raise( + "Cannot specify :depth and :ref at the same time. " <> + "Error on Git dependency: #{redact_uri(opts[:git])}" + ) - [{:depth, depth}] when is_integer(depth) and depth > 0 -> + [depth: depth] when is_integer(depth) and depth > 0 -> opts - invalid_depth -> + [depth: invalid_depth] -> Mix.raise( "The depth must be a positive integer, and be specified only once, got: #{inspect(invalid_depth)}. " <> "Error on Git dependency: #{redact_uri(opts[:git])}" ) + + _ -> + opts end end @@ -290,10 +296,6 @@ defmodule Mix.SCM.Git do end end - defp get_opts_rev(opts) do - opts[:branch] || opts[:ref] || opts[:tag] - end - defp redact_uri(git) do case URI.parse(git) do %{userinfo: nil} -> git diff --git a/lib/mix/lib/mix/tasks/deps.ex b/lib/mix/lib/mix/tasks/deps.ex index d972123fdec..c3a5f7faad2 100644 --- a/lib/mix/lib/mix/tasks/deps.ex +++ b/lib/mix/lib/mix/tasks/deps.ex @@ -125,7 +125,8 @@ defmodule Mix.Tasks.Deps do * `:depth` *(since v1.17.0)* - creates a shallow clone of the Git repository, limiting the history to the specified number of commits. This can significantly improve clone speed for large repositories when full history is not needed. - The value must be a positive integer, typically `1`. + The value must be a positive integer, typically `1`. Cannot be used with the + `:ref` option. If your Git repository requires authentication, such as basic username:password HTTP authentication via URLs, it can be achieved via Git configuration, keeping diff --git a/lib/mix/test/mix/tasks/deps.git_test.exs b/lib/mix/test/mix/tasks/deps.git_test.exs index 8ebca0d4744..cdaf7b337ca 100644 --- a/lib/mix/test/mix/tasks/deps.git_test.exs +++ b/lib/mix/test/mix/tasks/deps.git_test.exs @@ -530,43 +530,6 @@ defmodule Mix.Tasks.DepsGitTest do end) end - test "with ref" do - [last, _ | _] = get_git_repo_revs("git_repo") - - Process.put(:git_repo_opts, depth: 1, ref: last) - - in_fixture("no_mixfile", fn -> - Mix.Project.push(GitApp) - - Mix.Tasks.Deps.Get.run([]) - message = "* Getting git_repo (#{fixture_path("git_repo")} - #{last})" - assert_received {:mix_shell, :info, [^message]} - assert_shallow("deps/git_repo", 1) - end) - end - - test "changing refspec updates retaining depth" do - [last, first | _] = get_git_repo_revs("git_repo") - - Process.put(:git_repo_opts, ref: first, depth: 1) - - in_fixture("no_mixfile", fn -> - Mix.Project.push(GitApp) - - Mix.Tasks.Deps.Get.run([]) - message = "* Getting git_repo (#{fixture_path("git_repo")} - #{first})" - assert_received {:mix_shell, :info, [^message]} - assert_shallow("deps/git_repo", 1) - assert File.read!("mix.lock") =~ first - - # Change refspec - update_dep(ref: last, depth: 1) - Mix.Tasks.Deps.Get.run([]) - assert_shallow("deps/git_repo", 1) - assert File.read!("mix.lock") =~ last - end) - end - test "removing depth retains shallow repository" do # For compatibility and simplicity, we follow Git's behavior and do not # attempt to unshallow an existing repository. This should not be a