Description of problem:
DNF does file conflict evaluation in a fairly dumb way (i.e., it doesn't do it at all). People get surprised because a transaction is proposed and then it fails at the transaction check, causing people to have to walk back and figure out how to solve the transaction themselves.
This not only seems wrong (and antithetical to what DNF should do), but it's also totally possible to avoid. I found out that Zypper actually can evaluate file conflicts using simply the metadata and libsolv. This allows Zypper to account for file conflicts for package replacement and ordering. This seems like an enhancement we should have in libdnf (and thus propagate to DNF itself). Since we do actually load the filelist metadata into the solver during repository metadata fetch, we already have the necessary data in place, and don't even have to reset the solver to make that kind of check possible.
Even without the filelists.xml content, there's still some in primary.xml, and it's worth making sure those conflicts are handled. File conflicts can and should be detected ahead of time, because they change the calculation of the valid solution.
Version-Release number of selected component (if applicable):
Dnf not doing file conflict resolution is not dumb at all, there are several fundamental reasons for it.
First, you cannot do any file conflict resolution with primary.xml alone and trying to do so would be only harmful. Don't even think of doing it, but thinking to understand why this is so is certainly useful.
Second, Fedora/RHEL relies on multilib ELF file conflict resolution by file colors, and libsolv cannot do that because there's no color information in the repodata. By using libsolv's file conflict detection you'd break multilib as *we* know it. (Open)Suse isn't bothered by this because they disable the file color resolution in rpm too, ie don't support the sloppy multilib packaging. Fedora could do that too but it'd be a massive distro-wide change to go through all packages to ensure their multilib'ed parts do not have ELF conflicts.
Third, because libsolv's file conflict resolution runs way before the transaction has started (as you'd kinda expect it to), using it would break the one and only chance packages have at directory <-> symlink replacement by using %pretrans scriptlet to do the ugly-but-necessary trick.
Fourth, I don't know how closely libsolv's file conflict detection otherwise resembles rpm's fingerprinting, but as the repodata lacks symlink information it cannot do that side at all. So no matter what there would still be significant conflict cases that cannot be detected by libsolv.
Thanks Panu for nice explanation. I know that people are not happy about the behavior, but we cannot change it because only rpm has all required information after downloading oll of rpms. I am really sorry but I have to close it. Anyway thanks for your report.