diff --git a/.gitignore b/.gitignore
index f7cc0bd..0df9088 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/rpm-ostree-2018.8.tar.xz
+SOURCES/rpm-ostree-2019.3.tar.xz
diff --git a/.rpm-ostree.metadata b/.rpm-ostree.metadata
index 64f8f59..d703be9 100644
--- a/.rpm-ostree.metadata
+++ b/.rpm-ostree.metadata
@@ -1 +1 @@
-5cd96fcc7f2ced01a0e4803ab956cf508d727e6a SOURCES/rpm-ostree-2018.8.tar.xz
+982c3b335debe04763c0b0b8769f7e43229beebc SOURCES/rpm-ostree-2019.3.tar.xz
diff --git a/SOURCES/0001-Backport-f50f9e8d-to-v2018.8-for-RHEL8.patch b/SOURCES/0001-Backport-f50f9e8d-to-v2018.8-for-RHEL8.patch
deleted file mode 100644
index b350dae..0000000
--- a/SOURCES/0001-Backport-f50f9e8d-to-v2018.8-for-RHEL8.patch
+++ /dev/null
@@ -1,183 +0,0 @@
-From 603f7e1d6ca4b0dffdb0275550a75e67d7a04623 Mon Sep 17 00:00:00 2001
-From: Jonathan Lebon <jonathan@jlebon.com>
-Date: Thu, 11 Oct 2018 14:16:02 -0400
-Subject: [PATCH] Backport f50f9e8d to v2018.8 for RHEL8
-
-We don't want to use cbindgen there, we want to use the vendored
-rpmostree-rust.h.
----
- Makefile-rpm-ostree.am               | 22 +++++++++++++++++++---
- bindgen/.gitignore                   |  2 ++
- bindgen/Cargo.toml                   | 12 ++++++++++++
- rust/build.rs => bindgen/src/main.rs | 10 ++++++----
- configure.ac                         | 12 ++++++++++++
- packaging/make-git-snapshot.sh       |  7 +++++++
- rust/Cargo.toml                      |  4 ----
- 7 files changed, 58 insertions(+), 11 deletions(-)
- create mode 100644 bindgen/.gitignore
- create mode 100644 bindgen/Cargo.toml
- rename rust/build.rs => bindgen/src/main.rs (61%)
-
-diff --git a/Makefile-rpm-ostree.am b/Makefile-rpm-ostree.am
-index 50a57e8e..9198961b 100644
---- a/Makefile-rpm-ostree.am
-+++ b/Makefile-rpm-ostree.am
-@@ -82,6 +82,16 @@ if BUILDOPT_NEW_NAME
- INSTALL_DATA_HOOKS += install-bin-hook
- endif
- 
-+if !HAVE_PREBUILT_CBINDGEN
-+if !HAVE_EXTERNAL_CBINDGEN
-+rpmostree-bindgen: bindgen/Cargo.toml bindgen/src/main.rs
-+	cd $(top_srcdir)/bindgen && \
-+	export CARGO_TARGET_DIR=@abs_top_builddir@/bindgen-target && \
-+	$(cargo) build --verbose && \
-+	ln -sf $${CARGO_TARGET_DIR}/debug/rpmostree-bindgen $(abs_top_builddir)/rpmostree-bindgen
-+endif
-+endif
-+
- librpmostree_rust_path = @abs_top_builddir@/target/@RUST_TARGET_SUBDIR@/librpmostree_rust.a
- # If the target directory exists, use --frozen; we don't
- # want to (by default) touch the Internet during builds here.
-@@ -95,11 +105,17 @@ $(librpmostree_rust_path): Makefile $(LIBRPMOSTREE_RUST_SRCS)
- 	  $(cargo) build --verbose $${frozen} $(CARGO_RELEASE_ARGS)
- EXTRA_DIST += $(LIBRPMOSTREE_RUST_SRCS) rust/Cargo.lock
- 
--# See rust/build.rs - it uses cbindgen as part of the Rust build
-+# Generate bindings from Rust to C
-+if !HAVE_PREBUILT_CBINDGEN
-+if HAVE_EXTERNAL_CBINDGEN
- rpmostree-rust.h: $(librpmostree_rust_path)
--	$(AM_V_GEN) src=$$(find @abs_top_builddir@/target/@RUST_TARGET_SUBDIR@/ -name 'rpmostree-rust.h') && \
--	  test -n "$${src}" && ln -sfr "$${src}" rpmostree-rust.h
-+	$(AM_V_GEN) cbindgen -c rust/cbindgen.toml -o $@ $(top_srcdir)/rust
-+else
-+rpmostree-rust.h: $(librpmostree_rust_path) rpmostree-bindgen
-+	$(AM_V_GEN) ./rpmostree-bindgen $(top_srcdir)/rust
-+endif
- BUILT_SOURCES += rpmostree-rust.h
-+endif
- 
- rpm_ostree_CFLAGS += $(PKGDEP_RPMOSTREE_RS_CFLAGS)
- rpm_ostree_LDADD += $(librpmostree_rust_path) $(PKGDEP_RPMOSTREE_RS_LIBS)
-diff --git a/bindgen/.gitignore b/bindgen/.gitignore
-new file mode 100644
-index 00000000..fa8d85ac
---- /dev/null
-+++ b/bindgen/.gitignore
-@@ -0,0 +1,2 @@
-+Cargo.lock
-+target
-diff --git a/bindgen/Cargo.toml b/bindgen/Cargo.toml
-new file mode 100644
-index 00000000..5a9e09ef
---- /dev/null
-+++ b/bindgen/Cargo.toml
-@@ -0,0 +1,12 @@
-+[package]
-+name = "rpmostree-bindgen"
-+version = "0.1.0"
-+authors = ["Colin Walters <walters@verbum.org>"]
-+
-+[dependencies]
-+cbindgen = "0.6.3"
-+
-+# Might as well keep these from the main Rust source
-+[profile.release]
-+panic = "abort"
-+debug = true
-diff --git a/rust/build.rs b/bindgen/src/main.rs
-similarity index 61%
-rename from rust/build.rs
-rename to bindgen/src/main.rs
-index b2e487ee..502a021d 100644
---- a/rust/build.rs
-+++ b/bindgen/src/main.rs
-@@ -4,12 +4,14 @@
- extern crate cbindgen;
- 
- fn run() -> Result<(), String> {
--    let out_dir_v = std::env::var("OUT_DIR").expect("OUT_DIR is unset");
--    let out_dir = std::path::Path::new(&out_dir_v);
--    let bindings = cbindgen::generate(std::path::Path::new(".")).map_err(|e| e.to_string())?;
-+    let args: Vec<String> = std::env::args().collect();
-+    let rustdir = std::path::Path::new(&args[1]);
-+    let out = std::path::Path::new("rpmostree-rust.h");
-+
-+    let bindings = cbindgen::generate(rustdir).map_err(|e| e.to_string())?;
-     // This uses unwraps internally; it'd be good to submit a patch
-     // to add a Result-based API.
--    bindings.write_to_file(out_dir.join("rpmostree-rust.h"));
-+    bindings.write_to_file(out);
-     Ok(())
- }
- 
-diff --git a/configure.ac b/configure.ac
-index 89cb2add..3d768e7d 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -213,6 +213,17 @@ AS_IF([test -z "$cargo"], [AC_MSG_ERROR([cargo is required for --enable-rust])])
- AC_PATH_PROG([rustc], [rustc])
- AS_IF([test -z "$rustc"], [AC_MSG_ERROR([rustc is required for --enable-rust])])
- 
-+dnl https://github.com/projectatomic/rpm-ostree/pull/1573
-+dnl We support 3 modes for bindgen:
-+dnl  - External /usr/bin/cbindgen (Fedora + CI)
-+dnl  - Downloading it from crates.io (CentOS + CI builds)
-+dnl  - Not running it at all, and using a pre-built rpmostree-rust.h (Koji)
-+AS_IF([test -d "${srcdir}"/rust/vendor],
-+      [cbindgen=dist],
-+      [AC_PATH_PROG([cbindgen], [cbindgen])])
-+AM_CONDITIONAL(HAVE_PREBUILT_CBINDGEN, [test "${cbindgen}" = "dist"])
-+AM_CONDITIONAL(HAVE_EXTERNAL_CBINDGEN, [test -n "${cbindgen}" && test "${cbindgen}" != dist])
-+
- AC_MSG_CHECKING(whether to build in debug mode)
- debug_release=release
- if $(echo $CFLAGS |grep -q -E "(-O0|-Og)"); then
-@@ -279,4 +290,5 @@ echo "
-     bubblewrap:                              $with_bubblewrap
-     gtk-doc:                                 $enable_gtk_doc
-     rust:                                    $rust_debug_release
-+    cbindgen:                                ${cbindgen:-internal}
- "
-diff --git a/packaging/make-git-snapshot.sh b/packaging/make-git-snapshot.sh
-index bbcf0092..da285e8c 100755
---- a/packaging/make-git-snapshot.sh
-+++ b/packaging/make-git-snapshot.sh
-@@ -47,4 +47,11 @@ mkdir ${tmpd} && touch ${tmpd}/.tmp
-  cp ${TOP}/rust/cargo-vendor-config .cargo/config
-  tar --transform="s,^,${PKG_VER}/rust/," -rf ${TARFILE_TMP} * .cargo/
-  )
-+
-+# And finally, vendor rpmostree-rust.h; it's generated by cbindgen,
-+# and it's easier than vendoring all of the source for that too.
-+# This is currently the *only* generated file we treat this way. See also
-+# https://github.com/projectatomic/rpm-ostree/pull/1573
-+(cd ${srcdir} && tar --transform "s,^,${PKG_VER}/," -rf ${TARFILE_TMP} rpmostree-rust.h)
-+
- mv ${TARFILE_TMP} ${TARFILE}
-diff --git a/rust/Cargo.toml b/rust/Cargo.toml
-index ee95b012..258da5fa 100644
---- a/rust/Cargo.toml
-+++ b/rust/Cargo.toml
-@@ -2,7 +2,6 @@
- name = "rpmostree-rust"
- version = "0.1.0"
- authors = ["Colin Walters <walters@verbum.org>"]
--build = "build.rs"
- 
- [dependencies]
- serde = "1.0"
-@@ -17,9 +16,6 @@ tempfile = "3.0.3"
- openat = "0.1.15"
- curl = "0.4.14"
- 
--[build-dependencies]
--cbindgen = "0.6.3"
--
- [lib]
- name = "rpmostree_rust"
- path = "src/lib.rs"
--- 
-2.17.1
-
diff --git a/SOURCES/0001-rebase-Support-identical-checksum-rebases.patch b/SOURCES/0001-rebase-Support-identical-checksum-rebases.patch
new file mode 100644
index 0000000..cd1addc
--- /dev/null
+++ b/SOURCES/0001-rebase-Support-identical-checksum-rebases.patch
@@ -0,0 +1,69 @@
+From 76ae779635afcd3984dedc57fa7c0e80c6410bba Mon Sep 17 00:00:00 2001
+From: Colin Walters <walters@verbum.org>
+Date: Fri, 29 Mar 2019 14:39:34 +0000
+Subject: [PATCH] rebase: Support identical checksum rebases
+
+Change things to only throw this error for non-checksum rebases; for
+RHEL CoreOS + https://github.com/openshift/pivot/
+we've had it happen that the same ostree commit can end up
+in separate oscontainers.  We want to support changing
+the custom origin that might point to the same commit.
+---
+ src/daemon/rpmostreed-transaction-types.c | 12 +++++++++---
+ src/daemon/rpmostreed-utils.c             | 10 ----------
+ 2 files changed, 9 insertions(+), 13 deletions(-)
+
+diff --git a/src/daemon/rpmostreed-transaction-types.c b/src/daemon/rpmostreed-transaction-types.c
+index 9edfeecb..86112d1b 100644
+--- a/src/daemon/rpmostreed-transaction-types.c
++++ b/src/daemon/rpmostreed-transaction-types.c
+@@ -100,9 +100,6 @@ change_origin_refspec (GVariantDict    *options,
+                                          error))
+     return FALSE;
+ 
+-  if (strcmp (current_refspec, new_refspec) == 0)
+-    return glnx_throw (error, "Old and new refs are equal: %s", new_refspec);
+-
+   /* Re-classify after canonicalization to ensure we handle TYPE_CHECKSUM */
+   if (!rpmostree_refspec_classify (new_refspec, &refspectype, &refspecdata, error))
+     return FALSE;
+@@ -128,6 +125,15 @@ change_origin_refspec (GVariantDict    *options,
+     }
+   else
+     {
++      /* We only throw this error for non-checksum rebases; for
++       * RHEL CoreOS + https://github.com/openshift/pivot/
++       * we've had it happen that the same ostree commit can end up
++       * in separate oscontainers.  We want to support changing
++       * the custom origin that might point to the same commit.
++       */
++      if (strcmp (current_refspec, new_refspec) == 0)
++        return glnx_throw (error, "Old and new refs are equal: %s", new_refspec);
++
+       if (!rpmostree_origin_set_rebase (origin, new_refspec, error))
+         return FALSE;
+     }
+diff --git a/src/daemon/rpmostreed-utils.c b/src/daemon/rpmostreed-utils.c
+index 686965a3..19b45a01 100644
+--- a/src/daemon/rpmostreed-utils.c
++++ b/src/daemon/rpmostreed-utils.c
+@@ -202,16 +202,6 @@ rpmostreed_refspec_parse_partial (const gchar *new_provided_refspec,
+         }
+     }
+ 
+-  if (g_strcmp0 (origin_remote, remote) == 0 &&
+-      g_strcmp0 (origin_ref, ref) == 0)
+-    {
+-      g_set_error (error, RPM_OSTREED_ERROR,
+-                   RPM_OSTREED_ERROR_INVALID_REFSPEC,
+-                   "Old and new refs are equal: %s:%s",
+-                   remote, ref);
+-      return FALSE;
+-    }
+-
+   if (remote == NULL)
+       *out_refspec = g_steal_pointer (&ref);
+   else
+-- 
+2.20.1
+
diff --git a/SPECS/rpm-ostree.spec b/SPECS/rpm-ostree.spec
index 93198c2..47c267e 100644
--- a/SPECS/rpm-ostree.spec
+++ b/SPECS/rpm-ostree.spec
@@ -1,16 +1,15 @@
 Summary: Hybrid image/package system
 Name: rpm-ostree
-Version: 2018.8
-Release: 2%{?dist}.0.1
+Version: 2019.3
+Release: 3%{?dist}
 #VCS: https://github.com/cgwalters/rpm-ostree
 # This tarball is generated via "cd packaging && make -f Makefile.dist-packaging dist-snapshot"
 # in the upstream git.  If rust is enabled, it contains vendored sources.
 Source0: rpm-ostree-%{version}.tar.xz
+Patch0: 0001-rebase-Support-identical-checksum-rebases.patch
 License: LGPLv2+
 URL: https://github.com/projectatomic/rpm-ostree
 
-Patch0: 0001-Backport-f50f9e8d-to-v2018.8-for-RHEL8.patch
-
 %if !%{defined rust_arches}
 # It's not defined yet in the base CentOS7 root
 %define rust_arches x86_64 i686 armv7hl aarch64 ppc64 ppc64le s390x
@@ -19,15 +18,12 @@ Patch0: 0001-Backport-f50f9e8d-to-v2018.8-for-RHEL8.patch
 ExclusiveArch: %{rust_arches}
 
 %if 0%{?fedora}
-BuildRequires: rust-packaging
-%else
-%if 0%{?rhel} < 8
-# really, this is for CentOS 7 (CAHC)
 BuildRequires: cargo
+BuildRequires: rust
 %else
+# assume el8
 BuildRequires: rust-toolset
 %endif
-%endif
 
 # For the autofiles bits below
 BuildRequires: /usr/bin/python3
@@ -40,8 +36,8 @@ BuildRequires: gperf
 BuildRequires: gnome-common
 BuildRequires: /usr/bin/g-ir-scanner
 # Core requirements
-# Easy way to check this: `objdump -p /path/to/rpm-ostree | grep LIBOSTREE` and pick the highest
-BuildRequires: pkgconfig(ostree-1) >= 2018.6
+# One way to check this: `objdump -p /path/to/rpm-ostree | grep LIBOSTREE` and pick the highest (though that might miss e.g. new struct members)
+BuildRequires: pkgconfig(ostree-1) >= 2018.9
 BuildRequires: pkgconfig(polkit-gobject-1)
 BuildRequires: pkgconfig(json-glib-1.0)
 BuildRequires: pkgconfig(rpm)
@@ -60,25 +56,30 @@ BuildRequires: pkgconfig(libcurl)
 # We're using RPATH to pick up our bundled version
 %global __requires_exclude ^libdnf[.]so[.].*$
 
-# Our bundled libdnf.so.1 is for us only
+# Our bundled libdnf.so.2 is for us only
 %global __provides_exclude_from ^%{_libdir}/%{name}/.*$
 
 BuildRequires: cmake
 BuildRequires: pkgconfig(expat)
 BuildRequires: pkgconfig(check)
-%if (0%{?rhel} != 0 && 0%{?rhel} <= 7)
-BuildRequires: libsolv-devel
-%else
 BuildRequires: pkgconfig(libsolv)
-%endif
 
 # We need g++ for libdnf
 BuildRequires: gcc-c++
 
-# In CentOS7/RHEL the package is client-only right now, but we can do both
-%if 0%{?rhel} != 0 && 0%{?rhel} <= 7
-Provides: rpm-ostree-client
-%endif
+
+# more libdnf build deps (see libdnf's spec for versions)
+%global swig_version 3.0.12
+%global libmodulemd_version 1.6.1
+BuildRequires:  swig >= %{swig_version}
+BuildRequires:  pkgconfig(modulemd) >= %{libmodulemd_version}
+BuildRequires:  pkgconfig(json-c)
+BuildRequires:  pkgconfig(cppunit)
+BuildRequires:  pkgconfig(sqlite3)
+BuildRequires:  pkgconfig(smartcols)
+BuildRequires:  gpgme-devel
+
+Requires:       libmodulemd%{?_isa} >= %{libmodulemd_version}
 
 # For now...see https://github.com/projectatomic/rpm-ostree/pull/637
 # and https://github.com/fedora-infra/fedmsg-atomic-composer/pull/17
@@ -100,14 +101,12 @@ a "best of both worlds" approach.
 
 %package libs
 Summary: Shared library for rpm-ostree
-Group: Development/Libraries
 
 %description libs
 The %{name}-libs package includes the shared library for %{name}.
 
 %package devel
 Summary: Development headers for %{name}
-Group: Development/Libraries
 Requires: %{name}-libs%{?_isa} = %{version}-%{release}
 
 %description devel
@@ -160,7 +159,8 @@ $PYTHON autofiles.py > files \
   '%{_prefix}/lib/systemd/system/*' \
   '%{_libexecdir}/rpm-ostree*' \
   '%{_datadir}/polkit-1/actions/*.policy' \
-  '%{_datadir}/dbus-1/system-services'
+  '%{_datadir}/dbus-1/system-services' \
+  '%{_datadir}/bash-completion/completions/*'
 
 $PYTHON autofiles.py > files.lib \
   '%{_libdir}/*.so.*' \
@@ -182,9 +182,38 @@ $PYTHON autofiles.py > files.devel \
 %files devel -f files.devel
 
 %changelog
-* Wed Jun 05 2019 Johnny Hughes <johnny@centos.org>
-- https://src.fedoraproject.org/rpms/rpm-ostree/pull-request/27
-  Simplify Rust conditionals (to build via default rust-toolset)
+* Fri May 17 2019 Jonathan Lebon <jlebon@redhat.com> - 2019.3-3
+- Rebuild for rhel-8.1.0 branch
+
+* Fri Mar 29 2019 Colin Walters <walters@verbum.org> - 2019.3-2
+- Backport patch for pivot rebases
+
+* Wed Mar 27 2019 Jonathan Lebon <jonathan@jlebon.com> - 2019.3-1
+- New upstream version
+
+* Thu Feb 14 2019 Jonathan Lebon <jonathan@jlebon.com> - 2019.2-1
+- New upstream version
+
+* Sat Feb 02 2019 Fedora Release Engineering <releng@fedoraproject.org> - 2019.1-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
+
+* Tue Jan 22 2019 Jonathan Lebon <jonathan@jlebon.com> - 2019.1-1
+- New upstream version
+
+* Fri Dec 14 2018 Jonathan Lebon <jonathan@jlebon.com> - 2018.10-1
+- New upstream version
+
+* Tue Dec 04 2018 Jonathan Lebon <jonathan@jlebon.com>
+- Simplify Rust conditionals
+
+* Fri Nov 02 2018 Jonathan Lebon <jonathan@jlebon.com> - 2018.9-3
+- Backport patch for https://pagure.io/dusty/failed-composes/issue/956
+
+* Tue Oct 30 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 2018.9-2
+- Rebuild for libsolv 0.7
+
+* Sun Oct 28 2018 Jonathan Lebon <jonathan@jlebon.com> - 2018.9-1
+- New upstream version
 
 * Mon Oct 15 2018 Jonathan Lebon <jonathan@jlebon.com> - 2018.8-2
 - Add new source and patch to drop cbindgen requirement