[ostree] core: Add --skip-if-unchanged option for commit
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ostree] core: Add --skip-if-unchanged option for commit
- Date: Fri, 23 Dec 2011 17:10:41 +0000 (UTC)
commit dab4611263e5cd2dbf8fd1ecbde88e8ac5e68ac6
Author: Colin Walters <walters verbum org>
Date: Thu Dec 22 18:47:30 2011 -0500
core: Add --skip-if-unchanged option for commit
There's not much point for OS builds to have "empty" commits.
src/libostree/ostree-repo.c | 33 ++++++++++++++++++++++++
src/libostree/ostree-repo.h | 4 +++
src/ostree/ot-builtin-commit.c | 55 +++++++++++++++++++++++++++++++++------
tests/t0000-basic.sh | 8 +++++-
4 files changed, 90 insertions(+), 10 deletions(-)
---
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index 220994d..9c295aa 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -1044,6 +1044,39 @@ ostree_repo_commit_transaction (OstreeRepo *self,
return ret;
}
+gboolean
+ostree_repo_abort_transaction (OstreeRepo *self,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ OstreeRepoPrivate *priv = GET_PRIVATE (self);
+ GFile *f = NULL;
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_return_val_if_fail (priv->in_transaction == TRUE, FALSE);
+
+ priv->in_transaction = FALSE;
+
+ g_hash_table_iter_init (&iter, priv->pending_transaction_tmpfiles);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ const char *filename = value;
+
+ g_clear_object (&f);
+ f = g_file_get_child (priv->tmp_dir, filename);
+
+ (void) unlink (ot_gfile_get_path_cached (f));
+ }
+
+ ret = TRUE;
+ out:
+ g_hash_table_remove_all (priv->pending_transaction_tmpfiles);
+ g_clear_object (&f);
+ return ret;
+}
+
static gboolean
stage_gvariant_object (OstreeRepo *self,
OstreeObjectType type,
diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h
index 272d159..08ebd58 100644
--- a/src/libostree/ostree-repo.h
+++ b/src/libostree/ostree-repo.h
@@ -88,6 +88,10 @@ gboolean ostree_repo_commit_transaction (OstreeRepo *self,
GCancellable *cancellable,
GError **error);
+gboolean ostree_repo_abort_transaction (OstreeRepo *self,
+ GCancellable *cancellable,
+ GError **error);
+
gboolean ostree_repo_has_object (OstreeRepo *self,
OstreeObjectType objtype,
const char *checksum,
diff --git a/src/ostree/ot-builtin-commit.c b/src/ostree/ot-builtin-commit.c
index d97c27d..5fcc037 100644
--- a/src/ostree/ot-builtin-commit.c
+++ b/src/ostree/ot-builtin-commit.c
@@ -35,6 +35,7 @@ static char *subject;
static char *body;
static char *parent;
static char *branch;
+static gboolean skip_if_unchanged;
static char **trees;
static gint owner_uid = -1;
static gint owner_gid = -1;
@@ -49,6 +50,7 @@ static GOptionEntry options[] = {
{ "tree", 0, 0, G_OPTION_ARG_STRING_ARRAY, &trees, "Overlay the given argument as a tree", "NAME" },
{ "owner-uid", 0, 0, G_OPTION_ARG_INT, &owner_uid, "Set file ownership user id", "UID" },
{ "owner-gid", 0, 0, G_OPTION_ARG_INT, &owner_gid, "Set file ownership group id", "GID" },
+ { "skip-if-unchanged", 0, 0, G_OPTION_ARG_NONE, &skip_if_unchanged, "If the contents are unchanged from previous commit, do nothing", NULL },
{ NULL }
};
@@ -61,6 +63,7 @@ ostree_builtin_commit (int argc, char **argv, GFile *repo_path, GError **error)
GFile *arg = NULL;
char *parent = NULL;
char *commit_checksum = NULL;
+ GVariant *parent_commit = NULL;
GVariant *metadata = NULL;
GMappedFile *metadata_mappedf = NULL;
GFile *metadata_f = NULL;
@@ -69,6 +72,7 @@ ostree_builtin_commit (int argc, char **argv, GFile *repo_path, GError **error)
GCancellable *cancellable = NULL;
OstreeMutableTree *mtree = NULL;
char *tree_type = NULL;
+ gboolean skip_commit = FALSE;
context = g_option_context_new ("[ARG] - Commit a new revision");
g_option_context_add_main_entries (context, options, NULL);
@@ -128,6 +132,13 @@ ostree_builtin_commit (int argc, char **argv, GFile *repo_path, GError **error)
if (!ostree_repo_resolve_rev (repo, branch, TRUE, &parent, error))
goto out;
+ if (skip_if_unchanged && parent)
+ {
+ if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT,
+ parent, &parent_commit, error))
+ goto out;
+ }
+
if (!ostree_repo_prepare_transaction (repo, cancellable, error))
goto out;
@@ -200,24 +211,50 @@ ostree_builtin_commit (int argc, char **argv, GFile *repo_path, GError **error)
if (!ostree_repo_stage_mtree (repo, mtree, &contents_checksum, cancellable, error))
goto out;
- if (!ostree_repo_stage_commit (repo, branch, parent, subject, body, metadata,
- contents_checksum, ostree_mutable_tree_get_metadata_checksum (mtree),
- &commit_checksum, cancellable, error))
- goto out;
+ if (skip_if_unchanged && parent_commit)
+ {
+ const char *parent_contents_checksum;
+ const char *parent_metadata_checksum;
- if (!ostree_repo_commit_transaction (repo, cancellable, error))
- goto out;
+ g_variant_get_child (parent_commit, 6, "&s", &parent_contents_checksum);
+ g_variant_get_child (parent_commit, 7, "&s", &parent_metadata_checksum);
- if (!ostree_repo_write_ref (repo, NULL, branch, commit_checksum, error))
- goto out;
+ if (strcmp (contents_checksum, parent_contents_checksum) == 0
+ && strcmp (ostree_mutable_tree_get_metadata_checksum (mtree),
+ parent_metadata_checksum) == 0)
+ skip_commit = TRUE;
+ }
+
+ if (!skip_commit)
+ {
+ if (!ostree_repo_stage_commit (repo, branch, parent, subject, body, metadata,
+ contents_checksum, ostree_mutable_tree_get_metadata_checksum (mtree),
+ &commit_checksum, cancellable, error))
+ goto out;
+
+ if (!ostree_repo_commit_transaction (repo, cancellable, error))
+ goto out;
+
+ if (!ostree_repo_write_ref (repo, NULL, branch, commit_checksum, error))
+ goto out;
+
+ g_print ("%s\n", commit_checksum);
+ }
+ else
+ {
+ if (!ostree_repo_abort_transaction (repo, cancellable, error))
+ goto out;
+
+ g_print ("%s\n", parent);
+ }
ret = TRUE;
- g_print ("%s\n", commit_checksum);
out:
g_clear_object (&arg);
g_clear_object (&mtree);
g_free (contents_checksum);
g_free (parent);
+ ot_clear_gvariant(&parent_commit);
g_free (tree_type);
if (metadata_mappedf)
g_mapped_file_unref (metadata_mappedf);
diff --git a/tests/t0000-basic.sh b/tests/t0000-basic.sh
index 62e15b1..9176d8f 100755
--- a/tests/t0000-basic.sh
+++ b/tests/t0000-basic.sh
@@ -19,7 +19,7 @@
set -e
-echo "1..20"
+echo "1..21"
. libtest.sh
@@ -158,3 +158,9 @@ echo "ok commit from ref"
$OSTREE commit -b trees/test2 -s 'ref with / in it' --tree=ref=test2
echo "ok commit ref with /"
+old_rev=$($OSTREE rev-parse test2)
+$OSTREE commit --skip-if-unchanged -b test2 -s 'should not be committed' --tree=ref=test2
+new_rev=$($OSTREE rev-parse test2)
+assert_streq "${old_rev}" "${new_rev}"
+echo "ok commit --skip-if-unchanged"
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]