repo: Add a --commits option

Show commits for a branch in a similar format
to ostree log. We also show static deltas when
they are available.

Closes: #2156
Approved by: alexlarsson
This commit is contained in:
Matthias Clasen
2018-09-29 23:58:59 -04:00
committed by Atomic Bot
parent 6c6c279730
commit ff91bcf007

View File

@@ -205,14 +205,208 @@ print_metadata (GVariant *meta,
}
}
static gchar *
format_timestamp (guint64 timestamp,
GError **error)
{
GDateTime *dt;
gchar *str;
dt = g_date_time_new_from_unix_utc (timestamp);
if (dt == NULL)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
"Invalid timestamp: %" G_GUINT64_FORMAT, timestamp);
return NULL;
}
str = g_date_time_format (dt, "%Y-%m-%d %H:%M:%S +0000");
g_date_time_unref (dt);
return str;
}
static void
dump_indented_lines (const gchar *data)
{
const char* indent = " ";
const gchar *pos;
for (;;)
{
pos = strchr (data, '\n');
if (pos)
{
g_print ("%s%.*s", indent, (int)(pos + 1 - data), data);
data = pos + 1;
}
else
{
if (data[0] != '\0')
g_print ("%s%s\n", indent, data);
break;
}
}
}
static void
dump_deltas_for_commit (GPtrArray *deltas,
const char *checksum)
{
int i;
gboolean header_printed = FALSE;
if (!deltas)
return;
for (i = 0; i < deltas->len; i++)
{
const char *delta = g_ptr_array_index (deltas, i);
if (g_str_equal (delta, checksum))
{
if (!header_printed)
{
g_print ("Static Deltas:\n");
header_printed = TRUE;
}
g_print (" from scratch\n");
}
else if (strchr (delta, '-'))
{
g_auto(GStrv) parts = g_strsplit (delta, "-", 0);
if (g_str_equal (parts[1], checksum))
{
if (!header_printed)
{
g_print ("Static Deltas:\n");
header_printed = TRUE;
}
g_print (" from %s\n", parts[0]);
}
}
}
if (header_printed)
g_print ("\n");
}
static gboolean
dump_commit (const char *commit,
GVariant *variant,
GPtrArray *deltas,
GError **error)
{
const gchar *subject;
const gchar *body;
guint64 timestamp;
g_autofree char *str = NULL;
/* See OSTREE_COMMIT_GVARIANT_FORMAT */
g_variant_get (variant, "(a{sv}aya(say)&s&stayay)", NULL, NULL, NULL,
&subject, &body, &timestamp, NULL, NULL);
timestamp = GUINT64_FROM_BE (timestamp);
str = format_timestamp (timestamp, error);
if (!str)
return FALSE;
g_print ("Commit: %s\n", commit);
g_print ("Date: %s\n", str);
if (subject[0])
{
g_print ("\n");
dump_indented_lines (subject);
}
else
{
g_print ("(no subject)\n");
}
if (body[0])
{
g_print ("\n");
dump_indented_lines (body);
}
g_print ("\n");
dump_deltas_for_commit (deltas, commit);
return TRUE;
}
static gboolean
log_commit (OstreeRepo *repo,
const char *checksum,
gboolean is_recurse,
GPtrArray *deltas,
GError **error)
{
g_autoptr(GVariant) variant = NULL;
g_autofree char *parent = NULL;
gboolean ret = FALSE;
GError *local_error = NULL;
if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, checksum,
&variant, &local_error))
{
if (is_recurse && g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
{
g_print ("<< History beyond this commit not fetched >>\n");
g_clear_error (&local_error);
ret = TRUE;
}
else
{
g_propagate_error (error, local_error);
}
goto out;
}
if (!dump_commit (checksum, variant, deltas, error))
goto out;
/* Get the parent of this commit */
parent = ostree_commit_get_parent (variant);
if (parent && !log_commit (repo, parent, TRUE, deltas, error))
goto out;
ret = TRUE;
out:
return ret;
}
static gboolean
print_commits (OstreeRepo *repo,
const char *ref,
GError **error)
{
g_autofree char *checksum = NULL;
g_autoptr(GPtrArray) deltas = NULL;
if (!ostree_repo_list_static_delta_names (repo, &deltas, NULL, error))
return FALSE;
if (!ostree_repo_resolve_rev (repo, ref, FALSE, &checksum, error))
return FALSE;
if (!log_commit (repo, checksum, FALSE, deltas, error))
return FALSE;
return TRUE;
}
static gboolean opt_info;
static gboolean opt_branches;
static gchar *opt_metadata_branch;
static gchar *opt_commits_branch;
static GOptionEntry options[] = {
{ "info", 0, 0, G_OPTION_ARG_NONE, &opt_info, N_("Print general information about the repository"), NULL },
{ "branches", 0, 0, G_OPTION_ARG_NONE, &opt_branches, N_("List the branches in the repository"), NULL },
{ "metadata", 0, 0, G_OPTION_ARG_STRING, &opt_metadata_branch, N_("Print metadata for a branch"), N_("BRANCH") },
{ "commits", 0, 0, G_OPTION_ARG_STRING, &opt_commits_branch, N_("Show commits for a branch"), N_("BRANCH") },
{ NULL }
};
@@ -275,7 +469,7 @@ flatpak_builtin_repo (int argc, char **argv,
g_debug ("Using repository metadata from the summary file");
}
if (!opt_info && !opt_branches && !opt_metadata_branch && !opt_size)
if (!opt_info && !opt_branches && !opt_metadata_branch && !opt_commits_branch)
opt_info = TRUE;
/* Print out the metadata. */
@@ -288,6 +482,12 @@ flatpak_builtin_repo (int argc, char **argv,
if (opt_metadata_branch)
print_metadata (meta, opt_metadata_branch);
if (opt_commits_branch)
{
if (!print_commits (repo, opt_commits_branch, error))
return FALSE;
}
return TRUE;
}