Skip to content

Commit 78b8142

Browse files
committed
fixes for cloning and fetching
1 parent a6252b1 commit 78b8142

File tree

4 files changed

+82
-48
lines changed

4 files changed

+82
-48
lines changed

src/API.jl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import Dates
77
import LibGit2
88

99
import ..depots, ..logdir, ..devdir, ..print_first_command_header
10-
import ..Operations, ..Display
10+
import ..Operations, ..Display, ..GitTools
1111
using ..Types, ..TOML
1212

1313

@@ -75,7 +75,6 @@ function up(ctx::Context, pkgs::Vector{PackageSpec};
7575
for reg in registries()
7676
if isdir(joinpath(reg, ".git"))
7777
regpath = pathrepr(reg)
78-
printpkgstyle(ctx, :Updating, "registry at ", regpath)
7978
LibGit2.with(LibGit2.GitRepo, reg) do repo
8079
if LibGit2.isdirty(repo)
8180
push!(errors, (regpath, "registry dirty"))
@@ -86,7 +85,7 @@ function up(ctx::Context, pkgs::Vector{PackageSpec};
8685
return
8786
end
8887
branch = LibGit2.headname(repo)
89-
LibGit2.fetch(repo)
88+
GitTools.fetch(repo)
9089
ff_succeeded = try
9190
LibGit2.merge!(repo; branch="refs/remotes/origin/$branch", fastforward=true)
9291
catch e

src/GitTools.jl

Lines changed: 63 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module GitTools
22

3+
using ..Pkg3
34
import LibGit2
45
using Printf
56

@@ -16,6 +17,8 @@ end
1617
function showprogress(io::IO, p::MiniProgressBar)
1718
perc = p.current / p.max * 100
1819
prev_perc = p.prev / p.max * 100
20+
# Bail early if we are not updating the progress bar,
21+
# Saves printing to the terminal
1922
if p.has_shown && !(perc - prev_perc > 0.1)
2023
return
2124
end
@@ -32,43 +35,45 @@ function showprogress(io::IO, p::MiniProgressBar)
3235
print(io, "\r")
3336
end
3437

35-
function transfer_progress(progress::Ptr{LibGit2.GitTransferProgress}, p::Any)
38+
Base.@kwdef struct GitTransferProgress
39+
total_objects::Cuint
40+
indexed_objects::Cuint
41+
received_objects::Cuint
42+
local_objects::Cuint
43+
total_deltas::Cuint
44+
indexed_deltas::Cuint
45+
received_bytes::Csize_t
46+
end
47+
48+
function transfer_progress(progress::Ptr{GitTransferProgress}, p::Any)
3649
progress = unsafe_load(progress)
50+
bar = unsafe_pointer_to_objref(p.transfer_progress)
51+
@assert typeof(bar) == MiniProgressBar
3752
if progress.total_deltas != 0
38-
p.header = "Resolving Deltas:"
39-
p.max = progress.total_deltas
40-
p.current = progress.indexed_deltas
53+
bar.header = "Resolving Deltas:"
54+
bar.max = progress.total_deltas
55+
bar.current = progress.indexed_deltas
4156
else
42-
p.max = progress.total_objects
43-
p.current = progress.received_objects
57+
bar.max = progress.total_objects
58+
bar.current = progress.received_objects
4459
end
45-
showprogress(stdout, p)
60+
showprogress(stdout, bar)
4661
return Cint(0)
4762
end
4863

4964
function clone(url, source_path; isbare::Bool=false, header = nothing, branch = nothing, credentials = nothing)
50-
isdir(source_path) && error("$source_path already exists")
51-
printstyled(stdout, "Cloning "; color = :green, bold=true)
52-
if header == nothing
53-
println(stdout, "from git repo: ", url, ".")
54-
else
55-
println(stdout, header)
56-
end
65+
Pkg3.Types.printpkgstyle(stdout, :Cloning, header == nothing ? string("git-repo `", url, "`") : header)
5766
transfer_payload = MiniProgressBar(header = "Fetching:", color = Base.info_color())
5867
cred_payload = LibGit2.CredentialPayload(credentials)
59-
print(stdout, "\e[?25l")
68+
print(stdout, "\e[?25l") # disable cursor
6069
try
61-
GC.@preserve p branch begin
70+
GC.@preserve transfer_payload branch begin
6271
callbacks = LibGit2.RemoteCallbacks(
63-
credentials=(LibGit2.credential_cb(), pointer_from_objref(cred_payload)),
64-
transfer_progress=(cfunction(transfer_progress, Cint, Tuple{Ptr{LibGit2.GitTransferProgress}, Any}), pointer_from_objref(transfer_payload)),
72+
credentials=(LibGit2.credentials_cb(), pointer_from_objref(cred_payload)),
73+
transfer_progress=(cfunction(transfer_progress, Cint, Tuple{Ptr{GitTransferProgress}, Any}), pointer_from_objref(transfer_payload)),
6574
)
6675
fetch_opts = LibGit2.FetchOptions(callbacks = callbacks)
67-
if branch == nothing
68-
clone_opts = LibGit2.CloneOptions(fetch_opts=fetch_opts, bare=isbare)
69-
else
70-
clone_opts = LibGit2.CloneOptions(fetch_opts=fetch_opts, bare=isbare, checkout_branch=Cstring(pointer(branch)))
71-
end
76+
clone_opts = LibGit2.CloneOptions(fetch_opts=fetch_opts, bare=isbare, checkout_branch= branch == nothing ? C_NULL : Cstring(pointer(branch)))
7277
return LibGit2.clone(url, source_path, clone_opts)
7378
end
7479
catch e
@@ -79,10 +84,42 @@ function clone(url, source_path; isbare::Bool=false, header = nothing, branch =
7984
rm(source_path; force=true, recursive=true)
8085
rethrow(e)
8186
finally
82-
print(stdout, "\e[?25h")
83-
println(stdout)
87+
print(stdout, "\033[2K") # clear line
88+
print(stdout, "\e[?25h") # put back cursor
89+
end
90+
LibGit2.approve(cred_payload)
91+
end
92+
93+
function fetch(repo::LibGit2.GitRepo, remoteurl=nothing; header = nothing, refspecs=String[], credentials=nothing)
94+
remote = if remoteurl == nothing
95+
LibGit2.get(LibGit2.GitRemote, repo, "origin")
96+
else
97+
LibGit2.GitRemoteAnon(repo, remoteurl)
98+
end
99+
Pkg3.Types.printpkgstyle(stdout, :Updating, header == nothing ? string("git-repo `", LibGit2.url(remote), "`") : header)
100+
transfer_payload = MiniProgressBar(header = "Fetching:", color = Base.info_color())
101+
cred_payload = LibGit2.CredentialPayload(credentials)
102+
print(stdout, "\e[?25l") # disable cursor
103+
try
104+
GC.@preserve transfer_payload begin
105+
callbacks = LibGit2.RemoteCallbacks(
106+
credentials=(LibGit2.credentials_cb(), pointer_from_objref(cred_payload)),
107+
transfer_progress=(cfunction(transfer_progress, Cint, Tuple{Ptr{GitTransferProgress}, Any}), pointer_from_objref(transfer_payload)),
108+
)
109+
fetch_opts = LibGit2.FetchOptions(callbacks = callbacks)
110+
return LibGit2.fetch(remote, refspecs; options=fetch_opts)
111+
end
112+
catch e
113+
if isa(e, LibGit2.GitError) && e.code == LibGit2.Error.EAUTH
114+
LibGit2.reject(cred_payload)
115+
end
116+
rethrow(e)
117+
finally
118+
close(remote)
119+
print(stdout, "\033[2K") # clear line
120+
print(stdout, "\e[?25h") # put back cursor
84121
end
85122
LibGit2.approve(cred_payload)
86123
end
87124

88-
end # module
125+
end # module

src/Operations.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ function install_git(
391391
err isa LibGit2.GitError && err.code == LibGit2.Error.ENOTFOUND || rethrow(err)
392392
end
393393
url = urls[i]
394-
LibGit2.fetch(repo, remoteurl=url, refspecs=refspecs, credentials=creds)
394+
GitTools.fetch(repo, url, refspecs=refspecs, credentials=creds)
395395
end
396396
tree = try
397397
with(LibGit2.GitObject, repo, git_hash) do g

src/Types.jl

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -622,14 +622,12 @@ function handle_repos_develop!(ctx::Context, pkgs::AbstractVector{PackageSpec})
622622
mkpath(clone_path)
623623
repo_path = joinpath(clone_path, string(hash(pkg.repo.url), "_full"))
624624
repo, just_cloned = ispath(repo_path) ? (LibGit2.GitRepo(repo_path), false) : begin
625-
printpkgstyle(ctx, :Cloning, "package from $(pkg.repo.url)")
626-
r = LibGit2.clone(pkg.repo.url, repo_path)
627-
GitTools.fetch(r, remoteurl=pkg.repo.url, refspecs=refspecs, credentials=creds)
625+
r = GitTools.clone(pkg.repo.url, repo_path)
626+
GitTools.fetch(r, pkg.repo.url; refspecs=refspecs, credentials=creds)
628627
r, true
629628
end
630629
if !just_cloned
631-
printpkgstyle(ctx, :Updating, "repo from $(pkg.repo.url)")
632-
GitTools.fetch(repo, remoteurl=pkg.repo.url, refspecs=refspecs, credentials=creds)
630+
GitTools.fetch(repo, pkg.repo.url; refspecs=refspecs, credentials=creds)
633631
end
634632
close(repo)
635633

@@ -672,14 +670,14 @@ function handle_repos_add!(ctx::Context, pkgs::AbstractVector{PackageSpec}; upgr
672670
repo_path = joinpath(clones_dir, string(hash(pkg.repo.url)))
673671
repo, just_cloned = ispath(repo_path) ? (LibGit2.GitRepo(repo_path), false) : begin
674672
r = GitTools.clone(pkg.repo.url, repo_path, isbare=true, credentials=creds)
675-
GitTools.fetch(r, remoteurl=pkg.repo.url, refspecs=refspecs, credentials=creds)
673+
GitTools.fetch(r, pkg.repo.url; refspecs=refspecs, credentials=creds)
676674
r, true
677675
end
678676
info = manifest_info(env, pkg.uuid)
679677
pinned = (info != nothing && get(info, "pinned", false))
680-
if upgrade_or_add && !pinned && !just_cloned
681-
printpkgstyle(ctx, :Updating, "repo from $(pkg.repo.url)")
682-
GitTools.fetch(repo, remoteurl=pkg.repo.url, refspecs=refspecs, credentials=creds)
678+
if upgrade_or_add && !pinned && !just_cloned
679+
rev = pkg.repo.rev
680+
GitTools.fetch(repo, pkg.repo.url; refspecs=refspecs, credentials=creds)
683681
end
684682
if upgrade_or_add && !pinned
685683
rev = pkg.repo.rev
@@ -934,7 +932,8 @@ function registries()::Vector{String}
934932
printpkgstyle(stdout, :Cloning, "default registries into $user_regs")
935933
for (reg, url) in DEFAULT_REGISTRIES
936934
path = joinpath(user_regs, reg)
937-
GitTools.clone(url, path; header = "registry $reg from $(repr(url))", credentials = creds)
935+
repo = Pkg3.GitTools.clone(url, path; header = "registry $reg from $(repr(url))", credentials = creds)
936+
close(repo)
938937
end
939938
end
940939
return [r for d in depots() for r in registries(d)]
@@ -1151,14 +1150,13 @@ pathrepr(path::String, base::String=pwd()) = pathrepr(nothing, path, base)
11511150
function pathrepr(env::Union{Nothing, EnvCache}, path::String, base::String=pwd())
11521151
path = abspath(base, path)
11531152
if env isa EnvCache && env.git != nothing
1154-
LibGit2.with(LibGit2.GitRepo, LibGit2.path(env.git)) do repo
1155-
if startswith(base, repo)
1156-
# we're in the repo => path relative to pwd()
1157-
path = relpath(path, base)
1158-
elseif startswith(path, repo)
1159-
# we're not in repo but path is => path relative to repo
1160-
path = relpath(path, repo)
1161-
end
1153+
repo = LibGit2.path(env.git)
1154+
if startswith(base, repo)
1155+
# we're in the repo => path relative to pwd()
1156+
path = relpath(path, base)
1157+
elseif startswith(path, repo)
1158+
# we're not in repo but path is => path relative to repo
1159+
path = relpath(path, repo)
11621160
end
11631161
end
11641162
if !Sys.iswindows() && isabspath(path)

0 commit comments

Comments
 (0)