Studying vartree.py I have noticed that emerge behaves strangely when it finds that a config protected file has been replaced by a directory on the livesystem. If the config protected file had just been edited emerge would instead merge a ._cfg file but if the file had instead been replaced with a directory it does not. This does not give the user a change merge the new default configuration with his local changes. The attached patch fixes this by creating the ._cfg file. However etc-update fails to do something reasonable with it. But at least the user now sees that the file has changed. Reproducible: Always Steps to Reproduce: 1. Replace a config protected file with a directory 2. Install new version of the respective package. 3. Don't be informed about the change. Actual Results: creates no ._0000_filename file Expected Results: create a ._0000_filename file This is how etc-update fails after the above patch has been applied: $ tree -a /etc /etc |-- ._cfg0000_foo.conf |-- foo.conf (directory) `-- ... $ etc-update Scanning Configuration files... diff: /etc/foo.conf/._cfg0000_foo.conf: No such file or directory Automerging trivial changes in: /etc/foo.conf Exiting: Nothing left to do; exiting. :) NOTE: 1 updates remaining $ tree -a /etc /etc |--foo.conf | `-- ._cfg0000_foo.conf `--... Running etc-update again using "replace original with update" obviously has to results in /etc/foo.conf/foo.conf. However etc-update should be able to detect that it can't trivially merge a file and a directory and inform the user in such a situation. But that is a different bug - let's first get emerge to create the ._cfg file.
Created attachment 195614 [details] patch to create ._cfg file
Thanks, this is in svn r13679.
Most of mergeme() is quite messy. But I focus on the 'regular file' part because that is where I want to hook up some of my own code. So have started to refactor that part of the function. I do so to make it easier to actually understand what's going on. So then I noticed other things that seem a strange: A directory is not overwritten with a file even when it is NOT config protected. With my above patch (which you have already applied) the user will at least notice but it still seems wrong: (update from foo-1 to foo-2) foo-1: /etc/foo-config/ /etc/foo-config/foo-config /usr/share/foo/data/ /usr/share/foo/data/part1 /usr/share/foo/data/part2 foo-2: /etc/foo-config /usr/share/foo/data Sure the directory 'foo-config' should be protected but shouldn't this on the other hand just replace the directory 'data' with the file 'data'? So I would change: if stat.S_ISDIR(mydmode): ... elif stat.S_ISREG(mydmode)...: if protected: ... else: overwrite unconditionally to if protected: if stat.S_ISDIR(mydmode): ... elif stat.S_ISREG(mydmode)...: else: overwrite unconditionally I have also attached a patch containing my rewrite of this portion of the code. It can NOT be applied as is, as I first have to make sure that I have not overlooked any hidden behaviour in the old version. My version should behave the same except that: 1. Doesn't protect all directories. See above. 2. No error message is shown when the destination is blocked by a directory. This error message is redundant because it now (see [1]) only affects config protected files) and the user will be informed about the conflicts anyway. Besides this isn't an error, just a special situation. 3. First check if 'mymd5 == md5-of-destination' then if 'mymd5 == saved-md5' not other way around. The only difference this should make is that in very few cases destination is not overwritten by an IDENTICAL file as it would have with the current implementation. So the user sees '---' instead of '>>>' but the end result on the livefs is the same. My version has two 'if condition: pass' but that's a small price when replacing a maximum nesting of 6 with on of 2. Some more problems are mentioned in the comments starting with '???'.
Created attachment 197547 [details, diff] mergeme() -> stat.S_ISREG() rewrite
(In reply to comment #2) > Thanks, this is in svn r13679. Via gitweb: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=abf3368c778c9e615e5fa8acffcb2aa56fdd6a80 This was released in 2.1.7. Please file a new bug for any remaining issues. (In reply to comment #4) > Created an attachment (id=197547) [details] > mergeme() -> stat.S_ISREG() rewrite IIRC I didn't commit this patch because I found a bug in it. If you want, please rebase it against latest git and file a new bug.