Skip to content

Commit ae7052a

Browse files
derrickstoleedscho
authored andcommitted
maintenance: care about gvfs.sharedCache config
For Scalar and VFS for Git, we use an alternate as a shared object cache. We need to enable the maintenance builtin to work on that shared object cache, especially in the background. 'scalar run <task>' would set GIT_OBJECT_DIRECTORY to handle this. We set GIT_OBJECT_DIRECTORY based on the gvfs.sharedCache config, but we also need the checks in pack_loose() to look at that object directory instead of the current ODB's. Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
1 parent 77a0de5 commit ae7052a

File tree

2 files changed

+69
-3
lines changed

2 files changed

+69
-3
lines changed

builtin/gc.c

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,21 +1338,37 @@ static int write_loose_object_to_stdin(const struct object_id *oid,
13381338
return ++(d->count) > d->batch_size;
13391339
}
13401340

1341+
static const char *shared_object_dir = NULL;
1342+
13411343
static int pack_loose(struct maintenance_run_opts *opts)
13421344
{
13431345
struct repository *r = the_repository;
13441346
int result = 0;
13451347
struct write_loose_object_data data;
13461348
struct child_process pack_proc = CHILD_PROCESS_INIT;
1349+
struct odb_source *prev_source = NULL;
1350+
const char *object_dir = r->objects->sources->path;
1351+
1352+
/* If set, use the shared object directory. */
1353+
if (shared_object_dir) {
1354+
prev_source =
1355+
odb_set_temporary_primary_source(r->objects,
1356+
shared_object_dir, 0);
1357+
object_dir = shared_object_dir;
1358+
}
13471359

13481360
/*
13491361
* Do not start pack-objects process
13501362
* if there are no loose objects.
13511363
*/
13521364
if (!for_each_loose_file_in_source(r->objects->sources,
13531365
bail_on_loose,
1354-
NULL, NULL, NULL))
1366+
NULL, NULL, NULL)) {
1367+
if (shared_object_dir)
1368+
odb_restore_primary_source(r->objects, prev_source,
1369+
shared_object_dir);
13551370
return 0;
1371+
}
13561372

13571373
pack_proc.git_cmd = 1;
13581374

@@ -1361,7 +1377,7 @@ static int pack_loose(struct maintenance_run_opts *opts)
13611377
strvec_push(&pack_proc.args, "--quiet");
13621378
else
13631379
strvec_push(&pack_proc.args, "--no-quiet");
1364-
strvec_pushf(&pack_proc.args, "%s/pack/loose", r->objects->sources->path);
1380+
strvec_pushf(&pack_proc.args, "%s/pack/loose", object_dir);
13651381

13661382
pack_proc.in = -1;
13671383

@@ -1373,6 +1389,9 @@ static int pack_loose(struct maintenance_run_opts *opts)
13731389

13741390
if (start_command(&pack_proc)) {
13751391
error(_("failed to start 'git pack-objects' process"));
1392+
if (shared_object_dir)
1393+
odb_restore_primary_source(r->objects, prev_source,
1394+
shared_object_dir);
13761395
return 1;
13771396
}
13781397

@@ -1400,6 +1419,10 @@ static int pack_loose(struct maintenance_run_opts *opts)
14001419
result = 1;
14011420
}
14021421

1422+
if (shared_object_dir)
1423+
odb_restore_primary_source(r->objects, prev_source,
1424+
shared_object_dir);
1425+
14031426
return result;
14041427
}
14051428

@@ -1832,11 +1855,12 @@ static int task_option_parse(const struct option *opt,
18321855
}
18331856

18341857
static int maintenance_run(int argc, const char **argv, const char *prefix,
1835-
struct repository *repo UNUSED)
1858+
struct repository *repo)
18361859
{
18371860
struct maintenance_run_opts opts = MAINTENANCE_RUN_OPTS_INIT;
18381861
struct string_list selected_tasks = STRING_LIST_INIT_DUP;
18391862
struct gc_config cfg = GC_CONFIG_INIT;
1863+
const char *tmp_obj_dir = NULL;
18401864
struct option builtin_maintenance_run_options[] = {
18411865
OPT_BOOL(0, "auto", &opts.auto_flag,
18421866
N_("run tasks based on the state of the repository")),
@@ -1873,6 +1897,17 @@ static int maintenance_run(int argc, const char **argv, const char *prefix,
18731897
usage_with_options(builtin_maintenance_run_usage,
18741898
builtin_maintenance_run_options);
18751899

1900+
/*
1901+
* To enable the VFS for Git/Scalar shared object cache, use
1902+
* the gvfs.sharedcache config option to redirect the
1903+
* maintenance to that location.
1904+
*/
1905+
if (!repo_config_get_value(repo, "gvfs.sharedcache", &tmp_obj_dir) &&
1906+
tmp_obj_dir) {
1907+
shared_object_dir = xstrdup(tmp_obj_dir);
1908+
setenv(DB_ENVIRONMENT, shared_object_dir, 1);
1909+
}
1910+
18761911
ret = maintenance_run_tasks(&opts, &cfg);
18771912

18781913
string_list_clear(&selected_tasks, 0);

t/t7900-maintenance.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,37 @@ test_expect_success 'maintenance.loose-objects.batchSize' '
334334
test_must_be_empty err
335335
'
336336

337+
test_expect_success 'loose-objects and gvfs.sharedCache' '
338+
git init gvfs-worktree &&
339+
git init --bare gvfs-shared &&
340+
git -C gvfs-worktree config gvfs.sharedCache "$PWD/gvfs-shared/objects" &&
341+
342+
# Hack to stop maintenance from running during "git commit"
343+
echo in use >gvfs-worktree/.git/objects/maintenance.lock &&
344+
git -C gvfs-worktree config maintenance.loose-objects.auto 1 &&
345+
test_commit -C gvfs-worktree create-loose-object &&
346+
rm gvfs-worktree/.git/objects/maintenance.lock &&
347+
! ls -l gvfs-shared/objects/??/* &&
348+
ls -l gvfs-worktree/.git/objects/??/* >loose-objects &&
349+
test_file_not_empty loose-objects &&
350+
! ls -l gvfs-shared/objects/pack/*.pack &&
351+
352+
# move the loose objects into the shared objects as if they had been
353+
# fetched via the `gvfs-helper`
354+
mv gvfs-worktree/.git/objects/?? gvfs-shared/objects/ &&
355+
356+
# Run `loose-objects` twice: The first run creates a pack-file
357+
# but does not delete loose objects, the second run deletes
358+
# loose objects but does not create a pack-file.
359+
git -C gvfs-worktree maintenance run --task=loose-objects &&
360+
git -C gvfs-worktree maintenance run --task=loose-objects &&
361+
362+
! ls -l gvfs-worktree/.git/objects/??/* &&
363+
! ls -l gvfs-shared/.git/objects/??/* &&
364+
ls -l gvfs-shared/objects/pack/*.pack >shared-packs &&
365+
test_file_not_empty shared-packs
366+
'
367+
337368
test_expect_success 'incremental-repack task' '
338369
packDir=.git/objects/pack &&
339370
for i in $(test_seq 1 5)

0 commit comments

Comments
 (0)