Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 39 additions & 13 deletions src/utilities/utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,31 @@ const julia_remote = Remotes.GitHub("JuliaLang", "julia")
"""
Stores the memoized results of [`getremote`](@ref).
"""
const GIT_REMOTE_CACHE = Dict{String,Union{Remotes.Remote,Nothing}}()
const GIT_REMOTENAME_CACHE = Dict{String,Union{String,Nothing}}()
const GIT_REMOTEURL_CACHE = Dict{String,Union{Remotes.Remote,Nothing}}()

"""
$(TYPEDSIGNATURES)

Determines the GitHub remote of a directory by checking `remote.pushDefault` of the repository.
Defaults to `origin`.

The results for a given directory are memoized in [`GIT_REMOTENAME_CACHE`](@ref), since calling
`git` is expensive and it is often called on the same directory over and over again.
"""
function getremotename(dir::AbstractString)
isdir(dir) || return nothing
return get!(GIT_REMOTENAME_CACHE, dir) do
try
remotename = readchomp(setenv(`$(git()) config --get remote.pushDefault`; dir=dir))
@assert !isempty(remotename)
remotename
catch e
@warn "git config --get remote.pushDefault failed. Assuming remote `origin`." exception=(e, catch_backtrace())
"origin"
end
end
end

function parse_remote_url(remote::AbstractString)
# TODO: we only match for GitHub repositories automatically. Could we engineer a
Expand All @@ -435,24 +459,25 @@ end
"""
$(TYPEDSIGNATURES)

Determines the GitHub remote of a directory by checking `remote.origin.url` of the
repository. Returns a [`Remotes.GitHub`](@ref), or `nothing` is something has gone wrong
(e.g. it's run on a directory not in a Git repo, or `origin.url` points to a non-GitHub
remote).
Determines the GitHub remote of a directory by checking `remote.\$(remotename).url` of the
repository. `remotename` is determined by [`getremotename`](@ref). Returns a [`Remotes.GitHub`](@ref),
or `nothing` is something has gone wrong (e.g. it's run on a directory not in a Git repo, or the url
points to a non-GitHub remote).

The results for a given directory are memoized in [`GIT_REMOTE_CACHE`](@ref), since calling
The results for a given directory are memoized in [`GIT_REMOTEURL_CACHE`](@ref), since calling
`git` is expensive and it is often called on the same directory over and over again.
"""
function getremote(dir::AbstractString)
isdir(dir) || return nothing
return get!(GIT_REMOTE_CACHE, dir) do
remote = try
readchomp(setenv(`$(git()) config --get remote.origin.url`; dir=dir))
return get!(GIT_REMOTEURL_CACHE, dir) do
remotename = getremotename(dir)
remoteurl = try
readchomp(setenv(`$(git()) config --get remote.$(remotename).url`; dir=dir))
catch e
@debug "git config --get remote.origin.url failed" exception=(e, catch_backtrace())
@debug "git config --get remote.$(remotename).url failed" exception=(e, catch_backtrace())
""
end
return parse_remote_url(remote)
return parse_remote_url(remoteurl)
end
end

Expand Down Expand Up @@ -616,7 +641,7 @@ it out automatically.
`root` is the the directory where `git` gets run. `varname` is just informational and used
to construct the warning messages.
"""
function git_remote_head_branch(varname, root; remotename = "origin", fallback = "master")
function git_remote_head_branch(varname, root; fallback = "master")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docstring still references remotename. So either that needs to be adjusted. Alternatively, keep the kwarg here, but with a new default value nothing; and then later only call getremotename if remotename === nothing ?

gitcmd = git(nothrow = true)
if gitcmd === nothing
@warn """
Expand All @@ -628,8 +653,9 @@ function git_remote_head_branch(varname, root; remotename = "origin", fallback =
end
# We need to do addenv() here to merge the new variables with the environment set by
# Git_jll and the git() function.
remotename = getremotename(root)
cmd = addenv(
setenv(`$gitcmd remote show $(remotename)`, dir=root),
setenv(`$gitcmd remote show $remotename`, dir=root),
"GIT_TERMINAL_PROMPT" => "0",
"GIT_SSH_COMMAND" => get(ENV, "GIT_SSH_COMMAND", "ssh -o \"BatchMode yes\""),
)
Expand Down