From 34749e177db5d4aafdb9f3de630c7ab193a0f36d Mon Sep 17 00:00:00 2001 From: Allan McRae Date: Tue, 12 Feb 2013 22:00:53 +1000 Subject: 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 --- lib/libalpm/conflict.c | 28 ++++++++++++++++++++++++++-- lib/libalpm/sync.c | 2 +- 2 files changed, 27 insertions(+), 3 deletions(-) (limited to 'lib/libalpm') diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c index afed8953..18e29a89 100644 --- a/lib/libalpm/conflict.c +++ b/lib/libalpm/conflict.c @@ -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) { diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index f7b956ca..204456d6 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -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"); -- cgit v1.2.3-70-g09d2