Add --replacefiles option to resolve file conflicts (bnc#673720)
authorMichael Andres <ma@suse.de>
Wed, 29 Jan 2014 11:40:31 +0000 (12:40 +0100)
committerMichael Andres <ma@suse.de>
Wed, 29 Jan 2014 11:40:31 +0000 (12:40 +0100)
doc/zypper.8
src/Zypper.cc
src/callbacks/rpm.h

index 49983d4..ce0f3b3 100644 (file)
@@ -125,6 +125,13 @@ See http://old-en.opensuse.org/Software_Management/Dependencies for more
 information. Zypper uses a \fIdependency solver\fR to find out what
 packages need to be installed to satisfy the user's request.
 
+.SS Package File Conflicts
+.LP
+File conflicts happen when two packages attempt to install files with the same name but different contents. This may happen if you are installing a newer version of a package without erasing the older version, of if two unrelated packages each install a file with the same name.
+.LP
+As checking for file conflicts requires access to the full filelist of each package being installed, zypper will check for file conflict only if all packages are downloaded in advance (see \fI--download-in-advance\fR).
+.LP
+As the reason for file conlicts usually is a poor package design or lack of coordination between the the people building the packages, they are not easy to resolve. By using the \fI--replacefiles\fR option you can force zypper to replace the conflicting files. Nevertheless this may damage the package whose file gets replaced.
 
 .SH "COMMANDS"
 .LP
@@ -324,6 +331,9 @@ By default, zypper installs also packages recommended by the requested ones.
 This option causes the recomended packages to be ignored and only the
 required ones to be installed.
 .TP
+.I \ \ \ \ \-\-replacefiles
+Install the packages even if they replace files from other, already installed, packages. Default is to treat file conflicts as an error. \fI--download-as-needed\fR disables the fileconflict check because access to all packages filelists is needed in advance in order to perform the check.
+.TP
 .I \-R, \-\-no\-force\-resolution
 Do not force the solver to find a solution. Instead, report
 dependency problem and prompt the user to resolve it manually.
@@ -597,6 +607,9 @@ By default, zypper installs also packages recommended by the requested ones.
 This option causes the recomended packages to be ignored and only the
 required ones to be installed.
 .TP
+.I \ \ \ \ \-\-replacefiles
+Install the packages even if they replace files from other, already installed, packages. Default is to treat file conflicts as an error. \fI--download-as-needed\fR disables the fileconflict check because access to all packages filelists is needed in advance in order to perform the check.
+.TP
 .I \-R, \-\-no\-force\-resolution
 Do not force the solver to find a solution. Instead, report
 dependency problem and prompt the user to resolve it manually.
@@ -713,6 +726,9 @@ By default, zypper installs also packages recommended by the requested ones.
 This option causes the recomended packages to be ignored and only the
 required ones to be installed.
 .TP
+.I \ \ \ \ \-\-replacefiles
+Install the packages even if they replace files from other, already installed, packages. Default is to treat file conflicts as an error. \fI--download-as-needed\fR disables the fileconflict check because access to all packages filelists is needed in advance in order to perform the check.
+.TP
 .I \ \ \ \ \-\-debug\-solver
 Create test case for debugging of dependency resolver.
 .TP
@@ -768,6 +784,9 @@ By default, zypper installs also packages recommended by the requested ones.
 This option causes the recomended packages to be ignored and only the
 required ones to be installed.
 .TP
+.I \ \ \ \ \-\-replacefiles
+Install the packages even if they replace files from other, already installed, packages. Default is to treat file conflicts as an error. \fI--download-as-needed\fR disables the fileconflict check because access to all packages filelists is needed in advance in order to perform the check.
+.TP
 .I \ \ \ \ \-\-debug\-solver
 Create solver test case for debugging. See the install command for details.
 .TP
index 386eba4..2cf8e65 100644 (file)
@@ -1027,6 +1027,7 @@ void Zypper::processCommandOptions()
       {"name",                      no_argument,       0, 'n'},
       {"force",                     no_argument,       0, 'f'},
       {"oldpackage",                no_argument,       0,  0 },
+      {"replacefiles",              no_argument,       0,  0 },
       {"capability",                no_argument,       0, 'C'},
       // rug compatibility, we have global --non-interactive
       {"no-confirm",                no_argument,       0, 'y'},
@@ -1076,6 +1077,9 @@ void Zypper::processCommandOptions()
       "    --oldpackage            Allow to replace a newer item with an older one.\n"
       "                            Handy if you are doing a rollback. Unlike --force\n"
       "                            it will not enforce a reinstall.\n"
+      "    --replacefiles          Install the packages even if they replace files from other,\n"
+      "                            already installed, packages. Default is to treat file conflicts\n"
+      "                            as an error. --download-as-needed disables the fileconflict check.\n"
       "-l, --auto-agree-with-licenses\n"
       "                            Automatically say 'yes' to third party license\n"
       "                            confirmation prompt.\n"
@@ -1712,6 +1716,7 @@ void Zypper::processCommandOptions()
       {"force-resolution",          no_argument,       0,  0 },
       {"no-recommends",             no_argument,       0,  0 },
       {"recommends",                no_argument,       0,  0 },
+      {"replacefiles",              no_argument,       0,  0 },
       {"dry-run",                   no_argument,       0, 'D'},
       // rug uses -N shorthand
       {"dry-run",                   no_argument,       0, 'N'},
@@ -1754,6 +1759,9 @@ void Zypper::processCommandOptions()
       "    --no-recommends         Do not install recommended packages, only required.\n"
       "    --recommends            Install also recommended packages in addition\n"
       "                            to the required.\n"
+      "    --replacefiles          Install the packages even if they replace files from other,\n"
+      "                            already installed, packages. Default is to treat file conflicts\n"
+      "                            as an error. --download-as-needed disables the fileconflict check.\n"
       "-R, --no-force-resolution   Do not force the solver to find solution,\n"
       "                            let it ask.\n"
       "    --force-resolution      Force the solver to find a solution (even\n"
@@ -1778,6 +1786,7 @@ void Zypper::processCommandOptions()
       {"debug-solver",              no_argument,       0,  0 },
       {"no-recommends",             no_argument,       0,  0 },
       {"recommends",                no_argument,       0,  0 },
+      {"replacefiles",              no_argument,       0,  0 },
       {"dry-run",                   no_argument,       0, 'D'},
       {"download",                  required_argument, 0,  0 },
       // aliases for --download
@@ -1816,6 +1825,9 @@ void Zypper::processCommandOptions()
       "    --no-recommends         Do not install recommended packages, only required.\n"
       "    --recommends            Install also recommended packages in addition\n"
       "                            to the required.\n"
+      "    --replacefiles          Install the packages even if they replace files from other,\n"
+      "                            already installed, packages. Default is to treat file conflicts\n"
+      "                            as an error. --download-as-needed disables the fileconflict check.\n"
       "-r, --repo <alias|#|URI>    Load only the specified repository.\n"
       "-D, --dry-run               Test the update, do not actually update.\n"
       "    --download              Set the download-install mode. Available modes:\n"
@@ -1864,6 +1876,7 @@ void Zypper::processCommandOptions()
       {"from",                      required_argument, 0,  0 },
       {"no-recommends",             no_argument,       0,  0 },
       {"recommends",                no_argument,       0,  0 },
+      {"replacefiles",              no_argument,       0,  0 },
       {"auto-agree-with-licenses",  no_argument,       0, 'l'},
       {"debug-solver",              no_argument,       0,  0 },
       {"dry-run",                   no_argument,       0, 'D'},
@@ -1897,6 +1910,9 @@ void Zypper::processCommandOptions()
       "    --no-recommends         Do not install recommended packages, only required.\n"
       "    --recommends            Install also recommended packages in addition\n"
       "                            to the required.\n"
+      "    --replacefiles          Install the packages even if they replace files from other,\n"
+      "                            already installed, packages. Default is to treat file conflicts\n"
+      "                            as an error. --download-as-needed disables the fileconflict check.\n"
       "-D, --dry-run               Test the upgrade, do not actually upgrade\n"
       "    --download              Set the download-install mode. Available modes:\n"
       "                            %s\n"
index 7106ed7..8a34a38 100644 (file)
@@ -395,17 +395,23 @@ struct FindFileConflictstReportReceiver : public zypp::callback::ReceiveReport<z
                  conflicts_r, out::FileConflictsListFormater() );
        out.gap();
 
-
-       bool cont = read_bool_answer( PROMPT_YN_CONTINUE_ON_FILECONFLICT, str::Str()
-                   // TranslatorExplanation Problem description before asking whether to "Continue? [yes/no] (no):"
-                   <<_("File conflicts happen when two packages attempt to install files with the same name but different contents. If you continue, conflicting files will be replaced losing the previous content.")
-                   << "\n"
-                   <<_("Continue?"),
-                   false );
-       out.gap();
-
-       if ( ! cont )
-         return false;         // aborted.
+       if ( Zypper::instance()->cOpts().count("replacefiles") )
+       {
+         out.info( _("Conflicting files will be replaced."), " [--replacefiles]" );
+       }
+       else
+       {
+         bool cont = read_bool_answer( PROMPT_YN_CONTINUE_ON_FILECONFLICT, str::Str()
+                     // TranslatorExplanation Problem description before asking whether to "Continue? [yes/no] (no):"
+                     <<_("File conflicts happen when two packages attempt to install files with the same name but different contents. If you continue, conflicting files will be replaced losing the previous content.")
+                     << "\n"
+                     <<_("Continue?"),
+                     false );
+         out.gap();
+
+         if ( ! cont )
+           return false;               // aborted.
+       }
       }
     }