1
0
mirror of https://github.com/moparisthebest/pacman synced 2025-03-01 01:41:52 -05:00

Perform limited conflict checking with --force

Pacman currently bails when trying to extract a file over a directory
when using --force.  Instead of ignoring all conflict, perform the
check and skip any file-file conflicts. Conflicts between directories
and files are still flagged and cause the transation to abort.

As a bonus, we now know about files changing packages when using
--force, so we can skip removing them fixing upgrade046.

Signed-off-by: Allan McRae <allan@archlinux.org>
This commit is contained in:
Allan McRae 2013-02-12 22:00:53 +10:00
parent 19754b34a3
commit 34749e177d
5 changed files with 32 additions and 5 deletions

View File

@ -205,6 +205,8 @@ Upgrade Options (apply to '-S' and '-U')[[UO]]
Bypass file conflict checks and overwrite conflicting files. If the
package that is about to be installed contains files that are already
installed, this option will cause all those files to be overwritten.
Using '--force' will not allow overwriting a directory with a file or
installing packages with conflicting files and directories.
This option should be used with care, ideally not at all.
*\--asdeps*::

View File

@ -443,8 +443,10 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
alpm_list_t *common_files;
alpm_pkg_t *p2 = j->data;
common_files = _alpm_filelist_intersection(alpm_pkg_get_files(p1),
alpm_pkg_get_files(p2));
alpm_filelist_t *p1_files = alpm_pkg_get_files(p1);
alpm_filelist_t *p2_files = alpm_pkg_get_files(p2);
common_files = _alpm_filelist_intersection(p1_files, p2_files);
if(common_files) {
alpm_list_t *k;
@ -452,6 +454,20 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
for(k = common_files; k; k = k->next) {
char *filename = k->data;
snprintf(path, PATH_MAX, "%s%s", handle->root, filename);
/* can skip file-file conflicts when forced *
* checking presence in p2_files detects dir-file or file-dir
* conflicts as the path from p1 is returned */
if((handle->trans->flags & ALPM_TRANS_FLAG_FORCE) &&
alpm_filelist_contains(p2_files, filename)) {
_alpm_log(handle, ALPM_LOG_DEBUG,
"%s exists in both '%s' and '%s'\n", filename,
p1->name, p2->name);
_alpm_log(handle, ALPM_LOG_DEBUG,
"file-file conflict being forced\n");
continue;
}
conflicts = add_fileconflict(handle, conflicts, path, p1, p2);
if(handle->pm_errno == ALPM_ERR_MEMORY) {
FREELIST(conflicts);
@ -606,6 +622,14 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
}
}
/* skip file-file conflicts when being forced */
if((handle->trans->flags & ALPM_TRANS_FLAG_FORCE) &&
!S_ISDIR(lsbuf.st_mode)) {
_alpm_log(handle, ALPM_LOG_DEBUG,
"conflict with file on filesystem being forced\n");
resolved_conflict = 1;
}
if(!resolved_conflict) {
conflicts = add_fileconflict(handle, conflicts, path, p1, NULL);
if(handle->pm_errno == ALPM_ERR_MEMORY) {

View File

@ -1241,7 +1241,7 @@ int _alpm_sync_commit(alpm_handle_t *handle, alpm_list_t **data)
trans->state = STATE_COMMITING;
/* fileconflict check */
if(!(trans->flags & (ALPM_TRANS_FLAG_FORCE|ALPM_TRANS_FLAG_DBONLY))) {
if(!(trans->flags & ALPM_TRANS_FLAG_DBONLY)) {
EVENT(handle, ALPM_EVENT_FILECONFLICTS_START, NULL, NULL);
_alpm_log(handle, ALPM_LOG_DEBUG, "looking for file conflicts\n");

View File

@ -881,6 +881,9 @@ int sync_prepare_execute(void)
alpm_strerror(err));
switch(err) {
case ALPM_ERR_FILE_CONFLICTS:
if(config->flags & ALPM_TRANS_FLAG_FORCE) {
printf(_("unable to %s directory-file conflicts\n"), "--force");
}
for(i = data; i; i = alpm_list_next(i)) {
alpm_fileconflict_t *conflict = i->data;
switch(conflict->type) {

View File

@ -29,5 +29,3 @@ self.addrule("FILE_MODIFIED=bin/dummy")
self.addrule("FILE_MODIFIED=bin/foobar")
self.addrule("FILE_EXIST=usr/share/file")
self.addrule("FILE_MODIFIED=usr/share/file")
self.expectfailure = True