uutils / uutils/coreutils

cp: directory mode is not included by default in --preserve

Open
#11,271 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

U - cp
Dominant language
Rust
Stars
24.1k
Forks
2k
Avg merge
1d 5h
Merged PRs (30d)
365

Description

With cp, the mode on a directory is not being copied unless explicitly cited in --preserve, which is a change in behavior. (I'm reporting this due to: "Differences with GNU are treated as bugs", from the project goals.)

This is related to issue #5125, but my experience is that -a copies the mode.

First, baseline behavior. Note the 755 mode of testdir is copied.

$ ls -ltR /tmp/cp_source
/tmp/cp_source:
total 4
drwxr-xr-x 2 scott scott 4096 Mar  9 22:48 testdir
-rwxr-xr-x 1 scott scott    0 Mar  9 22:47 testfileparent

/tmp/cp_source/testdir:
total 0
-rwxr-xr-x 1 scott scott 0 Mar  9 22:48 testfilechild
$ cp -RP --preserve=ownership,timestamps /tmp/cp_source /tmp/cp_target
$ ls -ltR /tmp/cp_target
/tmp/cp_target:
total 4
drwxr-xr-x 2 scott scott 4096 Mar  9 22:48 testdir
-rwxr-xr-x 1 scott scott    0 Mar  9 22:47 testfileparent

/tmp/cp_target/testdir:
total 0
-rwxr-xr-x 1 scott scott 0 Mar  9 22:48 testfilechild
$ umask
0002
$ which cp
/usr/bin/cp
$ cp --version
cp (GNU coreutils) 9.4
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Torbjörn Granlund, David MacKenzie, and Jim Meyering.

$ grep PRETTY /etc/os-release
PRETTY_NAME="Pop!_OS 24.04 LTS"
$

Next, the differing be behavior. Note the 755 mode of testdir is NOT copied, until "mode" is added to the --preserve list.

$ ls -ltR /tmp/cp_source
/tmp/cp_source:
total 0
drwxr-xr-x 2 scott scott 60 Mar  9 22:48 testdir/
-rwxr-xr-x 1 scott scott  0 Mar  9 22:47 testfileparent

/tmp/cp_source/testdir:
total 0
-rwxr-xr-x 1 scott scott 0 Mar  9 22:48 testfilechild
$ cp -RP --preserve=ownership,timestamps /tmp/cp_source /tmp/cp_target
$ ls -ltR /tmp/cp_target
/tmp/cp_target:
total 0
drwx------ 2 scott scott 60 Mar  9 22:48 testdir/
-rwxr-xr-x 1 scott scott  0 Mar  9 22:47 testfileparent

/tmp/cp_target/testdir:
total 0
-rwxr-xr-x 1 scott scott 0 Mar  9 22:48 testfilechild
$ # But explicitly specifying mode does work:
$ rm -rf /tmp/cp_target
$ cp -RP --preserve=mode,ownership,timestamps /tmp/cp_source /tmp/cp_target
$ ls -ltR /tmp/cp_target
/tmp/cp_target:
total 0
drwxr-xr-x 2 scott scott 60 Mar  9 22:48 testdir/
-rwxr-xr-x 1 scott scott  0 Mar  9 22:47 testfileparent

/tmp/cp_target/testdir:
total 0
-rwxr-xr-x 1 scott scott 0 Mar  9 22:48 testfilechild
$ umask
0002
$ which cp
/usr/bin/cp
$ cp --version
cp (uutils coreutils) 0.6.0
$ grep PRETTY_NAME /etc/os-release
PRETTY_NAME="AerynOS 2026.02"
$

Sorry I can't submit a patch... I'm not a ruster. :-\ Much appreciation for all you do, folks. :-)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating the cp implementation's --preserve handling and directory-copy path, then compare its behavior with GNU cp using the commands and permissions shown in the report. Add a regression test for --preserve=ownership,timestamps and verify that directory modes match GNU cp without explicitly listing mode.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.