diff --git a/Makefile-tests.am b/Makefile-tests.am index cce78f39..94dd79f5 100644 --- a/Makefile-tests.am +++ b/Makefile-tests.am @@ -30,6 +30,7 @@ testfiles = test-basic \ test-help \ test-libarchive \ test-pull-archive-z \ + test-pull-commit-only \ test-pull-corruption \ test-pull-depth \ test-pull-mirror-summary \ diff --git a/doc/ostree-pull.xml b/doc/ostree-pull.xml index 5247f44a..d915bcd2 100644 --- a/doc/ostree-pull.xml +++ b/doc/ostree-pull.xml @@ -57,6 +57,14 @@ Boston, MA 02111-1307, USA. Options + + + + + Fetch only the commit metadata. + + + diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index 71469e9f..aa8e6359 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -88,6 +88,7 @@ typedef struct { guint64 start_time; gboolean is_mirror; + gboolean is_commit_only; char *dir; gboolean commitpartial_exists; @@ -1119,6 +1120,11 @@ scan_one_metadata_object_c (OtPullData *pull_data, do_fetch_detached = (objtype == OSTREE_OBJECT_TYPE_COMMIT); enqueue_one_object_request (pull_data, tmp_checksum, objtype, do_fetch_detached, FALSE); } + else if (objtype == OSTREE_OBJECT_TYPE_COMMIT && pull_data->is_commit_only) + { + ret = TRUE; + goto out; + } else if (is_stored) { gboolean do_scan = pull_data->transaction_resuming || is_requested || pull_data->commitpartial_exists; @@ -1654,6 +1660,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, g_return_val_if_fail (dir_to_pull[0] == '/', FALSE); pull_data->is_mirror = (flags & OSTREE_REPO_PULL_FLAGS_MIRROR) > 0; + pull_data->is_commit_only = (flags & OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY) > 0; pull_data->async_error = error; pull_data->main_context = g_main_context_ref_thread_default (); @@ -2160,7 +2167,7 @@ ostree_repo_pull_with_options (OstreeRepo *self, } /* iterate over commits fetched and delete any commitpartial files */ - if (!dir_to_pull) + if (!dir_to_pull && !pull_data->is_commit_only) { g_hash_table_iter_init (&hash_iter, requested_refs_to_fetch); while (g_hash_table_iter_next (&hash_iter, &key, &value)) diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 31c3b68c..28d67b2c 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -3674,6 +3674,9 @@ ostree_repo_read_commit (OstreeRepo *self, * the @refs_to_fetch is %NULL, and the remote repository contains a * summary file, then all refs will be fetched. * + * If @flags contains %OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY, then only the + * metadata for the commits in @refs_to_fetch is pulled. + * * Warning: This API will iterate the thread default main context, * which is a bug, but kept for compatibility reasons. If you want to * avoid this, use g_main_context_push_thread_default() to push a new diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index 992cf1e1..38a261f9 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -693,10 +693,12 @@ gboolean ostree_repo_prune (OstreeRepo *self, * OstreeRepoPullFlags: * @OSTREE_REPO_PULL_FLAGS_NONE: No special options for pull * @OSTREE_REPO_PULL_FLAGS_MIRROR: Write out refs suitable for mirrors + * @OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY: Fetch only the commit metadata */ typedef enum { OSTREE_REPO_PULL_FLAGS_NONE, - OSTREE_REPO_PULL_FLAGS_MIRROR + OSTREE_REPO_PULL_FLAGS_MIRROR = (1 << 0), + OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY = (1 << 1) } OstreeRepoPullFlags; gboolean ostree_repo_pull (OstreeRepo *self, diff --git a/src/ostree/ot-builtin-pull.c b/src/ostree/ot-builtin-pull.c index 9192e7cc..6aae8205 100644 --- a/src/ostree/ot-builtin-pull.c +++ b/src/ostree/ot-builtin-pull.c @@ -29,11 +29,13 @@ static gboolean opt_disable_fsync; static gboolean opt_mirror; +static gboolean opt_commit_only; static gboolean opt_disable_static_deltas; static char* opt_subpath; static int opt_depth = 0; static GOptionEntry options[] = { + { "commit-metadata-only", 0, 0, G_OPTION_ARG_NONE, &opt_commit_only, "Fetch only the commit metadata", NULL }, { "disable-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", NULL }, { "disable-static-deltas", 0, 0, G_OPTION_ARG_NONE, &opt_disable_static_deltas, "Do not use static deltas", NULL }, { "mirror", 0, 0, G_OPTION_ARG_NONE, &opt_mirror, "Write refs suitable for a mirror", NULL }, @@ -91,6 +93,9 @@ ostree_builtin_pull (int argc, char **argv, GCancellable *cancellable, GError ** if (opt_mirror) pullflags |= OSTREE_REPO_PULL_FLAGS_MIRROR; + if (opt_commit_only) + pullflags |= OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY; + if (strchr (argv[1], ':') == NULL) { remote = g_strdup (argv[1]); diff --git a/tests/test-pull-commit-only.sh b/tests/test-pull-commit-only.sh new file mode 100755 index 00000000..1cdc675f --- /dev/null +++ b/tests/test-pull-commit-only.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# +# Copyright (C) 2015 Red Hat, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +set -e + +. $(dirname $0)/libtest.sh + +setup_fake_remote_repo1 "archive-z2" + +echo '1..1' + +cd ${test_tmpdir} +mkdir repo +${CMD_PREFIX} ostree --repo=repo init +${CMD_PREFIX} ostree --repo=repo remote add --set=gpg-verify=false origin $(cat httpd-address)/ostree/gnomerepo + +ostree --repo=repo pull --commit-metadata-only origin main +find repo/objects -name '*.commit' | wc -l > commitcount +assert_file_has_content commitcount "^1$" +ostree --repo=repo fsck + +find repo/objects -name '*.file.*' | wc -l > commitcount +assert_file_has_content commitcount "^0$" + +find repo/objects -name '*.dirtree' | wc -l > commitcount +assert_file_has_content commitcount "^0$" + +echo "ok pull commit metadata only"