public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
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,


             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