diff --git a/SOURCES/0001-Add-support-for-releasever.patch b/SOURCES/0001-Add-support-for-releasever.patch
new file mode 100644
index 0000000..d1250cf
--- /dev/null
+++ b/SOURCES/0001-Add-support-for-releasever.patch
@@ -0,0 +1,142 @@
+From 95ff60a5f0042ca587d0dad92b8a58f6a56be461 Mon Sep 17 00:00:00 2001
+From: Jaroslav Rohel <jrohel@redhat.com>
+Date: Wed, 10 Apr 2019 16:03:48 +0200
+Subject: [PATCH 1/2] Parse global arguments before context setup
+
+This is a preparation for support more program arguments.
+
+Some settings (eg. dnf_context_set_release_ver(), dnf_context_set_repo_dir())
+must be done before dnf_context_setup() function is called.
+So global arguments must be parsed before dnf_context_setup() is called.
+
+On the other hand there are functions which must be called after
+context setup. -> List of enabled and disabled repositories is stored
+to GSList and used later.
+---
+ dnf/dnf-main.c | 41 ++++++++++++++++++++++++++++-------------
+ 1 file changed, 28 insertions(+), 13 deletions(-)
+
+diff --git a/dnf/dnf-main.c b/dnf/dnf-main.c
+index ef5a04e..ebf429f 100644
+--- a/dnf/dnf-main.c
++++ b/dnf/dnf-main.c
+@@ -30,6 +30,7 @@ static gboolean opt_yes = TRUE;
+ static gboolean opt_nodocs = FALSE;
+ static gboolean show_help = FALSE;
+ static gboolean dl_pkgs_printed = FALSE;
++static GSList *enable_disable_repos = NULL;
+ 
+ static gboolean
+ process_global_option (const gchar  *option_name,
+@@ -40,21 +41,20 @@ process_global_option (const gchar  *option_name,
+   g_autoptr(GError) local_error = NULL;
+   DnfContext *ctx = DNF_CONTEXT (data);
+ 
+-  gboolean ret;
++  gboolean ret = TRUE;
+   if (g_strcmp0 (option_name, "--disablerepo") == 0)
+     {
+-      ret = show_help ? TRUE : dnf_context_repo_disable (ctx, value, &local_error);
++      enable_disable_repos = g_slist_append (enable_disable_repos, g_strconcat("d", value, NULL));
+     }
+   else if (g_strcmp0 (option_name, "--enablerepo") == 0)
+     {
+-      ret = show_help ? TRUE : dnf_context_repo_enable (ctx, value, &local_error);
++      enable_disable_repos = g_slist_append (enable_disable_repos, g_strconcat("e", value, NULL));
+     }
+   else if (g_strcmp0 (option_name, "--setopt") == 0)
+     {
+       if (g_strcmp0 (value, "tsflags=nodocs") == 0)
+         {
+           opt_nodocs = TRUE;
+-          ret = TRUE;
+         }
+       else
+         {
+@@ -235,6 +235,11 @@ main (int   argc,
+ 
+   /*
+    * Parse the global options.
++   */
++  if (!g_option_context_parse (opt_ctx, &argc, &argv, &error))
++    goto out;
++
++  /*
+    * Initialize dnf context only if help is not requested.
+    */
+   if (!show_help)
+@@ -246,14 +251,24 @@ main (int   argc,
+                         G_CALLBACK (state_action_changed_cb),
+                         NULL);
+ 
+-    }
+-  if (!g_option_context_parse (opt_ctx, &argc, &argv, &error))
+-    goto out;
+-  if (!show_help && opt_nodocs)
+-    {
+-      DnfTransaction *txn = dnf_context_get_transaction (ctx);
+-      dnf_transaction_set_flags (txn,
+-                                 dnf_transaction_get_flags (txn) | DNF_TRANSACTION_FLAG_NODOCS);
++      for (GSList * item = enable_disable_repos; item; item = item->next)
++        {
++          gchar * item_data = item->data;
++          int ret;
++          if (item_data[0] == 'd')
++            ret = dnf_context_repo_disable (ctx, item_data+1, &error);
++          else
++            ret = dnf_context_repo_enable (ctx, item_data+1, &error);
++          if (!ret)
++            goto out;
++        }
++
++      if (opt_nodocs)
++        {
++          DnfTransaction *txn = dnf_context_get_transaction (ctx);
++          dnf_transaction_set_flags (txn,
++                                     dnf_transaction_get_flags (txn) | DNF_TRANSACTION_FLAG_NODOCS);
++        }
+     }
+ 
+   /*
+@@ -271,7 +286,7 @@ main (int   argc,
+   if (cmd_name != NULL) --argc;
+ 
+   g_option_context_set_help_enabled (opt_ctx, TRUE);
+-  
++
+   if (cmd_name == NULL && show_help)
+     {
+       g_set_prgname (argv[0]);
+
+From 594f4ae5fdd60215a5010526406a34536472bb30 Mon Sep 17 00:00:00 2001
+From: Jaroslav Rohel <jrohel@redhat.com>
+Date: Thu, 11 Apr 2019 09:56:11 +0200
+Subject: [PATCH 2/2] Add support for --releasever (RhBug:1591627)
+
+---
+ dnf/dnf-main.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/dnf/dnf-main.c b/dnf/dnf-main.c
+index ebf429f..2381f20 100644
+--- a/dnf/dnf-main.c
++++ b/dnf/dnf-main.c
+@@ -50,6 +50,10 @@ process_global_option (const gchar  *option_name,
+     {
+       enable_disable_repos = g_slist_append (enable_disable_repos, g_strconcat("e", value, NULL));
+     }
++  else if (g_strcmp0 (option_name, "--releasever") == 0)
++    {
++      dnf_context_set_release_ver (ctx, value);
++    }
+   else if (g_strcmp0 (option_name, "--setopt") == 0)
+     {
+       if (g_strcmp0 (value, "tsflags=nodocs") == 0)
+@@ -81,6 +85,7 @@ static const GOptionEntry global_opts[] = {
+   { "disablerepo", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option, "Disable repository by an id", "ID" },
+   { "enablerepo", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option, "Enable repository by an id", "ID" },
+   { "nodocs", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_nodocs, "Install packages without docs", NULL },
++  { "releasever", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option, "Override the value of $releasever in config and repo files", "RELEASEVER" },
+   { "setopt", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option, "Set transaction flag, like tsflags=nodocs", "FLAG" },
+   { NULL }
+ };
diff --git a/SOURCES/0002-Fix-minor-memory-leaks-RhBug1702283.patch b/SOURCES/0002-Fix-minor-memory-leaks-RhBug1702283.patch
new file mode 100644
index 0000000..dad7377
--- /dev/null
+++ b/SOURCES/0002-Fix-minor-memory-leaks-RhBug1702283.patch
@@ -0,0 +1,35 @@
+From 854119bb3cd790333cd7ed135fdc5c9cdca1d551 Mon Sep 17 00:00:00 2001
+From: Aleš Matěj <amatej@redhat.com>
+Date: Tue, 28 May 2019 15:07:11 +0200
+Subject: [PATCH] Fix minor memory leaks, RhBug:1702283
+
+---
+ dnf/dnf-utils.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/dnf/dnf-utils.c b/dnf/dnf-utils.c
+index ea067ad..14f1667 100644
+--- a/dnf/dnf-utils.c
++++ b/dnf/dnf-utils.c
+@@ -48,7 +48,9 @@ dnf_utils_add_transaction_packages (struct libscols_table *tb,
+       struct libscols_line *ln = scols_table_new_line (tb, parent);
+       scols_line_set_data (ln, COL_NEVRA, dnf_package_get_nevra (pkg));
+       scols_line_set_data (ln, COL_REPO, dnf_package_get_reponame (pkg));
+-      scols_line_set_data (ln, COL_SIZE, g_format_size (dnf_package_get_size (pkg)));
++      char *formatted_pkg_size = g_format_size (dnf_package_get_size (pkg));
++      scols_line_set_data (ln, COL_SIZE, formatted_pkg_size);
++      g_free(formatted_pkg_size);
+     }
+ }
+ 
+@@ -135,6 +137,7 @@ dnf_utils_print_transaction (DnfContext *ctx)
+     }
+ 
+   scols_print_table (tb);
++  scols_unref_symbols (sb);
+   scols_unref_table (tb);
+ 
+   g_print ("Transaction Summary:\n");
+--
+libgit2 0.27.8
+
diff --git a/SOURCES/0003-use-help2man-to-generate-a-man-page.patch b/SOURCES/0003-use-help2man-to-generate-a-man-page.patch
new file mode 100644
index 0000000..4ef2af5
--- /dev/null
+++ b/SOURCES/0003-use-help2man-to-generate-a-man-page.patch
@@ -0,0 +1,192 @@
+From a8d57daa4b7a98176a98af29e52c1df1295659cb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lhrazky@redhat.com>
+Date: Wed, 20 Feb 2019 17:18:00 +0100
+Subject: [PATCH 1/4] Reformat the commands listing in --help
+
+Use just spaces as a separator to be consistent with dnf, at least two
+spaces are needed so that help2man formats the commands correctly in the
+man page.
+---
+ dnf/dnf-main.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/dnf/dnf-main.c b/dnf/dnf-main.c
+index 2381f20..fd6406d 100644
+--- a/dnf/dnf-main.c
++++ b/dnf/dnf-main.c
+@@ -215,7 +215,11 @@ main (int   argc,
+       if (!peas_engine_load_plugin (engine, info))
+         continue;
+       if (peas_engine_provides_extension (engine, info, DNF_TYPE_COMMAND))
+-        g_string_append_printf (cmd_summary, "\n  %s - %s", peas_plugin_info_get_name (info), peas_plugin_info_get_description (info));
++        /*
++         * At least 2 spaces between the command and its description are needed
++         * so that help2man formats it correctly.
++         */
++        g_string_append_printf (cmd_summary, "\n  %-16s     %s", peas_plugin_info_get_name (info), peas_plugin_info_get_description (info));
+     }
+   g_option_context_set_summary (opt_ctx, cmd_summary->str);
+   g_string_free (cmd_summary, TRUE);
+-- 
+2.24.0
+
+
+From 838a235bba14d48f65ba760f35f32f9d090043fe Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lhrazky@redhat.com>
+Date: Mon, 17 Jun 2019 12:48:13 +0200
+Subject: [PATCH 2/4] Print only the binary name instead of the full path in
+ --help
+
+Removes the directory path from argv[0] for the program name in --help.
+This is required for generating the man page with help2man, as the
+build directory would appear in the man page.
+---
+ dnf/dnf-main.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/dnf/dnf-main.c b/dnf/dnf-main.c
+index fd6406d..e35ace0 100644
+--- a/dnf/dnf-main.c
++++ b/dnf/dnf-main.c
+@@ -298,7 +298,10 @@ main (int   argc,
+ 
+   if (cmd_name == NULL && show_help)
+     {
+-      g_set_prgname (argv[0]);
++      const char *prg_name = strrchr(argv[0], '/') + 1;
++      prg_name = prg_name ? prg_name : argv[0];
++
++      g_set_prgname (prg_name);
+       g_autofree gchar *help = g_option_context_get_help (opt_ctx, TRUE, NULL);
+       g_print ("%s", help);
+       goto out;
+-- 
+2.24.0
+
+
+From b00e2adb2520f11442f3a7cf3710e64f5f60dab2 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lukkash@email.cz>
+Date: Wed, 20 Feb 2019 15:17:33 +0100
+Subject: [PATCH 3/4] Add generating a manpage using help2man to meson.build
+
+Generates a man page using help2man. Note:
+
+- The version in meson.build now needs to be updated on every release,
+  it is used in the man page.
+
+- help2man is a new build dependency.
+
+- Packagers should add the generated man page to packages.
+---
+ dnf/meson.build |  2 +-
+ meson.build     | 21 ++++++++++++++++++++-
+ 2 files changed, 21 insertions(+), 2 deletions(-)
+
+diff --git a/dnf/meson.build b/dnf/meson.build
+index fe37998..f8f1bf3 100644
+--- a/dnf/meson.build
++++ b/dnf/meson.build
+@@ -40,7 +40,7 @@ microdnf_srcs = [
+   'plugins/clean/dnf-command-clean.c',
+ ]
+ 
+-executable(
++microdnf = executable(
+   'microdnf',
+   sources : microdnf_srcs,
+   dependencies : [
+diff --git a/meson.build b/meson.build
+index 1f01ae0..a3601aa 100644
+--- a/meson.build
++++ b/meson.build
+@@ -1,5 +1,5 @@
+ project('microdnf', 'c',
+-        version : '1',
++        version : '3.0.1',
+         license : 'GPL-3.0+',
+         default_options : [
+           'b_asneeded=True',
+@@ -44,3 +44,22 @@ add_project_arguments(
+ )
+ 
+ subdir('dnf')
++
++help2man = find_program('help2man', required: true)
++if help2man.found()
++  help2man_opts = [
++    '--version-string=' + meson.project_version(),
++    '--no-info',
++    '--section=8',
++    '--name=Micro DNF',
++  ]
++
++  custom_target('microdnf.8',
++                output: 'microdnf.8',
++                command: [
++                  help2man, help2man_opts, '--output=@OUTPUT@', microdnf
++                ],
++                install: true,
++                install_dir: get_option('mandir') + '/man8',
++  )
++endif
+-- 
+2.24.0
+
+
+From a1c777a4383ccc5f35396e86e6f3b0a1af92bc7c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lhrazky@redhat.com>
+Date: Mon, 17 Jun 2019 15:10:33 +0200
+Subject: [PATCH 4/4] Add generating a manpage using help2man to CMakeLists.txt
+
+Generates a man page using help2man. Note:
+
+- The version in CMakeLists.txt now needs to be updated on every
+  release, it is used in the man page.
+
+- help2man is a new build dependency.
+
+- Packagers should add the generated man page to packages.
+---
+ CMakeLists.txt | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 435d7e8..dcf8e2f 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -1,5 +1,6 @@
+ cmake_minimum_required (VERSION 2.8.5)
+ project (microdnf C)
++set (PROJECT_VERSION 3.0.1)
+ 
+ list (APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
+ 
+@@ -25,6 +26,25 @@ set (PKG_DATADIR ${CMAKE_INSTALL_FULL_DATADIR}/dnf)
+ add_definitions (-DPACKAGE_LIBDIR="${PKG_LIBDIR}")
+ add_definitions (-DPACKAGE_DATADIR="${PKG_DATADIR}")
+ 
++find_file (HELP2MAN_EXECUTABLE help2man)
++if (NOT HELP2MAN_EXECUTABLE)
++  message (FATAL_ERROR "unable to find help2man")
++endif ()
++
++set (MANPAGE ${CMAKE_CURRENT_BINARY_DIR}/microdnf.8)
++add_custom_command (
++  DEPENDS microdnf
++  OUTPUT ${MANPAGE}
++  COMMAND ${HELP2MAN_EXECUTABLE} $<TARGET_FILE:microdnf>
++  --version-string=${PROJECT_VERSION}
++  --no-info
++  --section=8
++  --name="Micro DNF"
++  --output=${MANPAGE}
++)
++add_custom_target (manpage ALL DEPENDS ${MANPAGE})
++install (FILES ${MANPAGE} DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man8)
++
+ include_directories (${GLIB_INCLUDE_DIRS})
+ include_directories (${GOBJECT_INCLUDE_DIRS})
+ include_directories (${PEAS_INCLUDE_DIRS})
+-- 
+2.24.0
+
diff --git a/SOURCES/0004-Fix-microdnf---help-coredump.patch b/SOURCES/0004-Fix-microdnf---help-coredump.patch
new file mode 100644
index 0000000..845eac4
--- /dev/null
+++ b/SOURCES/0004-Fix-microdnf---help-coredump.patch
@@ -0,0 +1,30 @@
+From 1701ad8ccccae6f8867a862e074ca30f6583e69f Mon Sep 17 00:00:00 2001
+From: Jaroslav Rohel <jrohel@redhat.com>
+Date: Fri, 23 Aug 2019 12:42:42 +0200
+Subject: [PATCH] Fix "microdnf --help" coredump
+
+There was a bug that causes coredump during comand "microdnf --help".
+The bug was in the code that removes the directory path from argv[0]
+(in case argv[0] does not contain '/' character).
+---
+ dnf/dnf-main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/dnf/dnf-main.c b/dnf/dnf-main.c
+index e35ace0..7c71bd0 100644
+--- a/dnf/dnf-main.c
++++ b/dnf/dnf-main.c
+@@ -298,8 +298,8 @@ main (int   argc,
+ 
+   if (cmd_name == NULL && show_help)
+     {
+-      const char *prg_name = strrchr(argv[0], '/') + 1;
+-      prg_name = prg_name ? prg_name : argv[0];
++      const char *prg_name = strrchr(argv[0], '/');
++      prg_name = prg_name ? prg_name + 1 : argv[0];
+ 
+       g_set_prgname (prg_name);
+       g_autofree gchar *help = g_option_context_get_help (opt_ctx, TRUE, NULL);
+-- 
+2.24.0
+
diff --git a/SOURCES/0005-Allow-downgrade-for-all-transactions-microdnf-does-RhBug1725863.patch b/SOURCES/0005-Allow-downgrade-for-all-transactions-microdnf-does-RhBug1725863.patch
new file mode 100644
index 0000000..1c22ec6
--- /dev/null
+++ b/SOURCES/0005-Allow-downgrade-for-all-transactions-microdnf-does-RhBug1725863.patch
@@ -0,0 +1,38 @@
+From a22e544907364467c9206fc196a9e43b684465a2 Mon Sep 17 00:00:00 2001
+From: Aleš Matěj <amatej@redhat.com>
+Date: Tue, 27 Aug 2019 10:54:14 +0200
+Subject: [PATCH] Allow downgrade for all transactions microdnf does (RhBug:1725863)
+
+It can sometimes be necessary to satisfy dependencies or if the user
+wants to specifically downgrade some package.
+---
+ dnf/dnf-main.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/dnf/dnf-main.c b/dnf/dnf-main.c
+index 7c71bd0..693ad7f 100644
+--- a/dnf/dnf-main.c
++++ b/dnf/dnf-main.c
+@@ -272,12 +272,16 @@ main (int   argc,
+             goto out;
+         }
+ 
++      /* allow downgrades for all transaction types */
++      DnfTransaction *txn = dnf_context_get_transaction (ctx);
++      int flags = dnf_transaction_get_flags (txn) | DNF_TRANSACTION_FLAG_ALLOW_DOWNGRADE;
++
+       if (opt_nodocs)
+         {
+-          DnfTransaction *txn = dnf_context_get_transaction (ctx);
+-          dnf_transaction_set_flags (txn,
+-                                     dnf_transaction_get_flags (txn) | DNF_TRANSACTION_FLAG_NODOCS);
++          flags |= DNF_TRANSACTION_FLAG_NODOCS;
+         }
++
++      dnf_transaction_set_flags (txn, flags);
+     }
+ 
+   /*
+--
+libgit2 0.28.2
+
diff --git a/SOURCES/0006-Add-support-of-best-behavior.patch b/SOURCES/0006-Add-support-of-best-behavior.patch
new file mode 100644
index 0000000..6136eac
--- /dev/null
+++ b/SOURCES/0006-Add-support-of-best-behavior.patch
@@ -0,0 +1,186 @@
+From 88602163094d654451a9586121aa8ff6fd7c96b0 Mon Sep 17 00:00:00 2001
+From: Jaroslav Mracek <jmracek@redhat.com>
+Date: Wed, 23 Oct 2019 13:14:45 +0200
+Subject: [PATCH 1/3] Add option best for transactions (RhBug:1679476)
+
+It adds option `--best` plus default is handled from libdnf.conf and
+dnf.conf
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1679476
+---
+ dnf/dnf-main.c                            | 7 ++++++-
+ dnf/plugins/install/dnf-command-install.c | 7 ++++++-
+ dnf/plugins/update/dnf-command-update.c   | 8 ++++++--
+ 3 files changed, 18 insertions(+), 4 deletions(-)
+
+diff --git a/dnf/dnf-main.c b/dnf/dnf-main.c
+index 693ad7f..0dce9b2 100644
+--- a/dnf/dnf-main.c
++++ b/dnf/dnf-main.c
+@@ -28,6 +28,7 @@
+ 
+ static gboolean opt_yes = TRUE;
+ static gboolean opt_nodocs = FALSE;
++static gboolean opt_best = FALSE;
+ static gboolean show_help = FALSE;
+ static gboolean dl_pkgs_printed = FALSE;
+ static GSList *enable_disable_repos = NULL;
+@@ -82,6 +83,7 @@ process_global_option (const gchar  *option_name,
+ 
+ static const GOptionEntry global_opts[] = {
+   { "assumeyes", 'y', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_yes, "Does nothing, we always assume yes", NULL },
++  { "best", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_best, "Try the best available package versions in transactions", NULL },
+   { "disablerepo", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option, "Disable repository by an id", "ID" },
+   { "enablerepo", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option, "Enable repository by an id", "ID" },
+   { "nodocs", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_nodocs, "Install packages without docs", NULL },
+@@ -283,7 +285,10 @@ main (int   argc,
+ 
+       dnf_transaction_set_flags (txn, flags);
+     }
+-
++  if (!show_help && opt_best)
++    {
++        dnf_context_set_best(opt_best);
++    }
+   /*
+    * The first non-option is the command.
+    * Get it and remove it from arguments.
+diff --git a/dnf/plugins/install/dnf-command-install.c b/dnf/plugins/install/dnf-command-install.c
+index ea549da..0b2f5e5 100644
+--- a/dnf/plugins/install/dnf-command-install.c
++++ b/dnf/plugins/install/dnf-command-install.c
+@@ -73,7 +73,12 @@ dnf_command_install_run (DnfCommand      *cmd,
+       if (!dnf_context_install (ctx, *pkg, error))
+         return FALSE;
+     }
+-  if (!dnf_goal_depsolve (dnf_context_get_goal (ctx), DNF_INSTALL, error))
++  DnfGoalActions flags = DNF_INSTALL;
++  if (dnf_context_get_best())
++    {
++      flags |= DNF_FORCE_BEST;
++    }
++  if (!dnf_goal_depsolve (dnf_context_get_goal (ctx), flags, error))
+     return FALSE;
+   if (!dnf_utils_print_transaction (ctx))
+     return TRUE;
+diff --git a/dnf/plugins/update/dnf-command-update.c b/dnf/plugins/update/dnf-command-update.c
+index 652d902..7bf1334 100644
+--- a/dnf/plugins/update/dnf-command-update.c
++++ b/dnf/plugins/update/dnf-command-update.c
+@@ -70,8 +70,12 @@ dnf_command_update_run (DnfCommand      *cmd,
+             return FALSE;
+         }
+     }
+-
+-  if (!dnf_goal_depsolve (dnf_context_get_goal (ctx), 0, error))
++  DnfGoalActions flags = 0;
++  if (dnf_context_get_best())
++    {
++      flags |= DNF_FORCE_BEST;
++    }
++  if (!dnf_goal_depsolve (dnf_context_get_goal (ctx), flags, error))
+     return FALSE;
+   if (!dnf_utils_print_transaction (ctx))
+     return TRUE;
+-- 
+2.21.0
+
+
+From 6a4a490d368fc7982264f8ab898e4bd195576b30 Mon Sep 17 00:00:00 2001
+From: Jaroslav Mracek <jmracek@redhat.com>
+Date: Wed, 23 Oct 2019 13:15:17 +0200
+Subject: [PATCH 2/3] Initialized to use tito.
+
+---
+ .tito/packages/.readme | 3 +++
+ .tito/tito.props       | 5 +++++
+ 2 files changed, 8 insertions(+)
+ create mode 100644 .tito/packages/.readme
+ create mode 100644 .tito/tito.props
+
+diff --git a/.tito/packages/.readme b/.tito/packages/.readme
+new file mode 100644
+index 0000000..b9411e2
+--- /dev/null
++++ b/.tito/packages/.readme
+@@ -0,0 +1,3 @@
++the .tito/packages directory contains metadata files
++named after their packages. Each file has the latest tagged
++version and the project's relative directory.
+diff --git a/.tito/tito.props b/.tito/tito.props
+new file mode 100644
+index 0000000..eab3f19
+--- /dev/null
++++ b/.tito/tito.props
+@@ -0,0 +1,5 @@
++[buildconfig]
++builder = tito.builder.Builder
++tagger = tito.tagger.VersionTagger
++changelog_do_not_remove_cherrypick = 0
++changelog_format = %s (%ae)
+-- 
+2.21.0
+
+
+From 4af6a4c76e7bce0ce06188319b0b4c21a235266c Mon Sep 17 00:00:00 2001
+From: Jaroslav Mracek <jmracek@redhat.com>
+Date: Wed, 23 Oct 2019 15:07:55 +0200
+Subject: [PATCH 3/3] Add option --nobest
+
+It is used to overwrite configuration of best option. It is useful when
+best=True is default.
+---
+ dnf/dnf-main.c | 22 ++++++++++++++++++----
+ 1 file changed, 18 insertions(+), 4 deletions(-)
+
+diff --git a/dnf/dnf-main.c b/dnf/dnf-main.c
+index 0dce9b2..4f19489 100644
+--- a/dnf/dnf-main.c
++++ b/dnf/dnf-main.c
+@@ -29,6 +29,7 @@
+ static gboolean opt_yes = TRUE;
+ static gboolean opt_nodocs = FALSE;
+ static gboolean opt_best = FALSE;
++static gboolean opt_nobest = FALSE;
+ static gboolean show_help = FALSE;
+ static gboolean dl_pkgs_printed = FALSE;
+ static GSList *enable_disable_repos = NULL;
+@@ -86,6 +87,7 @@ static const GOptionEntry global_opts[] = {
+   { "best", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_best, "Try the best available package versions in transactions", NULL },
+   { "disablerepo", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option, "Disable repository by an id", "ID" },
+   { "enablerepo", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option, "Enable repository by an id", "ID" },
++  { "nobest", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_nobest, "Do not limit the transaction to the best candidates", NULL },
+   { "nodocs", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_nodocs, "Install packages without docs", NULL },
+   { "releasever", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option, "Override the value of $releasever in config and repo files", "RELEASEVER" },
+   { "setopt", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, process_global_option, "Set transaction flag, like tsflags=nodocs", "FLAG" },
+@@ -284,11 +286,23 @@ main (int   argc,
+         }
+ 
+       dnf_transaction_set_flags (txn, flags);
++      if (opt_best && opt_nobest)
++        {
++          error = g_error_new_literal(G_OPTION_ERROR,
++                                      G_OPTION_ERROR_BAD_VALUE,
++                                      "Argument --nobest is not allowed with argument --best");
++          goto out;
++        }
++      if (opt_best)
++        {
++          dnf_context_set_best(TRUE);
++        }
++      else if (opt_nobest)
++        {
++          dnf_context_set_best(FALSE);
++        }
+     }
+-  if (!show_help && opt_best)
+-    {
+-        dnf_context_set_best(opt_best);
+-    }
++
+   /*
+    * The first non-option is the command.
+    * Get it and remove it from arguments.
+-- 
+2.21.0
+
diff --git a/SOURCES/0007-Add-repolist-command-RhBug1584952.patch b/SOURCES/0007-Add-repolist-command-RhBug1584952.patch
new file mode 100644
index 0000000..a74ff5f
--- /dev/null
+++ b/SOURCES/0007-Add-repolist-command-RhBug1584952.patch
@@ -0,0 +1,312 @@
+From 83f282853e22fe3146b86b33bdaebb7a22b0a580 Mon Sep 17 00:00:00 2001
+From: Jaroslav Rohel <jrohel@redhat.com>
+Date: Thu, 7 Nov 2019 21:34:38 +0100
+Subject: [PATCH] Add repolist command (RhBug:1584952)
+
+The command lists repositories.
+
+Command options:
+  --all        show all repositories
+  --disabled   show disabled repositories
+  --enabled    show enabled repositories (default)
+
+Signed-off-by: Jaroslav Rohel <jrohel@redhat.com>
+---
+ dnf/CMakeLists.txt                                      |   6 ++++++
+ dnf/meson.build                                         |   9 +++++++++
+ dnf/plugins/repolist/dnf-command-repolist.c             | 167 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ dnf/plugins/repolist/dnf-command-repolist.gresource.xml |   6 ++++++
+ dnf/plugins/repolist/dnf-command-repolist.h             |  33 +++++++++++++++++++++++++++++++++
+ dnf/plugins/repolist/repolist.plugin                    |   9 +++++++++
+ 6 files changed, 230 insertions(+)
+ create mode 100644 dnf/plugins/repolist/dnf-command-repolist.c
+ create mode 100644 dnf/plugins/repolist/dnf-command-repolist.gresource.xml
+ create mode 100644 dnf/plugins/repolist/dnf-command-repolist.h
+ create mode 100644 dnf/plugins/repolist/repolist.plugin
+
+diff --git a/dnf/CMakeLists.txt b/dnf/CMakeLists.txt
+index 04d5b17..eb73c11 100644
+--- a/dnf/CMakeLists.txt
++++ b/dnf/CMakeLists.txt
+@@ -15,6 +15,11 @@ glib_compile_resources (DNF_COMMAND_UPDATE plugins/update/dnf-command-update.gre
+                         INTERNAL)
+ list (APPEND DNF_COMMAND_UPDATE "plugins/update/dnf-command-update.c")
+ 
++glib_compile_resources (DNF_COMMAND_REPOLIST plugins/repolist/dnf-command-repolist.gresource.xml
++                        C_PREFIX dnf_command_repolist
++                        INTERNAL)
++list (APPEND DNF_COMMAND_REPOLIST "plugins/repolist/dnf-command-repolist.c")
++
+ glib_compile_resources (DNF_COMMAND_CLEAN plugins/clean/dnf-command-clean.gresource.xml
+                         C_PREFIX dnf_command_clean
+                         INTERNAL)
+@@ -25,6 +30,7 @@ add_executable (microdnf dnf-main.c ${DNF_SRCS}
+                 ${DNF_COMMAND_INSTALL}
+                 ${DNF_COMMAND_REMOVE}
+                 ${DNF_COMMAND_UPDATE}
++                ${DNF_COMMAND_REPOLIST}
+                 ${DNF_COMMAND_CLEAN})
+ 
+ target_link_libraries (microdnf
+diff --git a/dnf/meson.build b/dnf/meson.build
+index f8f1bf3..d368180 100644
+--- a/dnf/meson.build
++++ b/dnf/meson.build
+@@ -30,6 +30,15 @@ microdnf_srcs = [
+   ),
+   'plugins/update/dnf-command-update.c',
+ 
++  # repolist
++  gnome.compile_resources(
++    'dnf-repolist',
++    'plugins/repolist/dnf-command-repolist.gresource.xml',
++    c_name : 'dnf_command_repolist',
++    source_dir : 'plugins/repolist',
++  ),
++  'plugins/repolist/dnf-command-repolist.c',
++
+   # clean
+   gnome.compile_resources(
+     'dnf-clean',
+diff --git a/dnf/plugins/repolist/dnf-command-repolist.c b/dnf/plugins/repolist/dnf-command-repolist.c
+new file mode 100644
+index 0000000..f69917e
+--- /dev/null
++++ b/dnf/plugins/repolist/dnf-command-repolist.c
+@@ -0,0 +1,167 @@
++/*
++ * Copyright (C) 2019 Red Hat, Inc.
++ *
++ * Licensed under the GNU Lesser General Public License Version 2.1
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include "dnf-command-repolist.h"
++
++#include <libsmartcols.h>
++#include <unistd.h>
++
++struct _DnfCommandRepolist
++{
++  PeasExtensionBase parent_instance;
++};
++
++static void dnf_command_repolist_iface_init (DnfCommandInterface *iface);
++
++G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandRepolist,
++                                dnf_command_repolist,
++                                PEAS_TYPE_EXTENSION_BASE,
++                                0,
++                                G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
++                                                       dnf_command_repolist_iface_init))
++
++static void
++dnf_command_repolist_init (DnfCommandRepolist *self)
++{
++}
++
++// repository list table columns
++enum { COL_REPO_ID, COL_REPO_NAME, COL_REPO_STATUS };
++
++static struct libscols_table *
++create_repolist_table (gboolean with_status)
++{
++  struct libscols_table *table = scols_new_table ();
++  if (isatty (1))
++    scols_table_enable_colors (table, 1);
++  scols_table_enable_maxout (table, 1);
++  struct libscols_column *cl = scols_table_new_column (table, "repo id", 0.4, 0);
++  scols_column_set_cmpfunc(cl, scols_cmpstr_cells, NULL);
++  scols_table_new_column (table, "repo name", 0.5, SCOLS_FL_TRUNC);
++  if (with_status)
++    scols_table_new_column (table, "status", 0.1, SCOLS_FL_RIGHT);
++  return table;
++}
++
++static void
++add_line_into_table (struct libscols_table *table,
++                     gboolean               with_status,
++                     const char            *id,
++                     const char            *descr,
++                     gboolean               enabled)
++{
++  struct libscols_line *ln = scols_table_new_line (table, NULL);
++  scols_line_set_data (ln, COL_REPO_ID, id);
++  scols_line_set_data (ln, COL_REPO_NAME, descr);
++  if (with_status)
++    {
++      scols_line_set_data (ln, COL_REPO_STATUS, enabled ? "enabled" : "disabled");
++      struct libscols_cell * cl = scols_line_get_cell (ln, COL_REPO_STATUS);
++      scols_cell_set_color (cl, enabled ? "green" : "red");
++    }
++}
++
++static gboolean
++dnf_command_repolist_run (DnfCommand      *cmd,
++                          int              argc,
++                          char            *argv[],
++                          GOptionContext  *opt_ctx,
++                          DnfContext      *ctx,
++                          GError         **error)
++{
++  gboolean opt_all = FALSE;
++  gboolean opt_enabled = FALSE;
++  gboolean opt_disabled = FALSE;
++  g_auto(GStrv) opt_repos = NULL;
++  const GOptionEntry opts[] = {
++    { "all", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_all, "show all repos", NULL },
++    { "disabled", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_disabled, "show disabled repos", NULL },
++    { "enabled", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_enabled, "show enabled repos (default)", NULL },
++    { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &opt_repos, NULL, NULL },
++    { NULL }
++  };
++  g_option_context_add_main_entries (opt_ctx, opts, NULL);
++
++  if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
++    return FALSE;
++
++  if (opt_repos && opt_repos[0])
++    {
++      g_set_error (error,
++                   G_OPTION_ERROR,
++                   G_OPTION_ERROR_UNKNOWN_OPTION,
++                   "Unknown argument %s", opt_repos[0]);
++      return FALSE;
++    }
++
++  if (!opt_disabled)
++    opt_enabled = TRUE;
++
++  if (opt_enabled && opt_disabled)
++    opt_all = TRUE;
++
++  struct libscols_table *table = create_repolist_table (opt_all);
++
++  GPtrArray *repos = dnf_context_get_repos (ctx);
++  for (guint i = 0; i < repos->len; ++i)
++    {
++      DnfRepo * repo = g_ptr_array_index (repos, i);
++      gboolean enabled = dnf_repo_get_enabled (repo) & DNF_REPO_ENABLED_PACKAGES;
++      if (opt_all || (opt_enabled && enabled) || (opt_disabled && !enabled))
++        {
++          const gchar * id = dnf_repo_get_id (repo);
++          g_autofree gchar * descr = dnf_repo_get_description (repo);
++          add_line_into_table (table, opt_all, id, descr, enabled);
++        }
++    }
++
++  struct libscols_column *cl = scols_table_get_column (table, COL_REPO_ID);
++  scols_sort_table (table, cl);
++  scols_print_table (table);
++  scols_unref_table (table);
++
++  return TRUE;
++}
++
++static void
++dnf_command_repolist_class_init (DnfCommandRepolistClass *klass)
++{
++}
++
++static void
++dnf_command_repolist_iface_init (DnfCommandInterface *iface)
++{
++  iface->run = dnf_command_repolist_run;
++}
++
++static void
++dnf_command_repolist_class_finalize (DnfCommandRepolistClass *klass)
++{
++}
++
++G_MODULE_EXPORT void
++dnf_command_repolist_register_types (PeasObjectModule *module)
++{
++  dnf_command_repolist_register_type (G_TYPE_MODULE (module));
++
++  peas_object_module_register_extension_type (module,
++                                              DNF_TYPE_COMMAND,
++                                              DNF_TYPE_COMMAND_REPOLIST);
++}
+diff --git a/dnf/plugins/repolist/dnf-command-repolist.gresource.xml b/dnf/plugins/repolist/dnf-command-repolist.gresource.xml
+new file mode 100644
+index 0000000..0d12b8b
+--- /dev/null
++++ b/dnf/plugins/repolist/dnf-command-repolist.gresource.xml
+@@ -0,0 +1,6 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<gresources>
++  <gresource prefix="/org/fedoraproject/dnf/plugins/repolist">
++    <file>repolist.plugin</file>
++  </gresource>
++</gresources>
+diff --git a/dnf/plugins/repolist/dnf-command-repolist.h b/dnf/plugins/repolist/dnf-command-repolist.h
+new file mode 100644
+index 0000000..5edaf1c
+--- /dev/null
++++ b/dnf/plugins/repolist/dnf-command-repolist.h
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (C) 2019 Red Hat, Inc.
++ *
++ * Licensed under the GNU Lesser General Public License Version 2.1
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#pragma once
++
++#include "dnf-command.h"
++#include <libpeas/peas.h>
++
++G_BEGIN_DECLS
++
++#define DNF_TYPE_COMMAND_REPOLIST dnf_command_repolist_get_type ()
++G_DECLARE_FINAL_TYPE (DnfCommandRepolist, dnf_command_repolist, DNF, COMMAND_REPOLIST, PeasExtensionBase)
++
++G_MODULE_EXPORT void dnf_command_repolist_register_types (PeasObjectModule *module);
++
++G_END_DECLS
+diff --git a/dnf/plugins/repolist/repolist.plugin b/dnf/plugins/repolist/repolist.plugin
+new file mode 100644
+index 0000000..c659a1e
+--- /dev/null
++++ b/dnf/plugins/repolist/repolist.plugin
+@@ -0,0 +1,9 @@
++[Plugin]
++Module = command_repolist
++Embedded = dnf_command_repolist_register_types
++Name = repolist
++Description = List repositories
++Authors = Jaroslav Rohel <jrohel@redhat.com>
++License = GPL-3.0+
++Copyright = Copyright (C) 2019 Red Hat, Inc.
++X-Command-Syntax = repolist [--all] [--disabled] [--enabled]
+--
+libgit2 0.28.2
+
diff --git a/SOURCES/0008-Add-repoquery-command.patch b/SOURCES/0008-Add-repoquery-command.patch
new file mode 100644
index 0000000..1e71e10
--- /dev/null
+++ b/SOURCES/0008-Add-repoquery-command.patch
@@ -0,0 +1,431 @@
+From 1ded5d5babfe620488aa8965c7fb922361fa6eaa Mon Sep 17 00:00:00 2001
+From: Jaroslav Rohel <jrohel@redhat.com>
+Date: Fri, 8 Nov 2019 13:27:17 +0100
+Subject: [PATCH 1/2] Add repoquery command (RhBug:1769245)
+
+Searches for selected packages and displays the requested information
+about them.
+
+Command options:
+  --available   display available packages (default)
+  --installed   display installed packages
+
+Signed-off-by: Jaroslav Rohel <jrohel@redhat.com>
+---
+ dnf/CMakeLists.txt                            |   6 +
+ dnf/meson.build                               |   9 +
+ dnf/plugins/repoquery/dnf-command-repoquery.c | 158 ++++++++++++++++++
+ .../dnf-command-repoquery.gresource.xml       |   6 +
+ dnf/plugins/repoquery/dnf-command-repoquery.h |  33 ++++
+ dnf/plugins/repoquery/repoquery.plugin        |   9 +
+ 6 files changed, 221 insertions(+)
+ create mode 100644 dnf/plugins/repoquery/dnf-command-repoquery.c
+ create mode 100644 dnf/plugins/repoquery/dnf-command-repoquery.gresource.xml
+ create mode 100644 dnf/plugins/repoquery/dnf-command-repoquery.h
+ create mode 100644 dnf/plugins/repoquery/repoquery.plugin
+
+diff --git a/dnf/CMakeLists.txt b/dnf/CMakeLists.txt
+index eb73c11..2585c06 100644
+--- a/dnf/CMakeLists.txt
++++ b/dnf/CMakeLists.txt
+@@ -20,6 +20,11 @@ glib_compile_resources (DNF_COMMAND_REPOLIST plugins/repolist/dnf-command-repoli
+                         INTERNAL)
+ list (APPEND DNF_COMMAND_REPOLIST "plugins/repolist/dnf-command-repolist.c")
+ 
++glib_compile_resources (DNF_COMMAND_REPOQUERY plugins/repoquery/dnf-command-repoquery.gresource.xml
++                        C_PREFIX dnf_command_repoquery
++                        INTERNAL)
++list (APPEND DNF_COMMAND_REPOQUERY "plugins/repoquery/dnf-command-repoquery.c")
++
+ glib_compile_resources (DNF_COMMAND_CLEAN plugins/clean/dnf-command-clean.gresource.xml
+                         C_PREFIX dnf_command_clean
+                         INTERNAL)
+@@ -31,6 +36,7 @@ add_executable (microdnf dnf-main.c ${DNF_SRCS}
+                 ${DNF_COMMAND_REMOVE}
+                 ${DNF_COMMAND_UPDATE}
+                 ${DNF_COMMAND_REPOLIST}
++                ${DNF_COMMAND_REPOQUERY}
+                 ${DNF_COMMAND_CLEAN})
+ 
+ target_link_libraries (microdnf
+diff --git a/dnf/meson.build b/dnf/meson.build
+index d368180..d71a533 100644
+--- a/dnf/meson.build
++++ b/dnf/meson.build
+@@ -39,6 +39,15 @@ microdnf_srcs = [
+   ),
+   'plugins/repolist/dnf-command-repolist.c',
+ 
++  # repoquery
++  gnome.compile_resources(
++    'dnf-repoquery',
++    'plugins/repoquery/dnf-command-repoquery.gresource.xml',
++    c_name : 'dnf_command_repoquery',
++    source_dir : 'plugins/repoquery',
++  ),
++  'plugins/repoquery/dnf-command-repoquery.c',
++
+   # clean
+   gnome.compile_resources(
+     'dnf-clean',
+diff --git a/dnf/plugins/repoquery/dnf-command-repoquery.c b/dnf/plugins/repoquery/dnf-command-repoquery.c
+new file mode 100644
+index 0000000..7db1a8f
+--- /dev/null
++++ b/dnf/plugins/repoquery/dnf-command-repoquery.c
+@@ -0,0 +1,158 @@
++/*
++ * Copyright (C) 2019 Red Hat, Inc.
++ *
++ * Licensed under the GNU Lesser General Public License Version 2.1
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include "dnf-command-repoquery.h"
++
++struct _DnfCommandRepoquery
++{
++  PeasExtensionBase parent_instance;
++};
++
++static void dnf_command_repoquery_iface_init (DnfCommandInterface *iface);
++
++G_DEFINE_DYNAMIC_TYPE_EXTENDED (DnfCommandRepoquery,
++                                dnf_command_repoquery,
++                                PEAS_TYPE_EXTENSION_BASE,
++                                0,
++                                G_IMPLEMENT_INTERFACE (DNF_TYPE_COMMAND,
++                                                       dnf_command_repoquery_iface_init))
++
++static void
++dnf_command_repoquery_init (DnfCommandRepoquery *self)
++{
++}
++
++static void
++disable_available_repos (DnfContext *ctx)
++{
++  GPtrArray *repos = dnf_context_get_repos (ctx);
++  for (guint i = 0; i < repos->len; ++i)
++    {
++      DnfRepo * repo = g_ptr_array_index (repos, i);
++      dnf_repo_set_enabled (repo, DNF_REPO_ENABLED_NONE);
++    }
++}
++
++static gint
++gptrarr_dnf_package_cmp (gconstpointer a, gconstpointer b)
++{
++  return dnf_package_cmp(*(DnfPackage**)a, *(DnfPackage**)b);
++}
++
++static gboolean
++dnf_command_repoquery_run (DnfCommand     *cmd,
++                          int              argc,
++                          char            *argv[],
++                          GOptionContext  *opt_ctx,
++                          DnfContext      *ctx,
++                          GError         **error)
++{
++  gboolean opt_available = FALSE;
++  gboolean opt_installed = FALSE;
++  g_auto(GStrv) opt_key = NULL;
++  const GOptionEntry opts[] = {
++    { "available", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_available, "display available packages (default)", NULL },
++    { "installed", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_installed, "display installed packages", NULL },
++    { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &opt_key, NULL, NULL },
++    { NULL }
++  };
++  g_option_context_add_main_entries (opt_ctx, opts, NULL);
++
++  if (!g_option_context_parse (opt_ctx, &argc, &argv, error))
++    return FALSE;
++
++  // --available is default (compatibility with YUM/DNF)
++  if (!opt_available && !opt_installed)
++    opt_available = TRUE;
++
++  if (opt_available && opt_installed)
++    opt_available = opt_installed = FALSE;
++
++  if (opt_installed)
++    disable_available_repos (ctx);
++
++  DnfState * state = dnf_context_get_state (ctx);
++  DnfContextSetupSackFlags sack_flags = opt_available ? DNF_CONTEXT_SETUP_SACK_FLAG_SKIP_RPMDB
++                                                      : DNF_CONTEXT_SETUP_SACK_FLAG_NONE;
++  dnf_context_setup_sack_with_flags (ctx, state, sack_flags, error);
++  DnfSack *sack = dnf_context_get_sack (ctx);
++
++  hy_autoquery HyQuery query = hy_query_create (sack);
++
++  if (opt_key)
++    {
++      hy_query_filter_empty (query);
++      for (char **pkey = opt_key; *pkey; ++pkey)
++        {
++          g_auto(HySubject) subject = hy_subject_create (*pkey);
++          HyNevra out_nevra;
++          hy_autoquery HyQuery key_query = hy_subject_get_best_solution (subject, sack, NULL,
++            &out_nevra, TRUE, TRUE, FALSE, TRUE, TRUE);
++          if (out_nevra)
++            hy_nevra_free(out_nevra);
++          hy_query_union (query, key_query);
++        }
++    }
++
++  g_autoptr(GPtrArray) pkgs = hy_query_run (query);
++
++  g_ptr_array_sort (pkgs, gptrarr_dnf_package_cmp);
++
++  // print packages without duplicated lines
++  const char *prev_line = "";
++  for (guint i = 0; i < pkgs->len; ++i)
++    {
++      DnfPackage *package = g_ptr_array_index (pkgs, i);
++      const char * line = dnf_package_get_nevra (package);
++      if (strcmp (line, prev_line) != 0)
++        {
++          g_print ("%s\n", line);
++          prev_line = line;
++        }
++    }
++
++  return TRUE;
++}
++
++static void
++dnf_command_repoquery_class_init (DnfCommandRepoqueryClass *klass)
++{
++}
++
++static void
++dnf_command_repoquery_iface_init (DnfCommandInterface *iface)
++{
++  iface->run = dnf_command_repoquery_run;
++}
++
++static void
++dnf_command_repoquery_class_finalize (DnfCommandRepoqueryClass *klass)
++{
++}
++
++G_MODULE_EXPORT void
++dnf_command_repoquery_register_types (PeasObjectModule *module)
++{
++  dnf_command_repoquery_register_type (G_TYPE_MODULE (module));
++
++  peas_object_module_register_extension_type (module,
++                                              DNF_TYPE_COMMAND,
++                                              DNF_TYPE_COMMAND_REPOQUERY);
++}
+diff --git a/dnf/plugins/repoquery/dnf-command-repoquery.gresource.xml b/dnf/plugins/repoquery/dnf-command-repoquery.gresource.xml
+new file mode 100644
+index 0000000..6765af2
+--- /dev/null
++++ b/dnf/plugins/repoquery/dnf-command-repoquery.gresource.xml
+@@ -0,0 +1,6 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<gresources>
++  <gresource prefix="/org/fedoraproject/dnf/plugins/repoquery">
++    <file>repoquery.plugin</file>
++  </gresource>
++</gresources>
+diff --git a/dnf/plugins/repoquery/dnf-command-repoquery.h b/dnf/plugins/repoquery/dnf-command-repoquery.h
+new file mode 100644
+index 0000000..80fae53
+--- /dev/null
++++ b/dnf/plugins/repoquery/dnf-command-repoquery.h
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (C) 2019 Red Hat, Inc.
++ *
++ * Licensed under the GNU Lesser General Public License Version 2.1
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#pragma once
++
++#include "dnf-command.h"
++#include <libpeas/peas.h>
++
++G_BEGIN_DECLS
++
++#define DNF_TYPE_COMMAND_REPOQUERY dnf_command_repoquery_get_type ()
++G_DECLARE_FINAL_TYPE (DnfCommandRepoquery, dnf_command_repoquery, DNF, COMMAND_REPOQUERY, PeasExtensionBase)
++
++G_MODULE_EXPORT void dnf_command_repoquery_register_types (PeasObjectModule *module);
++
++G_END_DECLS
+diff --git a/dnf/plugins/repoquery/repoquery.plugin b/dnf/plugins/repoquery/repoquery.plugin
+new file mode 100644
+index 0000000..a107720
+--- /dev/null
++++ b/dnf/plugins/repoquery/repoquery.plugin
+@@ -0,0 +1,9 @@
++[Plugin]
++Module = command_repoquery
++Embedded = dnf_command_repoquery_register_types
++Name = repoquery
++Description = Search for packages matching keyword
++Authors = Jaroslav Rohel <jrohel@redhat.com>
++License = GPL-3.0+
++Copyright = Copyright (C) 2019 Red Hat, Inc.
++X-Command-Syntax = repoquery [OPTION…] [KEY…]
+-- 
+2.21.0
+
+
+From 99831d883f2a95f3540a844fe8455f896b9b097d Mon Sep 17 00:00:00 2001
+From: Jaroslav Rohel <jrohel@redhat.com>
+Date: Sun, 10 Nov 2019 15:32:31 +0100
+Subject: [PATCH 2/2] [repoquery] add "--info" and "--nevra" options
+
+--info   show detailed information about the packages
+--nevra  use name-epoch:version-release.architecture format
+         for displaying packages (default)
+
+Signed-off-by: Jaroslav Rohel <jrohel@redhat.com>
+---
+ dnf/plugins/repoquery/dnf-command-repoquery.c | 68 +++++++++++++++++--
+ 1 file changed, 63 insertions(+), 5 deletions(-)
+
+diff --git a/dnf/plugins/repoquery/dnf-command-repoquery.c b/dnf/plugins/repoquery/dnf-command-repoquery.c
+index 7db1a8f..721c990 100644
+--- a/dnf/plugins/repoquery/dnf-command-repoquery.c
++++ b/dnf/plugins/repoquery/dnf-command-repoquery.c
+@@ -20,6 +20,8 @@
+ 
+ #include "dnf-command-repoquery.h"
+ 
++#include <libsmartcols.h>
++
+ struct _DnfCommandRepoquery
+ {
+   PeasExtensionBase parent_instance;
+@@ -56,6 +58,49 @@ gptrarr_dnf_package_cmp (gconstpointer a, gconstpointer b)
+   return dnf_package_cmp(*(DnfPackage**)a, *(DnfPackage**)b);
+ }
+ 
++static void
++package_info_add_line (struct libscols_table *table, const char *key, const char *value)
++{
++  struct libscols_line *ln = scols_table_new_line (table, NULL);
++  scols_line_set_data (ln, 0, key);
++  scols_line_set_data (ln, 1, value);
++}
++
++static void
++print_package_info (DnfPackage *package)
++{
++  struct libscols_table *table = scols_new_table ();
++  scols_table_enable_noheadings (table, 1);
++  scols_table_set_column_separator (table, " : ");
++  scols_table_new_column (table, "key", 5, 0);
++  struct libscols_column *cl = scols_table_new_column (table, "value", 10, SCOLS_FL_WRAP);
++  scols_column_set_safechars (cl, "\n");
++  scols_column_set_wrapfunc (cl, scols_wrapnl_chunksize, scols_wrapnl_nextchunk, NULL);
++
++  package_info_add_line (table, "Name", dnf_package_get_name (package));
++  guint64 epoch = dnf_package_get_epoch (package);
++  if (epoch != 0)
++    {
++      g_autofree gchar *str_epoch = g_strdup_printf ("%ld", epoch);
++      package_info_add_line (table, "Epoch", str_epoch);
++    }
++  package_info_add_line (table, "Version", dnf_package_get_version (package));
++  package_info_add_line (table, "Release", dnf_package_get_release (package));
++  package_info_add_line (table, "Architecture", dnf_package_get_arch (package));
++  g_autofree gchar *size = g_format_size_full (dnf_package_get_size (package),
++                                               G_FORMAT_SIZE_LONG_FORMAT | G_FORMAT_SIZE_IEC_UNITS);
++  package_info_add_line (table, "Size", size);
++  package_info_add_line (table, "Source", dnf_package_get_sourcerpm (package));
++  package_info_add_line (table, "Repository", dnf_package_get_reponame (package));
++  package_info_add_line (table, "Summanry", dnf_package_get_summary (package));
++  package_info_add_line (table, "URL", dnf_package_get_url (package));
++  package_info_add_line (table, "License", dnf_package_get_license (package));
++  package_info_add_line (table, "Description", dnf_package_get_description (package));
++
++  scols_print_table (table);
++  scols_unref_table (table);
++}
++
+ static gboolean
+ dnf_command_repoquery_run (DnfCommand     *cmd,
+                           int              argc,
+@@ -65,11 +110,16 @@ dnf_command_repoquery_run (DnfCommand     *cmd,
+                           GError         **error)
+ {
+   gboolean opt_available = FALSE;
++  gboolean opt_info = FALSE;
+   gboolean opt_installed = FALSE;
++  gboolean opt_nevra = FALSE;
+   g_auto(GStrv) opt_key = NULL;
+   const GOptionEntry opts[] = {
+     { "available", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_available, "display available packages (default)", NULL },
++    { "info", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_info, "show detailed information about the packages", NULL },
+     { "installed", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_installed, "display installed packages", NULL },
++    { "nevra", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_nevra,
++      "use name-epoch:version-release.architecture format for displaying packages (default)", NULL },
+     { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &opt_key, NULL, NULL },
+     { NULL }
+   };
+@@ -115,16 +165,24 @@ dnf_command_repoquery_run (DnfCommand     *cmd,
+ 
+   g_ptr_array_sort (pkgs, gptrarr_dnf_package_cmp);
+ 
+-  // print packages without duplicated lines
+   const char *prev_line = "";
+   for (guint i = 0; i < pkgs->len; ++i)
+     {
+       DnfPackage *package = g_ptr_array_index (pkgs, i);
+-      const char * line = dnf_package_get_nevra (package);
+-      if (strcmp (line, prev_line) != 0)
++      if (opt_nevra || !opt_info)
++        {
++          const char * line = dnf_package_get_nevra (package);
++          // print nevras without duplicated lines
++          if (opt_info || strcmp (line, prev_line) != 0)
++            {
++              g_print ("%s\n", line);
++              prev_line = line;
++            }
++        }
++      if (opt_info)
+         {
+-          g_print ("%s\n", line);
+-          prev_line = line;
++          print_package_info (package);
++          g_print ("\n");
+         }
+     }
+ 
+-- 
+2.21.0
+
diff --git a/SPECS/microdnf.spec b/SPECS/microdnf.spec
index 75a27b9..75f8e56 100644
--- a/SPECS/microdnf.spec
+++ b/SPECS/microdnf.spec
@@ -1,19 +1,32 @@
+%global libdnf_version 0.38.0
+
 Name:           microdnf
 Version:        3.0.1
-Release:        1%{?dist}
+Release:        7%{?dist}
 Summary:        Micro DNF
 
 License:        GPLv3+
 URL:            https://github.com/rpm-software-management/microdnf
 Source0:        %{url}/archive/v%{version}/%{name}-%{version}.tar.gz
+Patch1:         0001-Add-support-for-releasever.patch
+Patch2:         0002-Fix-minor-memory-leaks-RhBug1702283.patch
+Patch3:         0003-use-help2man-to-generate-a-man-page.patch
+Patch4:         0004-Fix-microdnf---help-coredump.patch
+Patch5:         0005-Allow-downgrade-for-all-transactions-microdnf-does-RhBug1725863.patch
+Patch6:         0006-Add-support-of-best-behavior.patch
+Patch7:         0007-Add-repolist-command-RhBug1584952.patch
+Patch8:         0008-Add-repoquery-command.patch
 
 BuildRequires:  gcc
 BuildRequires:  meson >= 0.36.0
 BuildRequires:  pkgconfig(glib-2.0) >= 2.44.0
 BuildRequires:  pkgconfig(gobject-2.0) >= 2.44.0
 BuildRequires:  pkgconfig(libpeas-1.0) >= 1.20.0
-BuildRequires:  pkgconfig(libdnf) >= 0.7.0
+BuildRequires:  pkgconfig(libdnf) >= %{libdnf_version}
 BuildRequires:  pkgconfig(smartcols)
+BuildRequires:  help2man
+
+Requires:       libdnf%{?_isa} >= %{libdnf_version}
 
 %description
 %{summary}.
@@ -35,8 +48,30 @@ BuildRequires:  pkgconfig(smartcols)
 %license COPYING
 %doc README.md
 %{_bindir}/%{name}
+%{_mandir}/man8/%{name}.8*
 
 %changelog
+* Tue Dec 17 2019 Pavla Kratochvilova <pkratoch@redhat.com> - 3.0.1-7
+- Add dependency on libdnf
+
+* Tue Dec 17 2019 Pavla Kratochvilova <pkratoch@redhat.com> - 3.0.1-6
+- Allow downgrade for all transactions microdnf does (RhBug:1725863)
+
+* Tue Nov 26 2019 Ales Matej <amatej@redhat.com> - 3.0.1-5
+- Add repolist command (RhBug:1584952)
+- Add repoquery command (RhBug:1769245)
+
+* Wed Nov 13 2019 Ales Matej <amatej@redhat.com> - 3.0.1-4
+- Add support of best behavior (RhBug:1679476)
+- Add support for --releasever (RhBug:1591627)
+
+* Fri Aug 30 2019 Pavla Kratochvilova <pkratoch@redhat.com> - 3.0.1-3
+- Fix microdnf --help coredump (RhBug:1744979)
+
+* Thu Aug 01 2019 Pavla Kratochvilova <pkratoch@redhat.com> - 3.0.1-2
+- Fix minor memory leaks (RhBug:1702283)
+- Use help2man to generate a man page (RhBug:1612520)
+
 * Wed Jun 27 2018 Jaroslav Mracek <jmracek@redhat.com> - 3.0.1-1
 - Update to 3.0.1