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:
parent
19754b34a3
commit
34749e177d
5 changed files with 32 additions and 5 deletions
|
@ -205,6 +205,8 @@ Upgrade Options (apply to '-S' and '-U')[[UO]]
|
||||||
Bypass file conflict checks and overwrite conflicting files. If the
|
Bypass file conflict checks and overwrite conflicting files. If the
|
||||||
package that is about to be installed contains files that are already
|
package that is about to be installed contains files that are already
|
||||||
installed, this option will cause all those files to be overwritten.
|
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.
|
This option should be used with care, ideally not at all.
|
||||||
|
|
||||||
*\--asdeps*::
|
*\--asdeps*::
|
||||||
|
|
|
@ -443,8 +443,10 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
|
||||||
alpm_list_t *common_files;
|
alpm_list_t *common_files;
|
||||||
alpm_pkg_t *p2 = j->data;
|
alpm_pkg_t *p2 = j->data;
|
||||||
|
|
||||||
common_files = _alpm_filelist_intersection(alpm_pkg_get_files(p1),
|
alpm_filelist_t *p1_files = alpm_pkg_get_files(p1);
|
||||||
alpm_pkg_get_files(p2));
|
alpm_filelist_t *p2_files = alpm_pkg_get_files(p2);
|
||||||
|
|
||||||
|
common_files = _alpm_filelist_intersection(p1_files, p2_files);
|
||||||
|
|
||||||
if(common_files) {
|
if(common_files) {
|
||||||
alpm_list_t *k;
|
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) {
|
for(k = common_files; k; k = k->next) {
|
||||||
char *filename = k->data;
|
char *filename = k->data;
|
||||||
snprintf(path, PATH_MAX, "%s%s", handle->root, filename);
|
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);
|
conflicts = add_fileconflict(handle, conflicts, path, p1, p2);
|
||||||
if(handle->pm_errno == ALPM_ERR_MEMORY) {
|
if(handle->pm_errno == ALPM_ERR_MEMORY) {
|
||||||
FREELIST(conflicts);
|
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) {
|
if(!resolved_conflict) {
|
||||||
conflicts = add_fileconflict(handle, conflicts, path, p1, NULL);
|
conflicts = add_fileconflict(handle, conflicts, path, p1, NULL);
|
||||||
if(handle->pm_errno == ALPM_ERR_MEMORY) {
|
if(handle->pm_errno == ALPM_ERR_MEMORY) {
|
||||||
|
|
|
@ -1241,7 +1241,7 @@ int _alpm_sync_commit(alpm_handle_t *handle, alpm_list_t **data)
|
||||||
trans->state = STATE_COMMITING;
|
trans->state = STATE_COMMITING;
|
||||||
|
|
||||||
/* fileconflict check */
|
/* 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);
|
EVENT(handle, ALPM_EVENT_FILECONFLICTS_START, NULL, NULL);
|
||||||
|
|
||||||
_alpm_log(handle, ALPM_LOG_DEBUG, "looking for file conflicts\n");
|
_alpm_log(handle, ALPM_LOG_DEBUG, "looking for file conflicts\n");
|
||||||
|
|
|
@ -881,6 +881,9 @@ int sync_prepare_execute(void)
|
||||||
alpm_strerror(err));
|
alpm_strerror(err));
|
||||||
switch(err) {
|
switch(err) {
|
||||||
case ALPM_ERR_FILE_CONFLICTS:
|
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)) {
|
for(i = data; i; i = alpm_list_next(i)) {
|
||||||
alpm_fileconflict_t *conflict = i->data;
|
alpm_fileconflict_t *conflict = i->data;
|
||||||
switch(conflict->type) {
|
switch(conflict->type) {
|
||||||
|
|
|
@ -29,5 +29,3 @@ self.addrule("FILE_MODIFIED=bin/dummy")
|
||||||
self.addrule("FILE_MODIFIED=bin/foobar")
|
self.addrule("FILE_MODIFIED=bin/foobar")
|
||||||
self.addrule("FILE_EXIST=usr/share/file")
|
self.addrule("FILE_EXIST=usr/share/file")
|
||||||
self.addrule("FILE_MODIFIED=usr/share/file")
|
self.addrule("FILE_MODIFIED=usr/share/file")
|
||||||
|
|
||||||
self.expectfailure = True
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue