gboolean ostree_builtin_checkout (int argc, char **argv, GCancellable *cancellable, GError **error) { GOptionContext *context; glnx_unref_object OstreeRepo *repo = NULL; gboolean ret = FALSE; const char *commit; const char *destination; g_autofree char *resolved_commit = NULL; context = g_option_context_new ("COMMIT [DESTINATION] - Check out a commit into a filesystem tree"); if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) goto out; if (opt_disable_fsync) ostree_repo_set_disable_fsync (repo, TRUE); if (argc < 2) { gchar *help = g_option_context_get_help (context, TRUE, NULL); g_printerr ("%s\n", help); g_free (help); g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "COMMIT must be specified"); goto out; } if (opt_from_stdin || opt_from_file) { destination = argv[1]; if (!process_many_checkouts (repo, destination, cancellable, error)) goto out; } else { commit = argv[1]; if (argc < 3) destination = commit; else destination = argv[2]; if (!ostree_repo_resolve_rev (repo, commit, FALSE, &resolved_commit, error)) goto out; if (!process_one_checkout (repo, resolved_commit, opt_subpath, destination, cancellable, error)) goto out; } ret = TRUE; out: if (context) g_option_context_free (context); return ret; }
static gboolean process_many_checkouts (OstreeRepo *repo, GFile *target, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; gsize len; GError *temp_error = NULL; gs_unref_object GInputStream *instream = NULL; gs_unref_object GDataInputStream *datastream = NULL; gs_free char *revision = NULL; gs_free char *subpath = NULL; gs_free char *resolved_commit = NULL; if (opt_from_stdin) { instream = (GInputStream*)g_unix_input_stream_new (0, FALSE); } else { gs_unref_object GFile *f = g_file_new_for_path (opt_from_file); instream = (GInputStream*)g_file_read (f, cancellable, error); if (!instream) goto out; } datastream = g_data_input_stream_new (instream); while ((revision = g_data_input_stream_read_upto (datastream, "", 1, &len, cancellable, &temp_error)) != NULL) { if (revision[0] == '\0') break; /* Read the null byte */ (void) g_data_input_stream_read_byte (datastream, cancellable, NULL); g_free (subpath); subpath = g_data_input_stream_read_upto (datastream, "", 1, &len, cancellable, &temp_error); if (temp_error) { g_propagate_error (error, temp_error); goto out; } /* Read the null byte */ (void) g_data_input_stream_read_byte (datastream, cancellable, NULL); if (!ostree_repo_resolve_rev (repo, revision, FALSE, &resolved_commit, error)) goto out; if (!process_one_checkout (repo, resolved_commit, subpath, target, cancellable, error)) { g_prefix_error (error, "Processing tree %s: ", resolved_commit); goto out; } g_free (revision); } if (temp_error) { g_propagate_error (error, temp_error); goto out; } ret = TRUE; out: return ret; }