- Package:
- debian-policy
- Source:
- debian-policy
- Submitter:
- Goswin von Brederlow
- Date:
- 2025-08-14 10:09:02 UTC
- Severity:
- normal
Hi, in May there was a discussion about the right use of Breaks or Conflicts as part of Bug#582423, e.g. http://lists.debian.org/debian-ctte/2010/05/msg00012.html Since then I've noticed at least 3 people on #debian-devel asking questions about wether to use Breaks or Conflicts now. Imho the description of Breaks and Conflicts is unclear and contradictory in parts and the use of Replaces+Breaks in 7.6.1 is wrong (breaks when an upgrade is aborted). I think all the needed info is in policy and the above mentioned discussion and now a good word smith is needed to write it up all nice and understandable. Saddly that is not me so consider this a request for help from those of you good with words. MfG Goswin
Seconded. Specifically, Policy now allows use Breaks, not Conflicts if two packages has a file conflict. I consider it as a regression - a high-level package manager cannot assume anymore that two packages having Breaks can be installed (temporarily) without a file conflict, and IMO the whole purpose of Breaks (as opposed to Conflicts) is defeated. Please not write policy to reflect currently existing problems in some high-level package managers which do wrong thing seeing 'Conflicts+Replaces'.
"Eugene V. Lyubimkin" <ext-lyubimkin.eugene@nokia.com> writes:
Huh? The presense of Replaces allows the two to be both unpacked. The
Repalces specifically disables the file conflict.
MfG
Goswin
[ sorry for not proper 'mail-reply', used wrong mail address before ] Replaces is one-way dependency, Breaks is two-way one. If I unpack two packages, one having Breaks+Replaces, in the other order, I will have a file conflict. And a high-level package manager have right to do it, by the definition of Breaks, because "slave" package is not configured.
Breaks and Replaces are both asymmetric relationships. No, you won't. Why would you think so?
Steve Langasek wrote: and By logic. I didn't see anything to prevent them. However, as dpkg disagree with me too, I started to wonder if policy in 'Packages can declare in their control file that they should overwrite files in certain other packages, or completely replace other packages' actually means two-way dependency? And is it obvious to anyone but me?
It's not a "two-way dependency"; the relationship is still asymmetric, the files from the package /declaring/ Replaces always takes precedence. But the Replaces operation is invariant with respect to package unpack order - perhaps that's what you mean? I wouldn't say this is obvious. I would say it's the /correct/ way to implement it, and I know this is how it's implemented because I remember back to when dpkg *didn't* do this correctly. But it's possible that this should be clarified in Policy.
Steve Langasek wrote: Yes, that's what I mean.
"Eugene V. Lyubimkin" <jackyf@debian.org> writes:
That was a bug in dpkg that has been fixed a while now I think. Replaces
has to be two-way so that unpacking the replaced package after the
replacing one does not give a file overwrite error.
If you think the issue still exists then please create a unit test in
dpkg and file that as seperate bugreport against dpkg.
MfG
Goswin
retitle 592610 Clarify when Conflicts + Replaces et al are appropriate quit Hi Goswin, In 2010, Goswin von Brederlow wrote: Policy §7.6.2 sayeth: | Second, Replaces allows the packaging system to resolve which package | should be removed when there is a conflict (see Conflicting binary | packages - Conflicts, Section 7.4). One reading of this would be that in the presence of Conflicts, Replaces represents a partial ordering of packages, indicating which should be removed in case of conflict. Seems useful enough. One consequence of this definition is that when A conflicts with and replaces B, B should not conflict with and replace A in turn, since the symmetric relationships would give no guidance in how to resolve the conflict. Then it continues: | In this situation, the package declared as being replaced can be a | virtual package, so for example, all mail transport agents (MTAs) | would have the following fields in their control files: | | Provides: mail-transport-agent | Conflicts: mail-transport-agent | Replaces: mail-transport-agent | | ensuring that only one MTA can be unpacked at any one time. Here policy is recommending the same symmetrical C+R relationship it had just seemed to imply defeats the purpose of C+R. Responding to this confusing passage, Ian Jackson wrote[1]: | If two packages Replaces/Conflicts/Provides the same virtual | package you can't just "dpkg -i" to swap between them. This is | demonstrated in Eugene's message on the 9th of May, and the test | case mentioned by Raphael does it. [...] | So which of spec or implementation is correct ? I think the | implementation is correct and the spec is wrong. The thread also contains some guidance about particular use cases, but first I guess we should resolve this question. Should packages A and B be allowed to ever both conflict with and replace each other? I wouldn't mind a policy "should" forbidding mutual C+R on the grounds that they are confusing, even though they are a widespread practice. Thanks for filing this. I think it got forgotten. Hope that helps, Jonathan [1] https://lists.debian.org/debian-ctte/2010/05/msg00010.html
Jonathan Nieder <jrnieder@gmail.com> writes: Yes, that seems to be Ian's conclusion. Policy currently treats this as a special case distinguished by the presence of Provides, but as discussed in that thread, that isn't a very good assumption, since there are other reasons for wanting to add the Provides than this case. Ian proposed a comprehensive replacement for what to use in the different use cases we have, and I think that's a better approach. The point is to make sure that we cover all our different use cases and can usefully distinguish between them. The key change is that the virtual package conflict drops Replaces, which of course isn't what's in the archive right now and would require lots of people change packages. Before we go down that path, I'd really like to get confirmation from the dpkg developers that that's the correct thing to do. I think that's the only real change from the current wording; the rest is (useful) clarification. Note that the point originally raised is that dpkg -i can't be used to switch between packages implementing the same virtual package in a mutually-exclusive fashion. Does the proposed solution actually fix that problem? Maybe someone could propose new language implementing the table discussed in the above thread and then we could run it past the dpkg folks to make sure that makes sense? I think the best wording approach would be to describe the intent of Breaks, Conflicts, Provides, and Replaces in isolation in their current sections, but then move all of the text about how they work in concert to a new section that lays out the specific use cases discussed and provides guidance for how to implement each one.
Hello,
Note 3 says
To see why Breaks is normally needed in addition to Replaces,
consider the case of a file in the package foo being taken over by
the package foo-data. Replaces will allow foo-data to be installed
and take over that file. However, without Breaks, nothing requires
foo to be upgraded to a newer version that knows it does not include
that file and instead depends on foo-data. Nothing would prevent
the new foo-data package from being installed and then removed,
removing the file that it took over from foo. After that operation,
the package manager would think the system was in a consistent
state, but the foo package would be missing one of its files.
This works for the foo/foo-data example in the text because these are
implied to be tightly coupled packages. But sometimes you do want
Replaces without Breaks, because the cost of Breaks is high.
bin:git-debpush is taking over /usr/bin/git-deborig from devscripts.
So devscripts is getting a "Recommends: git-debpush (>= 13.12)" and
git-debpush is getting a "Replaces: devscripts (<< 2.25.18)".
If we also add a Breaks, git-debpush won't be installable on older
Debian releases. Currently dgit and git-debpush are installable and
work all the way back to buster.
devscripts doesn't hard-depend on the functionality in git-deborig.
You can't even use it without installing some of devscript's Recommends,
like with other things in devscripts. Therefore it wouldn't make sense
to give up the high installability of git-debpush and trivial
backportability of src:dgit just so that if someone decides to install
devscripts and then install and remove git-debpush, they will be left
without git-deborig.
Ideally the text would reflect this but it's a significant task to work
it in without adding too much length.
I think many people in Debian mistakenly think you can't ever use
Replaces without Breaks; there is a Salsa CI 'missing-breaks' check that
enforces it that we are now having to disable for src:dgit.
Sean Whitton <spwhitton@spwhitton.name> writes: My first reaction is that this is a very specific situation that isn't going to arise much, in part because devscripts is a rather unusual package: It provides a ton of functionality, most of which is probably not used by the typical person who installs it, and therefore the risk of a package inconsistency where part of the package goes missing is not as high for it. I think the way to generalize this would be to say that Breaks may not be desirable if all of the following apply: 1. The replaced functionality is not that important to the original package, so the consequences of the described pattern that causes the file to disappear won't affect many people. 2. Coinstallation of the two packages is important (in backports, for instance). 3. Backporting of the package whose files are being replaced is not desirable for some reason, even though backporting of the replacing package *is* important. This seems like an edge case, and the criteria for 1 are rather murky. The package inconsistency that can be reached without Breaks bothers me, since it's a sort of silent corruption in the sense that the contents of the installed packages no longer represent the files present on the system. That seems worth going to some effort to avoid, and I'm a bit worried about people accepting that state too readily. In other words, I agree with your conclusion that not using Breaks is fine in this situation, and this is why Policy says "should" and not "must," but explaining the exception cases to the "should" is a bit tricky. I think the problem might be more that forgetting the Breaks is a really common error because nothing in the packaging workflow makes you add it? If you try to move the file without Replaces, installing the new package fails and that's immediately obvious, but once you add the Replaces, nothing makes you add the Breaks and the failure mode is pretty silent. So I'm not sure it's that people think it's flatly disallowed as much as it's a common error that's hard to notice. I'm surprised that there's a special check for this instead of relying on Lintian, though. I don't *think* it requires cross-package knowledge to diagnose?
Hello, Thanks, I agree with everything you've written here. Yeah, you're probably right. The check currently actually determines whether there are issues with file overwriting, by installing the packages and seeing what happens, I think. But I don't know much about it.