-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Bring back support for Git :ref and :depth used together #13713
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This was discussed in https://github.com/elixir-lang/elixir/pull/13128/files#r1399042619. |
An optimization to fetch only the about-to-be-used refs introduced when the :depth option was added broke support for specifying a SHA1 prefix as :ref. Such possibility was neither documented nor tested, but certainly used in the wild. This use case is now explicitly supported with a new test case. We maintain this fetch optimization whenever :branch, :tag or :depth is specified. We fetch all refs when :ref is used without :depth to be able to resolve short SHA1 refs, and require full commit hashes to use :ref and :depth together. When using :ref with :depth, a full SHA1 is required by Git and surfaced in our docs. We enforce it when validating the options, leaving room for longer hashes. This commit brings back two tests to cover the :ref and :depth functionality, and adds a new one to cover the validation mentioned above.
4f51f5a
to
7ba18df
Compare
Ready for a second pass. |
|
||
["--git-dir=.git", "fetch", "--force", "--quiet"] | ||
|> Kernel.++(progress_switch(git_version())) | ||
|> Kernel.++(tags_switch(opts[:tag])) | ||
|> Kernel.++(depth_switch(opts[:depth])) | ||
|> Kernel.++(if branch_or_tag, do: ["origin", branch_or_tag], else: []) | ||
|> Kernel.++(refspec_switch(opts, rev)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would merge refspec_switch and depth_switch logic into a single function. There is too much dependency between these two and unifying it in a single place would probably be cleaner.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other than moving the call to depth_switch
into refspec_switch
, I'm not seeing a clean path forward here:
defp refspec_switch(_opts, nil), do: []
defp refspec_switch(opts, rev) do
depth_switch(opts[:depth]) ++
case Keyword.take(opts, [:depth, :branch, :tag]) do
[_ | _] -> ["origin", rev]
_ -> []
end
end
defp depth_switch(nil), do: []
defp depth_switch(n) when is_integer(n) and n > 0 do
check_depth_support(git_version())
["--depth=#{n}"]
end
We only want to call check_depth_support
with a valid :depth
, and the other logic is about when to include the repository + refspec (e.g. origin main). Do you see a better way to organize this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking this:
defp fetch_args(opts, nil), do: []
defp fetch_args(opts, rev) do
cond do
depth = opts[:depth] ->
check_depth_support(git_version())
["--depth=#{n}", "origin", rev]
# We can only fetch full refs, which :ref may not be one of
opts[:ref] == rev ->
[]
true ->
["origin", rev]
end
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm this misses the case of depth with no rev (tip of default branch, when neither of :ref, :branch, or :tag are specified)?
(I think a test case would go red)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn’t that rev equals to nil, handled in the first clause?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, my code above also falls into the same mistake. The current commit handles that case with the two independent functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So which arguments would reproduce the failure?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ran the tests locally for code in #13713 (comment) and #13713 (comment) (with a small fix, s/{n}/{depth}/
).
Both fail 5 tests (5 out of 10 in the describe "Git depth option"
): all the tests where the mix spec doesn't include one of :ref, :branch, :tag
(in the test file they are the first and the last four tests in the describe block).
The failure is the same, the produced repos are not shallow:
Expected truthy, got false
code: assert File.exists?(repo_path <> "/.git/shallow")
That confirms what I said in #13713 (comment) last night (I was on mobile and "ran the tests" on my head).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I got it. We need to run depth even if there is no rev. :)
💚 💙 💜 💛 ❤️ |
An optimization to fetch only the about-to-be-used refs introduced when the :depth option was added broke support for specifying a SHA1 prefix as :ref. Such possibility was neither documented nor tested, but certainly used in the wild. This use case is now explicitly supported with a new test case.
We maintain this fetch optimization whenever :branch, :tag or :depth is specified. We fetch all refs when :ref is used without :depth to be able to resolve short SHA1 refs, and require full commit hashes to use :ref and :depth together.
When using :ref with :depth, a full SHA1 is required by Git and surfaced in our docs. We enforce it when validating the options, leaving room for longer hashes.
This commit brings back two tests to cover the :ref and :depth functionality, and adds a new one to cover the validation mentioned above.
Related forum thread: https://elixirforum.com/t/elixir-v1-17-2-released/64794