aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editors/diff.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/editors/diff.c b/editors/diff.c
index ca4a4eae7..3719bb49f 100644
--- a/editors/diff.c
+++ b/editors/diff.c
@@ -952,6 +952,31 @@ int diff_main(int argc UNUSED_PARAM, char **argv)
if (gotstdin && (S_ISDIR(stb[0].st_mode) || S_ISDIR(stb[1].st_mode)))
bb_error_msg_and_die("can't compare stdin to a directory");
+ /* Compare metadata to check if the files are the same physical file.
+ *
+ * Comment from diffutils source says:
+ * POSIX says that two files are identical if st_ino and st_dev are
+ * the same, but many file systems incorrectly assign the same (device,
+ * inode) pair to two distinct files, including:
+ * GNU/Linux NFS servers that export all local file systems as a
+ * single NFS file system, if a local device number (st_dev) exceeds
+ * 255, or if a local inode number (st_ino) exceeds 16777215.
+ */
+ if (ENABLE_DESKTOP
+ && stb[0].st_ino == stb[1].st_ino
+ && stb[0].st_dev == stb[1].st_dev
+ && stb[0].st_size == stb[1].st_size
+ && stb[0].st_mtime == stb[1].st_mtime
+ && stb[0].st_ctime == stb[1].st_ctime
+ && stb[0].st_mode == stb[1].st_mode
+ && stb[0].st_nlink == stb[1].st_nlink
+ && stb[0].st_uid == stb[1].st_uid
+ && stb[0].st_gid == stb[1].st_gid
+ ) {
+ /* files are physically the same; no need to compare them */
+ return STATUS_SAME;
+ }
+
if (S_ISDIR(stb[0].st_mode) && S_ISDIR(stb[1].st_mode)) {
#if ENABLE_FEATURE_DIFF_DIR
diffdir(file, s_start);