Repository: borgbackup/borg

Issue:
borg compact -v could output some info
I tried `borg compact -v` in 1.2.0a6 and noticed it shows no output. I tried `borg compact --debug` and indeed it shows debug output.

`-v` usually shows some useful info/stats with other commands, it would be nice if borg compact could also output some basic stats (space freed or something else meaningful).

Also a couple tips related to compact (maybe I should open a new issue):
- the web page (https://borgbackup.readthedocs.io/en/latest/usage/compact.html) should details a bit more the description of --cleanup-commits , e.g. something like `"cleanup commit-only 17-byte segment files generated by borg 1.1. Use this one time after upgrading borg (server) to 1.2+"`, removing the same info from the Example;
- the docs should also clarify when it is useful to run compact, and also which commands may need it. I suppose it is only useful after a delete/prune. If I just run creates (and never delete/prune) is it still needed? BTW in 1.1 in which commands was executed?


Discussion:
good ideas, I'll see what can be done.

in < 1.2, compaction (IIRC) was always invoked when borg did write access to the repo.

but guess the only action creating holes that should be compacted is any kind of object deletion.

@FabioPedretti try `borg compact --progress` to see progress information.

Other than that, there isn't much to show for `borg compact --verbose` - just saying it started and it ended is a bit pointless and everything potentially taking a long time is covered by the progress indicator.

Looking at statistics now ...
Side note: if one uses a storage quota, it will log the quota and the quota use (which has somehow similar information than logging how much space was freed by compact_segments).

Resolving patch:
diff --git a/src/borg/archiver.py b/src/borg/archiver.py
--- a/src/borg/archiver.py
+++ b/src/borg/archiver.py
@@ -2777,12 +2777,20 @@ def define_archive_filters_group(subparser, *, sort_by=True, first_last=True):
         This command frees repository space by compacting segments.
 
         Use this regularly to avoid running out of space - you do not need to use this
-        after each borg command though.
+        after each borg command though. It is especially useful after deleting archives,
+        because only compaction will really free repository space.
 
         borg compact does not need a key, so it is possible to invoke it from the
         client or also from the server.
 
-        Depending on the amount of segments that need compaction, it may take a while.
+        Depending on the amount of segments that need compaction, it may take a while,
+        so consider using the ``--progress`` option.
+
+        When using ``--verbose``, borg will output an estimate of the freed space.
+
+        After upgrading borg (server) to 1.2+, you can use ``borg compact --cleanup-commits``
+        to clean up the numerous 17byte commit-only segments that borg 1.1 did not clean up
+        due to a bug. It is enough to do that once per repository.
 
         See :ref:`separate_compaction` in Additional Notes for more details.
         """)
diff --git a/src/borg/repository.py b/src/borg/repository.py
--- a/src/borg/repository.py
+++ b/src/borg/repository.py
@@ -695,6 +695,7 @@ def compact_segments(self):
         if not self.compact:
             logger.debug('nothing to do: compact empty')
             return
+        freed_space = 0
         index_transaction_id = self.get_index_transaction_id()
         segments = self.segments
         unused = []  # list of segments, that are not used anymore
@@ -734,6 +735,7 @@ def complete_xfer(intermediate=True):
                              segment, freeable_ratio * 100.0, freeable_space)
                 pi.show()
                 continue
+            freed_space += freeable_space  # this is what we THINK we can free
             segments.setdefault(segment, 0)
             logger.debug('compacting segment %d with usage count %d (freeable: %2.2f%% [%d bytes])',
                          segment, segments[segment], freeable_ratio * 100.0, freeable_space)
@@ -814,6 +816,7 @@ def complete_xfer(intermediate=True):
             pi.show()
         pi.finish()
         complete_xfer(intermediate=False)
+        logger.info('compaction freed about %s repository space.', format_file_size(freed_space))
         logger.debug('compaction completed.')
 
     def replay_segments(self, index_transaction_id, segments_transaction_id):


Test patch: