Subject: Re: bug#8419: cp -au : New hard links in source becomes new files at destination when using cp -au

From: Pádraig Brady <[email-masked]>
Date: Tue, 26 Jul 2011 12:39:38 +0100

On 26/07/11 11:07, Jim Meyering wrote:
> Jim Meyering wrote:
>> Pádraig Brady wrote:
>>> On 25/07/11 17:26, Pádraig Brady wrote:
>>>> Actually I'm wondering now whether the new code
>>>> should be unconditionally replacing the dest?
>>>> What if the dest is a separate newer file?
>>>> I.E. I think the following amended test should pass?
>>>> Also what about backups if the separate file is older?
>>>
>>> Well backups take a different path, as do
>>> older or non existing destination paths.
>>> So how about this change to just remove
>>> the new create_hard_link: call and beef up the test?
>>
>> Hi Pádraig,
>>
>> The link-creation code there cannot be removed.
>> Consider this scenario:
>>
>>   src/{a,b}  # a and b are linked
>>   dst/src/a
>>
>> If cp -au encounters src/a first, then the new "remember_copied"
>> call records the required info so when it encounters src/b it can
>> make the desired link from the preexisting dst/src/a to dst/src/b.
>> In that case, the link-creation code is indeed unnecessary.
>>
>> However, what if it encounters src/b first?
>> In that case, it must copy src/b to dst/src/b (new inode!)
>> Then, when it encounters src/a, it must *remove* the preexisting dst/src/a
> 
> This "must" is my interpretation that --preserve=link (implied
> by -a and -p) has a higher priority than the --update (-u) option.

That's a bit surprising, thought understandable I think.
If the separate file in the dest is newer it will be replaced
by an older link from the source.  That could legitimately happen
I suppose if the original copy was with -rp, then the timestamps
would be newer than those in dest.
I'll update the test to enforce the replacement of newer files in dest

>> and replace it with a hard link to dst/src/b.
>> As an alternative, cp could conceivably remove the just-copied dst/src/b,
>> replacing it with a hard-link to dst/src/a.
>>
>> The trouble I have with all of this is that we can see two different
>> outcomes, depending on the order in which "a" and "b" (in the src
>> directory) are processed by cp.  In one case, the preexisting and
>> up-to-date dst/src/a is not modified.  In the other, it is removed,
>> and replaced by a hard-link to potentially-differing-content "dst/src/b".

TBH I don't understand all the implications.
Note the `touch` commands in the test operate on the separate inodes in dest.
Note also your original test didn't fail for me on ext4 on F15.

cheers,
Pádraig.