From e06943b8646889cf6893d4a2bcc15cbee40a2380 Mon Sep 17 00:00:00 2001 From: Jeffrey Lo Date: Tue, 16 Dec 2025 22:15:57 -0500 Subject: [PATCH 1/2] fix(mix/scm): handle GIT_TRACE=1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When GIT_TRACE=1 is set in the env, `mix deps.get` fails with an unexpected `FunctionClauseError` due to `git --version`'s output including trace output from git itself: ``` λ GIT_TRACE=1 mix deps.get * Getting ariel (git@github.com:foo/bar.git - main) 22:17:06.786357 git.c:476 trace: built-in: git init --quiet 22:17:06.798692 git.c:476 trace: built-in: git remote add origin git@github.com:foo/bar.git 22:17:06.804333 git.c:476 trace: built-in: git config remote.origin.url git@github.com:foo/bar.git ** (FunctionClauseError) no function clause matching in Mix.SCM.Git.parse_version/1 The following arguments were given to Mix.SCM.Git.parse_version/1: # 1 "22:17:06.809548 git.c:476 trace: built-in: git version\ngit version 2.50.1\n" Attempted function clauses (showing 1 out of 1): defp parse_version(<<"git version ", version::binary>>) (mix 1.18.4) lib/mix/scm/git.ex:426: Mix.SCM.Git.parse_version/1 (mix 1.18.4) lib/mix/scm/git.ex:419: Mix.SCM.Git.git_version/0 (mix 1.18.4) lib/mix/scm/git.ex:132: Mix.SCM.Git.checkout/2 (elixir 1.18.4) lib/file.ex:1665: File.cd!/2 (mix 1.18.4) lib/mix/dep/fetcher.ex:68: Mix.Dep.Fetcher.do_fetch/3 (mix 1.18.4) lib/mix/dep/converger.ex:238: Mix.Dep.Converger.all/9 (mix 1.18.4) lib/mix/dep/converger.ex:170: Mix.Dep.Converger.init_all/8 (mix 1.18.4) lib/mix/dep/converger.ex:110: Mix.Dep.Converger.all/4 ``` This patch updates `git_version` to handle trace noise by running parse on the final output line of `git --version`. New `deps.git_test` added to exercise the `GIT_TRACE` condition. --- lib/mix/lib/mix/scm/git.ex | 14 +++++++++- lib/mix/test/mix/tasks/deps.git_test.exs | 33 ++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/mix/lib/mix/scm/git.ex b/lib/mix/lib/mix/scm/git.ex index cb2c29f5c35..2cb1e262beb 100644 --- a/lib/mix/lib/mix/scm/git.ex +++ b/lib/mix/lib/mix/scm/git.ex @@ -420,13 +420,21 @@ defmodule Mix.SCM.Git do version = ["--version"] |> git!("") - |> parse_version() + |> parse_version_output() Mix.State.put(:git_version, version) version end end + defp parse_version_output(output) do + output + |> String.trim() + |> String.split("\n") + |> List.last() + |> parse_version() + end + defp parse_version("git version " <> version) do version |> String.split(".") @@ -435,6 +443,10 @@ defmodule Mix.SCM.Git do |> List.to_tuple() end + defp parse_version(other) do + Mix.raise("Unable to parse Git version from: #{inspect(other)}") + end + defp format_version(version) do version |> Tuple.to_list() |> Enum.join(".") end diff --git a/lib/mix/test/mix/tasks/deps.git_test.exs b/lib/mix/test/mix/tasks/deps.git_test.exs index 58e52f196e9..2e8fbc46779 100644 --- a/lib/mix/test/mix/tasks/deps.git_test.exs +++ b/lib/mix/test/mix/tasks/deps.git_test.exs @@ -72,6 +72,39 @@ defmodule Mix.Tasks.DepsGitTest do end) end + test "gets Git repos with git trace enabled" do + previous_trace = System.get_env("GIT_TRACE") + git_version_cache = :ets.lookup(Mix.State, :git_version) + + on_exit(fn -> + case previous_trace do + nil -> System.delete_env("GIT_TRACE") + value -> System.put_env("GIT_TRACE", value) + end + + :ets.delete(Mix.State, :git_version) + + case git_version_cache do + [] -> :ok + [{:git_version, value}] -> :ets.insert(Mix.State, {:git_version, value}) + end + end) + + System.put_env("GIT_TRACE", "1") + :ets.delete(Mix.State, :git_version) + + in_fixture("no_mixfile", fn -> + Mix.Project.push(GitApp) + + Mix.Tasks.Deps.Get.run([]) + message = "* Getting git_repo (#{fixture_path("git_repo")})" + assert_received {:mix_shell, :info, [^message]} + + assert File.read!("mix.lock") =~ + ~r/"git_repo": {:git, #{inspect(fixture_path("git_repo"))}, "[a-f0-9]+", \[\]}/ + end) + end + test "gets and updates Git repos with submodules" do in_fixture("no_mixfile", fn -> Mix.Project.push(GitSubmodulesApp) From b2cef68b651c2aa56f8fa1e95051a949e3fa2ebc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 17 Dec 2025 08:41:48 +0100 Subject: [PATCH 2/2] Update lib/mix/test/mix/tasks/deps.git_test.exs --- lib/mix/test/mix/tasks/deps.git_test.exs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/lib/mix/test/mix/tasks/deps.git_test.exs b/lib/mix/test/mix/tasks/deps.git_test.exs index 2e8fbc46779..985d0405bda 100644 --- a/lib/mix/test/mix/tasks/deps.git_test.exs +++ b/lib/mix/test/mix/tasks/deps.git_test.exs @@ -73,21 +73,9 @@ defmodule Mix.Tasks.DepsGitTest do end test "gets Git repos with git trace enabled" do - previous_trace = System.get_env("GIT_TRACE") - git_version_cache = :ets.lookup(Mix.State, :git_version) - on_exit(fn -> - case previous_trace do - nil -> System.delete_env("GIT_TRACE") - value -> System.put_env("GIT_TRACE", value) - end - + System.delete_env("GIT_TRACE") :ets.delete(Mix.State, :git_version) - - case git_version_cache do - [] -> :ok - [{:git_version, value}] -> :ets.insert(Mix.State, {:git_version, value}) - end end) System.put_env("GIT_TRACE", "1")