1
1
#include < iostream>
2
2
3
3
#include " ../subcommand/clone_subcommand.hpp"
4
+ #include " ../utils/output.hpp"
4
5
#include " ../wrapper/repository_wrapper.hpp"
5
6
6
7
clone_subcommand::clone_subcommand (const libgit2_object&, CLI::App& app)
@@ -13,9 +14,90 @@ clone_subcommand::clone_subcommand(const libgit2_object&, CLI::App& app)
13
14
sub->callback ([this ]() { this ->run (); });
14
15
}
15
16
17
+ namespace
18
+ {
19
+ int sideband_progress (const char * str, int len, void *)
20
+ {
21
+ printf (" remote: %.*s" , len, str);
22
+ fflush (stdout);
23
+ return 0 ;
24
+ }
25
+
26
+ int fetch_progress (const git_indexer_progress* stats, void * payload)
27
+ {
28
+ static bool done = false ;
29
+
30
+ // We need to copy stats into payload even if the fetch is done,
31
+ // because the checkout_progress callback will be called with the
32
+ // same payload and needs the data to be up do date.
33
+ auto * pr = reinterpret_cast <git_indexer_progress*>(payload);
34
+ *pr = *stats;
35
+
36
+ if (done)
37
+ {
38
+ return 0 ;
39
+ }
40
+
41
+ int network_percent = pr->total_objects > 0 ?
42
+ (100 * pr->received_objects / pr->total_objects )
43
+ : 0 ;
44
+ size_t mbytes = pr->received_bytes / (1024 *1024 );
45
+
46
+ std::cout << " Receiving objects: " << std::setw (4 ) << network_percent
47
+ << " % (" << pr->received_objects << " /" << pr->total_objects << " ), "
48
+ << mbytes << " MiB" ;
49
+
50
+ if (pr->received_objects == pr->total_objects )
51
+ {
52
+ std::cout << " , done." << std::endl;
53
+ done = true ;
54
+ }
55
+ else
56
+ {
57
+ std::cout << ' \r ' ;
58
+ }
59
+ return 0 ;
60
+ }
61
+
62
+ void checkout_progress (const char * path, size_t cur, size_t tot, void * payload)
63
+ {
64
+ static bool done = false ;
65
+ if (done)
66
+ {
67
+ return ;
68
+ }
69
+ auto * pr = reinterpret_cast <git_indexer_progress*>(payload);
70
+ int deltas_percent = pr->total_deltas > 0 ?
71
+ (100 * pr->indexed_deltas / pr->total_deltas )
72
+ : 0 ;
73
+
74
+ std::cout << " Resolving deltas: " << std::setw (4 ) << deltas_percent
75
+ << " % (" << pr->indexed_deltas << " /" << pr->total_deltas << " )" ;
76
+ if (pr->indexed_deltas == pr->total_deltas )
77
+ {
78
+ std::cout << " , done." << std::endl;
79
+ done = true ;
80
+ }
81
+ else
82
+ {
83
+ std::cout << ' \r ' ;
84
+ }
85
+ }
86
+ }
87
+
16
88
void clone_subcommand::run ()
17
89
{
18
- git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
90
+ git_indexer_progress pd;
91
+ git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;
92
+ git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
93
+ checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
94
+ checkout_opts.progress_cb = checkout_progress;
95
+ checkout_opts.progress_payload = &pd;
96
+ clone_opts.checkout_opts = checkout_opts;
97
+ clone_opts.fetch_opts .callbacks .sideband_progress = sideband_progress;
98
+ clone_opts.fetch_opts .callbacks .transfer_progress = fetch_progress;
99
+ clone_opts.fetch_opts .callbacks .payload = &pd;
100
+
19
101
std::string short_name = m_directory;
20
102
if (m_directory.empty ())
21
103
{
@@ -27,5 +109,6 @@ void clone_subcommand::run()
27
109
m_directory = get_current_git_path () + ' /' + short_name;
28
110
}
29
111
std::cout << " Cloning into '" + short_name + " '..." << std::endl;
30
- repository_wrapper::clone (m_repository, m_directory, opts);
112
+ cursor_hider ch;
113
+ repository_wrapper::clone (m_repository, m_directory, clone_opts);
31
114
}
0 commit comments