From: "Sam James" <sam@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/portage:master commit in: lib/portage/util/, lib/portage/dbapi/
Date: Tue, 23 May 2023 00:26:21 +0000 (UTC) [thread overview]
Message-ID: <1684801329.5572b73744121f67c4e55040966bfe91a0e5fb6c.sam@gentoo> (raw)
commit: 5572b73744121f67c4e55040966bfe91a0e5fb6c
Author: gcarq <egger.m <AT> protonmail <DOT> com>
AuthorDate: Tue Mar 21 16:19:13 2023 +0000
Commit: Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue May 23 00:22:09 2023 +0000
URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=5572b737
mergeme: Consider file mode and xattr for comparison
Implements dblink._needs_move(...) to take care of file equality
checks which consist of file mode, extended attributes and
file content.
Signed-off-by: gcarq <egger.m <AT> protonmail.com>
Signed-off-by: Sam James <sam <AT> gentoo.org>
lib/portage/dbapi/vartree.py | 32 +++++++++++++++++++++++++-------
lib/portage/util/movefile.py | 29 +++++++++++++++++++++++++++++
2 files changed, 54 insertions(+), 7 deletions(-)
diff --git a/lib/portage/dbapi/vartree.py b/lib/portage/dbapi/vartree.py
index 327b72bed..317cf327a 100644
--- a/lib/portage/dbapi/vartree.py
+++ b/lib/portage/dbapi/vartree.py
@@ -3,8 +3,6 @@
__all__ = ["vardbapi", "vartree", "dblink"] + ["write_contents", "tar_contents"]
-import filecmp
-
import portage
portage.proxy.lazyimport.lazyimport(
@@ -34,7 +32,7 @@ portage.proxy.lazyimport.lazyimport(
"portage.util.env_update:env_update",
"portage.util.install_mask:install_mask_dir,InstallMask,_raise_exc",
"portage.util.listdir:dircache,listdir",
- "portage.util.movefile:movefile",
+ "portage.util.movefile:movefile,_cmpxattr",
"portage.util.path:first_existing,iter_parents",
"portage.util.writeable_check:get_ro_checker",
"portage.util._xattr:xattr",
@@ -95,6 +93,7 @@ from ._ContentsCaseSensitivityManager import ContentsCaseSensitivityManager
import argparse
import errno
+import filecmp
import fnmatch
import functools
import gc
@@ -5803,10 +5802,7 @@ class dblink:
# same way. Unless moveme=0 (blocking directory)
if moveme:
# only replace the existing file if it differs, see #722270
- already_merged = os.path.exists(mydest)
- if already_merged and filecmp.cmp(mysrc, mydest, shallow=False):
- zing = "==="
- else:
+ if self._needs_move(mysrc, mydest, mymode, mydmode):
# Create hardlinks only for source files that already exist
# as hardlinks (having identical st_dev and st_ino).
hardlink_key = (mystat.st_dev, mystat.st_ino)
@@ -5829,6 +5825,8 @@ class dblink:
return 1
hardlink_candidates.append(mydest)
zing = ">>>"
+ else:
+ zing = "==="
try:
self._merged_path(mydest, os.lstat(mydest))
@@ -6254,6 +6252,26 @@ class dblink:
finally:
self.unlockdb()
+ def _needs_move(self, mysrc, mydest, mymode, mydmode):
+ """
+ Checks whether the given file at |mysrc| needs to be moved to |mydest| or if
+ they are identical.
+
+ Takes file mode and extended attributes into account.
+ Should only be used for regular files.
+ """
+ if not os.path.exists(mydest):
+ return True
+
+ if mymode != mydmode:
+ return True
+
+ excluded_xattrs = self.settings.get("PORTAGE_XATTR_EXCLUDE", "")
+ if not _cmpxattr(mysrc, mydest, exclude=excluded_xattrs):
+ return True
+
+ return not filecmp.cmp(mysrc, mydest, shallow=False)
+
def merge(
mycat,
diff --git a/lib/portage/util/movefile.py b/lib/portage/util/movefile.py
index d46c56ade..e2f19ba92 100644
--- a/lib/portage/util/movefile.py
+++ b/lib/portage/util/movefile.py
@@ -105,6 +105,35 @@ def _copyxattr(src, dest, exclude=None):
)
+def _cmpxattr(src, dest, exclude=None):
+ """
+ Compares extended attributes between |src| and |dest| and returns True
+ if they are equal or xattrs are not supported, False otherwise
+ """
+ try:
+ src_attrs = xattr.list(src)
+ dest_attrs = xattr.list(dest)
+ except OSError as e:
+ if e.errno != OperationNotSupported.errno:
+ raise
+ return True
+
+ if src_attrs:
+ if exclude is not None and isinstance(src_attrs[0], bytes):
+ exclude = exclude.encode(_encodings["fs"])
+ exclude = _get_xattr_excluder(exclude)
+
+ src_attrs = {attr for attr in src_attrs if not exclude(attr)}
+ dest_attrs = {attr for attr in dest_attrs if not exclude(attr)}
+ if src_attrs != dest_attrs:
+ return False
+
+ for attr in src_attrs:
+ if xattr.get(src, attr) != xattr.get(dest, attr):
+ return False
+ return True
+
+
def movefile(
src,
dest,
next reply other threads:[~2023-05-23 0:26 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-23 0:26 Sam James [this message]
-- strict thread matches above, loose matches on Subject: below --
2020-09-07 22:32 [gentoo-commits] proj/portage:master commit in: lib/portage/util/, lib/portage/dbapi/ Zac Medico
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1684801329.5572b73744121f67c4e55040966bfe91a0e5fb6c.sam@gentoo \
--to=sam@gentoo.org \
--cc=gentoo-commits@lists.gentoo.org \
--cc=gentoo-dev@lists.gentoo.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox