1 |
commit: 3a25c3fa13d7c62ba8c00d6c7a75eb907d34b568 |
2 |
Author: Zac Medico <zmedico <AT> gentoo <DOT> org> |
3 |
AuthorDate: Fri Jul 13 03:58:04 2018 +0000 |
4 |
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> |
5 |
CommitDate: Sat Jul 14 23:54:29 2018 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=3a25c3fa |
7 |
|
8 |
_unmerge_dirs: revisit parents of removed symlinks (bug 640058) |
9 |
|
10 |
When removal of a symlink is triggered by removal of the directory |
11 |
that it points to, revisit the parent directories of the symlink. |
12 |
|
13 |
Bug: https://bugs.gentoo.org/640058 |
14 |
Reviewed-by: Brian Dolbec <dolsen <AT> gentoo.org> |
15 |
|
16 |
pym/portage/dbapi/vartree.py | 25 +++++++++++++++++++++++-- |
17 |
1 file changed, 23 insertions(+), 2 deletions(-) |
18 |
|
19 |
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py |
20 |
index 1a86940f1..a104306eb 100644 |
21 |
--- a/pym/portage/dbapi/vartree.py |
22 |
+++ b/pym/portage/dbapi/vartree.py |
23 |
@@ -2753,9 +2753,13 @@ class dblink(object): |
24 |
real_root = self.settings['ROOT'] |
25 |
|
26 |
dirs = sorted(dirs) |
27 |
- dirs.reverse() |
28 |
+ revisit = {} |
29 |
|
30 |
- for obj, inode_key in dirs: |
31 |
+ while True: |
32 |
+ try: |
33 |
+ obj, inode_key = dirs.pop() |
34 |
+ except IndexError: |
35 |
+ break |
36 |
# Treat any directory named "info" as a candidate here, |
37 |
# since it might have been in INFOPATH previously even |
38 |
# though it may not be there now. |
39 |
@@ -2818,6 +2822,7 @@ class dblink(object): |
40 |
raise |
41 |
if e.errno != errno.ENOENT: |
42 |
show_unmerge("---", unmerge_desc["!empty"], "dir", obj) |
43 |
+ revisit[obj] = inode_key |
44 |
|
45 |
# Since we didn't remove this directory, record the directory |
46 |
# itself for use in syncfs calls, if we have removed another |
47 |
@@ -2838,6 +2843,7 @@ class dblink(object): |
48 |
# no need to protect symlinks that point to it. |
49 |
unmerge_syms = protected_symlinks.pop(inode_key, None) |
50 |
if unmerge_syms is not None: |
51 |
+ parents = [] |
52 |
for relative_path in unmerge_syms: |
53 |
obj = os.path.join(real_root, |
54 |
relative_path.lstrip(os.sep)) |
55 |
@@ -2849,6 +2855,21 @@ class dblink(object): |
56 |
raise |
57 |
del e |
58 |
show_unmerge("!!!", "", "sym", obj) |
59 |
+ else: |
60 |
+ parents.append(os.path.dirname(obj)) |
61 |
+ |
62 |
+ if parents: |
63 |
+ # Revisit parents recursively (bug 640058). |
64 |
+ recursive_parents = [] |
65 |
+ for parent in set(parents): |
66 |
+ while parent in revisit: |
67 |
+ recursive_parents.append(parent) |
68 |
+ parent = os.path.dirname(parent) |
69 |
+ if parent == '/': |
70 |
+ break |
71 |
+ |
72 |
+ for parent in sorted(set(recursive_parents)): |
73 |
+ dirs.append((parent, revisit.pop(parent))) |
74 |
|
75 |
def isowner(self, filename, destroot=None): |
76 |
""" |