Skip to content

Commit bb9721f

Browse files
jeffreylojosevalim
andauthored
More robust git version parsing (#15019)
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. * Update lib/mix/test/mix/tasks/deps.git_test.exs --------- Co-authored-by: José Valim <jose.valim@gmail.com>
1 parent 68207c0 commit bb9721f

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

lib/mix/lib/mix/scm/git.ex

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,13 +420,21 @@ defmodule Mix.SCM.Git do
420420
version =
421421
["--version"]
422422
|> git!("")
423-
|> parse_version()
423+
|> parse_version_output()
424424

425425
Mix.State.put(:git_version, version)
426426
version
427427
end
428428
end
429429

430+
defp parse_version_output(output) do
431+
output
432+
|> String.trim()
433+
|> String.split("\n")
434+
|> List.last()
435+
|> parse_version()
436+
end
437+
430438
defp parse_version("git version " <> version) do
431439
version
432440
|> String.split(".")
@@ -435,6 +443,10 @@ defmodule Mix.SCM.Git do
435443
|> List.to_tuple()
436444
end
437445

446+
defp parse_version(other) do
447+
Mix.raise("Unable to parse Git version from: #{inspect(other)}")
448+
end
449+
438450
defp format_version(version) do
439451
version |> Tuple.to_list() |> Enum.join(".")
440452
end

lib/mix/test/mix/tasks/deps.git_test.exs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,27 @@ defmodule Mix.Tasks.DepsGitTest do
7272
end)
7373
end
7474

75+
test "gets Git repos with git trace enabled" do
76+
on_exit(fn ->
77+
System.delete_env("GIT_TRACE")
78+
:ets.delete(Mix.State, :git_version)
79+
end)
80+
81+
System.put_env("GIT_TRACE", "1")
82+
:ets.delete(Mix.State, :git_version)
83+
84+
in_fixture("no_mixfile", fn ->
85+
Mix.Project.push(GitApp)
86+
87+
Mix.Tasks.Deps.Get.run([])
88+
message = "* Getting git_repo (#{fixture_path("git_repo")})"
89+
assert_received {:mix_shell, :info, [^message]}
90+
91+
assert File.read!("mix.lock") =~
92+
~r/"git_repo": {:git, #{inspect(fixture_path("git_repo"))}, "[a-f0-9]+", \[\]}/
93+
end)
94+
end
95+
7596
test "gets and updates Git repos with submodules" do
7697
in_fixture("no_mixfile", fn ->
7798
Mix.Project.push(GitSubmodulesApp)

0 commit comments

Comments
 (0)