Skip to content

Commit

Permalink
Fix regression when fetching repo with a ref
Browse files Browse the repository at this point in the history
Also note that depth and ref cannot be used in combination.
  • Loading branch information
josevalim committed Jul 2, 2024
1 parent 2d1f280 commit 786f959
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 53 deletions.
32 changes: 17 additions & 15 deletions lib/mix/lib/mix/scm/git.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion lib/mix/lib/mix/tasks/deps.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
37 changes: 0 additions & 37 deletions lib/mix/test/mix/tasks/deps.git_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 786f959

Please sign in to comment.