summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/pacman.8.txt7
-rw-r--r--lib/libalpm/deps.c29
-rw-r--r--src/pacman/conf.h3
-rw-r--r--src/pacman/pacman.c8
4 files changed, 45 insertions, 2 deletions
diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt
index 3240022d..a362d2cf 100644
--- a/doc/pacman.8.txt
+++ b/doc/pacman.8.txt
@@ -400,6 +400,13 @@ system upgrade and install/upgrade the foo package in the same operation.
*\--needed*::
Don't reinstall the targets that are already up to date.
+*\--recursive*::
+ Recursively reinstall all dependencies of the targets. This forces upgrades
+ or reinstalls of all dependencies without requiring explicit version
+ requirements. This is most useful in combination with the '\--needed' flag,
+ which will induce a deep dependency upgrade without any unnecessary
+ reinstalls.
+
Handling Config Files[[HCF]]
----------------------------
diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c
index 51ae0fb9..992ebe23 100644
--- a/lib/libalpm/deps.c
+++ b/lib/libalpm/deps.c
@@ -701,6 +701,12 @@ int _alpm_resolvedeps(alpm_handle_t *handle, alpm_list_t *localpkgs,
return 0;
}
+ if(handle->trans->flags & ALPM_TRANS_FLAG_RECURSE) {
+ /* removing local packages from the equation causes the entire dep chain to
+ * get pulled for each target- e.g., pactree -u output */
+ localpkgs = NULL;
+ }
+
/* Create a copy of the packages list, so that it can be restored
on error */
packages_copy = alpm_list_copy(*packages);
@@ -753,6 +759,29 @@ int _alpm_resolvedeps(alpm_handle_t *handle, alpm_list_t *localpkgs,
alpm_list_free(deps);
}
+ if(handle->trans->flags & ALPM_TRANS_FLAG_NEEDED) {
+ /* remove any deps that were pulled that match installed version */
+ /* odd loop syntax so we can modify the list as we iterate */
+ i = *packages;
+ while(i) {
+ alpm_pkg_t *tpkg = i->data;
+ alpm_pkg_t *local = _alpm_db_get_pkgfromcache(
+ handle->db_local, tpkg->name);
+ if(local && _alpm_pkg_compare_versions(tpkg, local) == 0) {
+ /* with the NEEDED flag, packages up to date are not reinstalled */
+ _alpm_log(handle, ALPM_LOG_DEBUG,
+ "not adding dep %s-%s as it is not needed, same version\n",
+ local->name, local->version);
+ j = i;
+ i = i->next;
+ *packages = alpm_list_remove_item(*packages, j);
+ free(j);
+ } else {
+ i = i->next;
+ }
+ }
+ }
+
if(ret != 0) {
alpm_list_free(*packages);
*packages = packages_copy;
diff --git a/src/pacman/conf.h b/src/pacman/conf.h
index bce42ab5..33a87983 100644
--- a/src/pacman/conf.h
+++ b/src/pacman/conf.h
@@ -123,7 +123,8 @@ enum {
OP_ASEXPLICIT,
OP_ARCH,
OP_PRINTFORMAT,
- OP_GPGDIR
+ OP_GPGDIR,
+ OP_RECURSIVE
};
/* clean method */
diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index 21ccc966..585c8e08 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -165,6 +165,7 @@ static void usage(int op, const char * const myname)
addlist(_(" -w, --downloadonly download packages but do not install/upgrade anything\n"));
addlist(_(" -y, --refresh download fresh package databases from the server\n"));
addlist(_(" --needed don't reinstall up to date packages\n"));
+ addlist(_(" --recursive reinstall all dependencies of target packages\n"));
} else if(op == PM_OP_DATABASE) {
printf("%s: %s {-D --database} <%s> <%s>\n", str_usg, myname, str_opt, str_pkg);
printf("%s:\n", str_opt);
@@ -506,6 +507,9 @@ static int parsearg_remove(int opt)
case 'c': config->flags |= ALPM_TRANS_FLAG_CASCADE; break;
case 'n': config->flags |= ALPM_TRANS_FLAG_NOSAVE; break;
case 's':
+ case OP_RECURSIVE:
+ /* 's' is the legacy flag here, but since recursive is used in -S without
+ * a shortopt, we need to do funky tricks */
if(config->flags & ALPM_TRANS_FLAG_RECURSE) {
config->flags |= ALPM_TRANS_FLAG_RECURSEALL;
} else {
@@ -544,6 +548,7 @@ static int parsearg_sync(int opt)
return 0;
switch(opt) {
case OP_NEEDED: config->flags |= ALPM_TRANS_FLAG_NEEDED; break;
+ case OP_RECURSIVE: config->flags |= ALPM_TRANS_FLAG_RECURSE; break;
case 'c': (config->op_s_clean)++; break;
case 'g': (config->group)++; break;
case 'i': (config->op_s_info)++; break;
@@ -603,7 +608,6 @@ static int parseargs(int argc, char *argv[])
{"print", no_argument, 0, 'p'},
{"quiet", no_argument, 0, 'q'},
{"root", required_argument, 0, 'r'},
- {"recursive", no_argument, 0, 's'},
{"search", no_argument, 0, 's'},
{"unrequired", no_argument, 0, 't'},
{"upgrades", no_argument, 0, 'u'},
@@ -612,6 +616,7 @@ static int parseargs(int argc, char *argv[])
{"verbose", no_argument, 0, 'v'},
{"downloadonly", no_argument, 0, 'w'},
{"refresh", no_argument, 0, 'y'},
+
{"noconfirm", no_argument, 0, OP_NOCONFIRM},
{"config", required_argument, 0, OP_CONFIG},
{"ignore", required_argument, 0, OP_IGNORE},
@@ -628,6 +633,7 @@ static int parseargs(int argc, char *argv[])
{"arch", required_argument, 0, OP_ARCH},
{"print-format", required_argument, 0, OP_PRINTFORMAT},
{"gpgdir", required_argument, 0, OP_GPGDIR},
+ {"recursive", no_argument, 0, OP_RECURSIVE},
{0, 0, 0, 0}
};