Skip to content

Commit f62f687

Browse files
authored
human-readable: scale progress rates by default (#1138)
1 parent a7404a9 commit f62f687

3 files changed

Lines changed: 31 additions & 8 deletions

File tree

‎progress.c‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
extern int am_server;
2727
extern int flist_eof;
2828
extern int quiet;
29+
extern int human_readable;
2930
extern int need_unsorted_flist;
3031
extern int output_needs_newline;
3132
extern int stdout_format_has_i;
@@ -69,9 +70,10 @@ static unsigned long msdiff(struct timeval *t1, struct timeval *t2)
6970
static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now, int is_last)
7071
{
7172
char rembuf[64], eol[128];
73+
const char *rate_str;
7274
unsigned long diff;
7375
double rate, remain;
74-
int pct;
76+
int pct, rate_human_level;
7577

7678
if (is_last) {
7779
int len = snprintf(eol, sizeof eol,
@@ -115,9 +117,13 @@ static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now, int is_l
115117

116118
output_needs_newline = 0;
117119
pct = ofs == size ? 100 : (int) (100.0 * ofs / size);
120+
/* Keep progress rates scaled while byte counts retain the level-1 default. */
121+
rate_human_level = human_readable == 1 ? 2 : human_readable;
122+
rate_str = rate >= INT64_MAX ? ">MAX "
123+
: do_big_num((int64)rate, rate_human_level, NULL);
118124
rput_progress();
119125
rprintf(FCLIENT, "%15sB %3d%% %7sB/s %s%s", human_num(ofs), pct,
120-
rate >= INT64_MAX ? ">MAX " : human_num((int64)rate), rembuf, eol);
126+
rate_str, rembuf, eol);
121127
if (!is_last && !quiet) {
122128
output_needs_newline = 1;
123129
rflush(FCLIENT);

‎rsync.1.md‎

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3613,7 +3613,9 @@ sign) if you want the local shell to expand it.
36133613

36143614
The default is human-readable level 1. Each `-h` option increases the
36153615
level by one. You can take the level down to 0 (to output numbers as pure
3616-
digits) by specifying the `--no-human-readable` (`--no-h`) option.
3616+
digits) by specifying the `--no-human-readable` (`--no-h`) option. Progress
3617+
rates are an exception: the default and `-h` use level 2, `--no-h` uses
3618+
level 0 and `-hh` uses level 3.
36173619

36183620
The unit letters that are appended in levels 2 and 3 are: `K` (kilo), `M`
36193621
(mega), `G` (giga), `T` (tera), `P` (peta) or `E` (exa). For example, a
@@ -3821,13 +3823,17 @@ sign) if you want the local shell to expand it.
38213823
While rsync is transferring a regular file, it updates a progress line that
38223824
looks like this:
38233825

3824-
> 782,448B 63% 113,295B/s 0:00:04
3826+
> 782,448B 63% 113KB/s 0:00:04
38253827
38263828
In this example, the receiver has reconstructed 782,448 bytes or 63% of the
3827-
sender's file, which is being reconstructed at a rate of 113,295 bytes
3829+
sender's file, which is being reconstructed at a rate of 113 kilobytes
38283830
per second, and the transfer will finish in 4 seconds if the current rate
38293831
is maintained until the end.
38303832

3833+
Progress rates are scaled in decimal units by default. `--no-h` keeps the
3834+
rate in bytes per second, while `-hh` uses binary units such as `KiB/s` and
3835+
`MiB/s`.
3836+
38313837
These statistics can be misleading if rsync's delta-transfer algorithm is
38323838
in use. For example, if the sender's file consists of the basis file
38333839
followed by additional data, the reported rate will probably drop
@@ -3838,10 +3844,10 @@ sign) if you want the local shell to expand it.
38383844
When the file transfer finishes, rsync replaces the progress line with a
38393845
summary line that looks like this:
38403846

3841-
> 1,238,099B 100% 149,893B/s 0:00:08 (xfr#5, to-chk=169/396)
3847+
> 1,238,099B 100% 150KB/s 0:00:08 (xfr#5, to-chk=169/396)
38423848
38433849
In this example, the file was 1,238,099 bytes long in total, the average
3844-
rate of transfer for the whole file was 149,893 bytes per second over the
3850+
rate of transfer for the whole file was 150 kilobytes per second over the
38453851
8 seconds that it took to complete, it was the 5th transfer of a
38463852
regular file during the current rsync session, and there are 169 more files
38473853
for the receiver to check (to see if they are up-to-date or not) remaining

‎testsuite/output-options_test.py‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def out(*args, want_rc=0, env=None, text=True):
9595
# --- --progress shows a percentage ------------------------------------------
9696
rmtree(TODIR)
9797
p = out('-a', '--progress', f'{src}/', f'{TODIR}/')
98-
progress_re = r'[\d.,]+B\s+100%\s+[\d.,]+B/s\s+\d+:\d\d:\d\d'
98+
progress_re = r'[\d.,]+B\s+100%\s+[\d.,]+(?:[KMGTPE]i?)?B/s\s+\d+:\d\d:\d\d'
9999
if not re.search(progress_re, p.stdout):
100100
test_fail(f"--progress did not show the expected final shape:\n{p.stdout}")
101101

@@ -122,6 +122,17 @@ def out(*args, want_rc=0, env=None, text=True):
122122
if re.search(suffix_re, plain):
123123
test_fail(f"--stats without -h unexpectedly used a unit suffix:\n{plain}")
124124

125+
for label, options, progress_re in (
126+
('default', (), r'50[,.]000B\s+100%\s+[\d.,]+[KMGTPE]B/s'),
127+
('--no-h', ('--no-h',), r'50000B\s+100%\s+\d+B/s'),
128+
('-h', ('-h',), r'50\.0KB\s+100%\s+[\d.,]+[KMGTPE]B/s'),
129+
('-hh', ('-hh',), r'48\.8KiB\s+100%\s+[\d.,]+[KMGTPE]iB/s'),
130+
):
131+
rmtree(TODIR)
132+
progress = out('-a', '--progress', *options, f'{src}/', f'{TODIR}/').stdout
133+
if not re.search(progress_re, progress):
134+
test_fail(f"{label} progress output has the wrong units:\n{progress}")
135+
125136
rmtree(TODIR)
126137
human_binary = out('-a', '-hh', '--stats', f'{src}/', f'{TODIR}/').stdout
127138
if 'Total file size: 48.8Ki bytes' not in human_binary:

0 commit comments

Comments
 (0)