Skip to content

Commit bc1a700

Browse files
authored
gc: add dry option and log num removed objs (#9952)
Closes #9330
1 parent 9f4b67c commit bc1a700

File tree

4 files changed

+35
-6
lines changed

4 files changed

+35
-6
lines changed

dvc/commands/gc.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ def run(self): # noqa: C901, PLR0912
8181
rev=self.args.rev,
8282
num=self.args.num,
8383
not_in_remote=self.args.not_in_remote,
84+
dry=self.args.dry,
8485
)
8586
return 0
8687

@@ -213,4 +214,10 @@ def add_parser(subparsers, parent_parser):
213214
),
214215
metavar="<paths>",
215216
)
217+
gc_parser.add_argument(
218+
"--dry",
219+
action="store_true",
220+
default=False,
221+
help=("Only print what would get removed without actually removing."),
222+
)
216223
gc_parser.set_defaults(func=CmdGC)

dvc/repo/gc.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ def gc( # noqa: PLR0913, C901
6767
rev: Optional[str] = None,
6868
num: Optional[int] = None,
6969
not_in_remote: bool = False,
70+
dry: bool = False,
7071
):
7172
# require `workspace` to be true to come into effect.
7273
# assume `workspace` to be enabled if any of `all_tags`, `all_commits`,
@@ -128,18 +129,21 @@ def gc( # noqa: PLR0913, C901
128129
for scheme, odb in self.cache.by_scheme():
129130
if not odb:
130131
continue
131-
removed = ogc(odb, used_obj_ids, jobs=jobs)
132-
if not removed:
132+
num_removed = ogc(odb, used_obj_ids, jobs=jobs, dry=dry)
133+
if num_removed:
134+
logger.info("Removed %d objects from %s cache.", num_removed, scheme)
135+
else:
133136
logger.info("No unused '%s' cache to remove.", scheme)
134137

135138
if not cloud:
136139
return
137140

138141
for remote_odb, obj_ids in odb_to_obj_ids.items():
139142
assert remote_odb is not None
140-
removed = ogc(remote_odb, obj_ids, jobs=jobs)
141-
if removed:
143+
num_removed = ogc(remote_odb, obj_ids, jobs=jobs, dry=dry)
144+
if num_removed:
142145
get_index(remote_odb).clear()
146+
logger.info("Removed %d objects from remote.", num_removed)
143147
else:
144148
logger.info("No unused cache to remove from remote.")
145149

tests/func/test_gc.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@ def test_gc_api(dvc, good_and_bad_cache):
3636
dvc.gc(workspace=True)
3737
odb = dvc.cache.local
3838
good_cache, bad_cache = good_and_bad_cache
39-
assert set(odb.oids_exist([*good_cache, *bad_cache])) == good_cache
39+
assert set(odb.all()) == good_cache
4040

4141

4242
def test_gc_cli(dvc, good_and_bad_cache):
4343
assert main(["gc", "-wf"]) == 0
4444
odb = dvc.cache.local
4545
good_cache, bad_cache = good_and_bad_cache
46-
assert set(odb.oids_exist([*good_cache, *bad_cache])) == good_cache
46+
assert set(odb.all()) == good_cache
4747

4848

4949
def test_gc_branches_tags(tmp_dir, dvc, scm):
@@ -423,3 +423,19 @@ def test_gc_cloud_remote_field(tmp_dir, scm, dvc, mocker, make_remote):
423423
mocked_remove = mocker.spy(LocalFileSystem, "remove")
424424
dvc.gc(workspace=True, cloud=True)
425425
assert len(mocked_remove.mock_calls) == 2 # local and other_remote
426+
427+
428+
def test_gc_dry(dvc, good_and_bad_cache):
429+
dvc.gc(workspace=True, dry=True)
430+
odb = dvc.cache.local
431+
good_cache, bad_cache = good_and_bad_cache
432+
assert set(odb.all()) != good_cache
433+
434+
435+
def test_gc_logging(caplog, dvc, good_and_bad_cache):
436+
with caplog.at_level(logging.INFO, logger="dvc"):
437+
dvc.gc(workspace=True)
438+
439+
assert "Removed 3 objects from repo cache." in caplog.text
440+
assert "No unused 'local' cache to remove." in caplog.text
441+
assert "No unused 'legacy' cache to remove." in caplog.text

tests/unit/command/test_gc.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def test_(dvc, scm, mocker):
2222
"--force",
2323
"--jobs",
2424
"3",
25+
"--dry",
2526
"--projects",
2627
"project1",
2728
"project2",
@@ -49,6 +50,7 @@ def test_(dvc, scm, mocker):
4950
rev=None,
5051
num=None,
5152
not_in_remote=False,
53+
dry=True,
5254
)
5355

5456
cli_args = parse_args(["gc"])

0 commit comments

Comments
 (0)