summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Gregory <andrew.gregory.8@gmail.com>2015-12-04 20:14:32 +0100
committerAllan McRae <allan@archlinux.org>2015-12-05 08:46:22 +0100
commit4838d250e5fc258bdd52dc31098ed2ad0e44ee40 (patch)
tree3542dbadea732d9b2e0d29b8aac1102b70c91b3e
parentbb5e6c3b767e923fdb6cbdd75a930838c9b2a018 (diff)
downloadpacman-4838d250e5fc258bdd52dc31098ed2ad0e44ee40.tar.gz
pacman-4838d250e5fc258bdd52dc31098ed2ad0e44ee40.tar.xz
skip conflicts resolved by file replacement
When replacing a file with a directory, any files inside the new directory cannot possibly exist on the filesystem and can be skipped. This allows cross-package symlink-to-directory transitions when there are files with the same name under both the symlinked directory and the new directory. Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com> Signed-off-by: Allan McRae <allan@archlinux.org>
-rw-r--r--lib/libalpm/conflict.c15
-rw-r--r--test/pacman/tests/symlink021.py2
2 files changed, 15 insertions, 2 deletions
diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c
index 41b8393c..a70023b1 100644
--- a/lib/libalpm/conflict.c
+++ b/lib/libalpm/conflict.c
@@ -566,6 +566,8 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
/* localp2->files will be removed (target conflicts are handled by CHECK 1) */
if(localp2 && alpm_filelist_contains(alpm_pkg_get_files(localp2), relative_path)) {
+ size_t fslen = strlen(filestr);
+
/* skip removal of file, but not add. this will prevent a second
* package from removing the file when it was already installed
* by its new owner (whether the file is in backup array or not */
@@ -574,6 +576,19 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
_alpm_log(handle, ALPM_LOG_DEBUG,
"file changed packages, adding to remove skiplist\n");
resolved_conflict = 1;
+
+ if(filestr[fslen - 1] == '/') {
+ /* replacing a file with a directory:
+ * go ahead and skip any files inside filestr as they will
+ * necessarily be resolved by replacing the file with a dir
+ * NOTE: afterward, j will point to the last file inside filestr */
+ for( ; j->next; j = j->next) {
+ const char *filestr2 = j->next->data;
+ if(strncmp(filestr, filestr2, fslen) != 0) {
+ break;
+ }
+ }
+ }
}
}
diff --git a/test/pacman/tests/symlink021.py b/test/pacman/tests/symlink021.py
index 19a7f099..1ba7c025 100644
--- a/test/pacman/tests/symlink021.py
+++ b/test/pacman/tests/symlink021.py
@@ -24,5 +24,3 @@ self.addrule("FILE_TYPE=usr/include/foo|dir")
self.addrule("!FILE_TYPE=usr/include/bar|link")
self.addrule("FILE_EXIST=usr/include/foo/header.h")
self.addrule("FILE_EXIST=usr/include/bar/header.h")
-
-self.expectfailure = True