diff --git a/bin/xbps-bin/install.c b/bin/xbps-bin/install.c
index 661239c4..349c4860 100644
--- a/bin/xbps-bin/install.c
+++ b/bin/xbps-bin/install.c
@@ -341,7 +341,8 @@ static int
exec_transaction(struct transaction *trans)
{
prop_dictionary_t instpkgd;
- prop_object_t obj;
+ prop_object_t obj, obj2;
+ prop_object_iterator_t replaces_iter;
const char *pkgname, *version, *instver, *filename, *tract;
int rv = 0;
bool essential, isdep, autoinst;
@@ -384,6 +385,7 @@ exec_transaction(struct transaction *trans)
prop_dictionary_get_bool(obj, "essential", &essential);
prop_dictionary_get_cstring_nocopy(obj, "filename", &filename);
prop_dictionary_get_cstring_nocopy(obj, "trans-action", &tract);
+ replaces_iter = xbps_get_array_iter_from_dict(obj, "replaces");
if (trans->originpkgname &&
strcmp(trans->originpkgname, pkgname))
@@ -399,6 +401,37 @@ exec_transaction(struct transaction *trans)
if (state == XBPS_PKG_STATE_UNPACKED)
continue;
+ /*
+ * This package replaces other package(s), so we remove
+ * them before upgrading or installing new one.
+ */
+ if (replaces_iter != NULL) {
+ while ((obj2 =
+ prop_object_iterator_next(replaces_iter))) {
+ printf("Replacing package '%s' with '%s-%s' "
+ "...\n", prop_string_cstring(obj2),
+ pkgname, version);
+ rv = xbps_remove_pkg(prop_string_cstring(obj2),
+ NULL, false);
+ if (rv != 0) {
+ printf("Couldn't remove %s (%s)\n",
+ prop_string_cstring(obj2),
+ strerror(rv));
+ return rv;
+ }
+ rv = xbps_purge_pkg(prop_string_cstring(obj2),
+ false);
+ if (rv != 0) {
+ printf("Couldn't purge %s (%s)\n",
+ prop_string_cstring(obj2),
+ strerror(rv));
+ return rv;
+ }
+ }
+ prop_object_iterator_release(replaces_iter);
+ replaces_iter = NULL;
+ }
+
if (strcmp(tract, "update") == 0) {
instpkgd = xbps_find_pkg_installed_from_plist(pkgname);
if (instpkgd == NULL) {
diff --git a/doc/README b/doc/README
index 7e1eb1ed..9b759486 100644
--- a/doc/README
+++ b/doc/README
@@ -47,7 +47,7 @@ and install xbps binary packages:
* sudo
Super-user privileges are required as well, because all packages are built
-in a chroot (except the ones that are included in a virtual package to be
+in a chroot (except the ones that are included in a meta package to be
able to build a minimal system for the chroot).
PLEASE NOTE THAT fakechroot or fakeroot-ng DO NOT WORK.
@@ -65,9 +65,6 @@ Once the xbps distfiles are installed into prefix, you can start building
packages from source, add local repositories with binary packages, install or
remove them, etc.
-If you are only interested in building/using packages from source, see the
-SRCPKG_INFO file.
-
For information about binary packages, see the BINPKG_INFO file.
------------------------------------------------------------------------------
diff --git a/shutils/metadata.sh b/shutils/metadata.sh
index aa7ffbdb..90c40703 100644
--- a/shutils/metadata.sh
+++ b/shutils/metadata.sh
@@ -311,6 +311,16 @@ _EOF
echo "" >> $TMPFPROPS
fi
+ # Replace package(s).
+ if [ -n "$replaces" ]; then
+ echo "replaces" >> $TMPFPROPS
+ echo "" >> $TMPFPROPS
+ for f in ${replaces}; do
+ echo "$f" >> $TMPFPROPS
+ done
+ echo "" >> $TMPFPROPS
+ fi
+
# Terminate the property list file.
echo "" >> $TMPFPROPS
echo "" >> $TMPFPROPS
diff --git a/shutils/tmpl_funcs.sh b/shutils/tmpl_funcs.sh
index 5a22559d..56d8a218 100644
--- a/shutils/tmpl_funcs.sh
+++ b/shutils/tmpl_funcs.sh
@@ -76,7 +76,7 @@ reset_tmpl_vars()
only_for_archs conf_files keep_libtool_archives \
noarch subpackages sourcepkg gtk_iconcache_dirs \
abi_depends api_depends triggers openrc_services \
- XBPS_EXTRACT_DONE XBPS_CONFIGURE_DONE \
+ replaces XBPS_EXTRACT_DONE XBPS_CONFIGURE_DONE \
XBPS_BUILD_DONE XBPS_INSTALL_DONE FILESDIR DESTDIR \
SRCPKGDESTDIR PATCHESDIR"