core: Add --skip-if-unchanged option for commit
There's not much point for OS builds to have "empty" commits.
This commit is contained in:
parent
d8ea31e24e
commit
dab4611263
|
|
@ -1044,6 +1044,39 @@ ostree_repo_commit_transaction (OstreeRepo *self,
|
||||||
return ret;
|
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
|
static gboolean
|
||||||
stage_gvariant_object (OstreeRepo *self,
|
stage_gvariant_object (OstreeRepo *self,
|
||||||
OstreeObjectType type,
|
OstreeObjectType type,
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,10 @@ gboolean ostree_repo_commit_transaction (OstreeRepo *self,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
gboolean ostree_repo_abort_transaction (OstreeRepo *self,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
gboolean ostree_repo_has_object (OstreeRepo *self,
|
gboolean ostree_repo_has_object (OstreeRepo *self,
|
||||||
OstreeObjectType objtype,
|
OstreeObjectType objtype,
|
||||||
const char *checksum,
|
const char *checksum,
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ static char *subject;
|
||||||
static char *body;
|
static char *body;
|
||||||
static char *parent;
|
static char *parent;
|
||||||
static char *branch;
|
static char *branch;
|
||||||
|
static gboolean skip_if_unchanged;
|
||||||
static char **trees;
|
static char **trees;
|
||||||
static gint owner_uid = -1;
|
static gint owner_uid = -1;
|
||||||
static gint owner_gid = -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" },
|
{ "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-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" },
|
{ "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 }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -61,6 +63,7 @@ ostree_builtin_commit (int argc, char **argv, GFile *repo_path, GError **error)
|
||||||
GFile *arg = NULL;
|
GFile *arg = NULL;
|
||||||
char *parent = NULL;
|
char *parent = NULL;
|
||||||
char *commit_checksum = NULL;
|
char *commit_checksum = NULL;
|
||||||
|
GVariant *parent_commit = NULL;
|
||||||
GVariant *metadata = NULL;
|
GVariant *metadata = NULL;
|
||||||
GMappedFile *metadata_mappedf = NULL;
|
GMappedFile *metadata_mappedf = NULL;
|
||||||
GFile *metadata_f = NULL;
|
GFile *metadata_f = NULL;
|
||||||
|
|
@ -69,6 +72,7 @@ ostree_builtin_commit (int argc, char **argv, GFile *repo_path, GError **error)
|
||||||
GCancellable *cancellable = NULL;
|
GCancellable *cancellable = NULL;
|
||||||
OstreeMutableTree *mtree = NULL;
|
OstreeMutableTree *mtree = NULL;
|
||||||
char *tree_type = NULL;
|
char *tree_type = NULL;
|
||||||
|
gboolean skip_commit = FALSE;
|
||||||
|
|
||||||
context = g_option_context_new ("[ARG] - Commit a new revision");
|
context = g_option_context_new ("[ARG] - Commit a new revision");
|
||||||
g_option_context_add_main_entries (context, options, NULL);
|
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))
|
if (!ostree_repo_resolve_rev (repo, branch, TRUE, &parent, error))
|
||||||
goto out;
|
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))
|
if (!ostree_repo_prepare_transaction (repo, cancellable, error))
|
||||||
goto out;
|
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))
|
if (!ostree_repo_stage_mtree (repo, mtree, &contents_checksum, cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!ostree_repo_stage_commit (repo, branch, parent, subject, body, metadata,
|
if (skip_if_unchanged && parent_commit)
|
||||||
contents_checksum, ostree_mutable_tree_get_metadata_checksum (mtree),
|
{
|
||||||
&commit_checksum, cancellable, error))
|
const char *parent_contents_checksum;
|
||||||
goto out;
|
const char *parent_metadata_checksum;
|
||||||
|
|
||||||
if (!ostree_repo_commit_transaction (repo, cancellable, error))
|
g_variant_get_child (parent_commit, 6, "&s", &parent_contents_checksum);
|
||||||
goto out;
|
g_variant_get_child (parent_commit, 7, "&s", &parent_metadata_checksum);
|
||||||
|
|
||||||
if (!ostree_repo_write_ref (repo, NULL, branch, commit_checksum, error))
|
if (strcmp (contents_checksum, parent_contents_checksum) == 0
|
||||||
goto out;
|
&& 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;
|
ret = TRUE;
|
||||||
g_print ("%s\n", commit_checksum);
|
|
||||||
out:
|
out:
|
||||||
g_clear_object (&arg);
|
g_clear_object (&arg);
|
||||||
g_clear_object (&mtree);
|
g_clear_object (&mtree);
|
||||||
g_free (contents_checksum);
|
g_free (contents_checksum);
|
||||||
g_free (parent);
|
g_free (parent);
|
||||||
|
ot_clear_gvariant(&parent_commit);
|
||||||
g_free (tree_type);
|
g_free (tree_type);
|
||||||
if (metadata_mappedf)
|
if (metadata_mappedf)
|
||||||
g_mapped_file_unref (metadata_mappedf);
|
g_mapped_file_unref (metadata_mappedf);
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
echo "1..20"
|
echo "1..21"
|
||||||
|
|
||||||
. libtest.sh
|
. libtest.sh
|
||||||
|
|
||||||
|
|
@ -158,3 +158,9 @@ echo "ok commit from ref"
|
||||||
$OSTREE commit -b trees/test2 -s 'ref with / in it' --tree=ref=test2
|
$OSTREE commit -b trees/test2 -s 'ref with / in it' --tree=ref=test2
|
||||||
echo "ok commit ref with /"
|
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"
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue