Skip to content

Commit

Permalink
bin/prune: Add --only-branch
Browse files Browse the repository at this point in the history
In 5c94098 / #646 we
added `--retain-branch-depth`; this adds a symmetric
`--only-branch` for the case where a repo owner just
wants to prune a specific branch.

The implementation here is pretty straightforward; we
just walk all refs and inject the equivalent of
`--retain-branch-depth=$ref=-1` if they're *not* in
`--only-branch`.

Closes: #1115
  • Loading branch information
cgwalters committed Sep 1, 2017
1 parent 729d63f commit 50525a2
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 2 deletions.
41 changes: 40 additions & 1 deletion src/ostree/ot-builtin-prune.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ static gboolean opt_refs_only;
static char *opt_delete_commit;
static char *opt_keep_younger_than;
static char **opt_retain_branch_depth;
static char **opt_only_branches;

/* ATTENTION:
* Please remember to update the bash-completion script (bash/ostree) and
Expand All @@ -49,6 +50,7 @@ static GOptionEntry options[] = {
{ "keep-younger-than", 0, 0, G_OPTION_ARG_STRING, &opt_keep_younger_than, "Prune all commits older than the specified date", "DATE" },
{ "static-deltas-only", 0, 0, G_OPTION_ARG_NONE, &opt_static_deltas_only, "Change the behavior of delete-commit and keep-younger-than to prune only static deltas" },
{ "retain-branch-depth", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_retain_branch_depth, "Additionally retain BRANCH=DEPTH commits", "BRANCH=DEPTH" },
{ "only-branch", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_only_branches, "Only prune BRANCH (may be specified multiple times)", "BRANCH" },
{ NULL }
};

Expand Down Expand Up @@ -192,7 +194,7 @@ ostree_builtin_prune (int argc, char **argv, GCancellable *cancellable, GError *
gint n_objects_total;
gint n_objects_pruned;
guint64 objsize_total;
if (!(opt_retain_branch_depth || opt_keep_younger_than))
if (!(opt_retain_branch_depth || opt_keep_younger_than || opt_only_branches))
{
if (!ostree_repo_prune (repo, pruneflags, opt_depth,
&n_objects_total, &n_objects_pruned, &objsize_total,
Expand All @@ -217,6 +219,7 @@ ostree_builtin_prune (int argc, char **argv, GCancellable *cancellable, GError *
return glnx_throw (error, "Could not parse '%s'", opt_keep_younger_than);
}

/* Process --retain-branch-depth */
for (char **iter = opt_retain_branch_depth; iter && *iter; iter++)
{
/* bd should look like BRANCH=DEPTH where DEPTH is an int */
Expand Down Expand Up @@ -246,6 +249,41 @@ ostree_builtin_prune (int argc, char **argv, GCancellable *cancellable, GError *
cancellable, error))
return FALSE;

/* Process --only-branch. Note this combines with --retain-branch-depth; one
* could do e.g.:
* * --only-branch exampleos/x86_64/foo
* * --retain-branch-depth exampleos/x86_64/foo=0
* to prune exampleos/x86_64/foo to just the latest commit.
*/
if (opt_only_branches)
{
/* Turn --only-branch into a set */
g_autoptr(GHashTable) only_branches_set = g_hash_table_new (g_str_hash, g_str_equal);
for (char **iter = opt_only_branches; iter && *iter; iter++)
{
const char *ref = *iter;
g_autofree char *commit = NULL;
/* Ensure the specified branch exists */
if (!ostree_repo_resolve_rev (repo, ref, FALSE, &commit, error))
return FALSE;
g_hash_table_add (only_branches_set, *iter);
}

/* Iterate over all refs, add equivalent of --retain-branch-depth=$ref=-1
* if the ref isn't in --only-branch set.
*/
g_hash_table_iter_init (&hash_iter, all_refs);
while (g_hash_table_iter_next (&hash_iter, &key, &value))
{
const char *ref = key;
if (!g_hash_table_contains (only_branches_set, ref))
g_hash_table_insert (retain_branch_depth, g_strdup (ref), GINT_TO_POINTER ((int)-1));
}
}

/* Traverse each ref, and gather all objects pointed to by it up to a
* specific depth (if configured).
*/
g_hash_table_iter_init (&hash_iter, all_refs);
while (g_hash_table_iter_next (&hash_iter, &key, &value))
{
Expand Down Expand Up @@ -282,6 +320,7 @@ ostree_builtin_prune (int argc, char **argv, GCancellable *cancellable, GError *
return FALSE;
}

/* We've gathered the reachable set; start the prune ✀ */
{ OstreeRepoPruneOptions opts = { pruneflags, reachable };
if (!ostree_repo_prune_from_reachable (repo, &opts,
&n_objects_total,
Expand Down
40 changes: 39 additions & 1 deletion tests/test-prune.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ skip_without_user_xattrs

setup_fake_remote_repo1 "archive-z2"

echo '1..5'
echo '1..10'

cd ${test_tmpdir}
mkdir repo
Expand Down Expand Up @@ -238,3 +238,41 @@ assert_repo_has_n_commits repo 9
$OSTREE fsck

echo "ok retain branch depth (alone)"

# Test --only-branch with --depth=0; this should be exactly identical to the
# above with a result of 9.
reinitialize_datesnap_repo
${CMD_PREFIX} ostree --repo=repo prune --only-branch=dev --depth=0
assert_repo_has_n_commits repo 9
$OSTREE fsck
echo "ok --only-branch --depth=0"

# Test --only-branch with --depth=1; should just add 1 to the above, for 10.
reinitialize_datesnap_repo
${CMD_PREFIX} ostree --repo=repo prune --only-branch=dev --depth=1
assert_repo_has_n_commits repo 10
echo "ok --only-branch --depth=1"

# Test --only-branch with all branches
reinitialize_datesnap_repo
${CMD_PREFIX} ostree --repo=repo prune --only-branch=dev --only-branch=stable --depth=0
assert_repo_has_n_commits repo 2
reinitialize_datesnap_repo
${CMD_PREFIX} ostree --repo=repo prune --only-branch=dev --only-branch=stable --depth=1
assert_repo_has_n_commits repo 4
echo "ok --only-branch (all) --depth=1"

# Test --only-branch with --keep-younger-than; this should be identical to the test
# above for --retain-branch-depth=stable=-1
reinitialize_datesnap_repo
${CMD_PREFIX} ostree --repo=repo prune --only-branch=stable --keep-younger-than="1 week ago"
assert_repo_has_n_commits repo 11
echo "ok --only-branch --keep-younger-than"

# Test --only-branch with a nonexistent ref
reinitialize_datesnap_repo
if ${CMD_PREFIX} ostree --repo=repo prune --only-branch=BACON 2>err.txt; then
fatal "we pruned BACON?"
fi
assert_file_has_content err.txt "Refspec.*BACON.*not found"
echo "ok --only-branch=BACON"

0 comments on commit 50525a2

Please sign in to comment.