Warum wurde bei `cp -uav` eines Git-Repos für einige Dateien „entfernt“ angezeigt?

Warum wurde bei `cp -uav` eines Git-Repos für einige Dateien „entfernt“ angezeigt?

Früher habe ich cp -uaveine Kopie eines Git-Repos aktualisiert, einschließlich nicht festgeschriebener Dateien.

Warum wird angezeigt, dass Dateien entfernt werden? Es sieht so aus:

$ cp -uav repos copy
removed 'copy/repos/h/.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391'
removed 'copy/repos/h/.git/objects/3b/b3f834dd037db9298b10d71e0cd7383000fa1c'
removed 'copy/repos/h/.git/objects/49/6d6428b9cf92981dc9495211e6e1120fb6f2ba'
removed 'copy/repos/h/.git/objects/2b/bf350cea1fb4fd036235d7e6c36eb600e68885'

$ rpm -q --whatprovides `which cp`
coreutils-8.25-17.fc25.x86_64

Antwort1

Ich kann die obigen Meldungen wie folgt reproduzieren:

mkdir test; cd test
mkdir repos; cd repos

mkdir g; cd g
git init
touch a
git add a
git commit -m test
cd ..

git clone g h
cd ..

mkdir copy
cp -ua repos copy
cp -uav repos copy

Das Ausführen des cp -uaBefehls stracezeigt, dass unlinkdie angegebenen Dateien tatsächlich entfernt werden ().

Was passiert ist, ist, dass die Objekte in repo/h/.git/objectsHardlinks der Objekte in sind repo/g/.git/objects. (In meinem ursprünglichen Fall habe ich ein Repo kopiert, das Unter-Repos enthielt, die ursprünglich als Klone des Haupt-Repos erstellt wurden.)

cp -abedeutet cp --preserve, was dokumentiert ist als

--preserve[=ATTR_LIST]

Behalte die angegebenen Attribute bei (Standard: Modus, Besitz, Zeitstempel), wenn möglich zusätzliche Attribute: Kontext, Links, Xattr, alle

Die Aufhebung der Verknüpfung erfolgt im Rahmen der Hardlink-Erhaltung:

linkat(AT_FDCWD, "copy/repos/g/.git/objects/2b/bf350cea1fb4fd036235d7e6c36eb600e68885", AT_FDCWD, "copy/repos/h/.git/objects/2b/bf350cea1fb4fd036235d7e6c36eb600e68885", 0) = -1 EEXIST (Datei existiert)

Verknüpfung aufheben("copy/repos/h/.git/objects/2b/bf350cea1fb4fd036235d7e6c36eb600e68885") = 0

linkat(AT_FDCWD, "kopiere/repos/g/.git/objects/2b/bf350cea1fb4fd036235d7e6c36eb600e68885", AT_FDCWD, "kopiere/repos/h/.git/objects/2b/bf350cea1fb4fd036235d7e6c36eb600e68885", 0) = 0

Warum genau werden Meldungen generiert, die mich so verwirren?

Es scheint, als ob -u( --update) in diesem Code nicht vollständig implementiert ist. Es handelt sich hauptsächlich um eine Leistungsoptimierung, um unnötiges erneutes Kopieren von Daten zu vermeiden. Für das Erstellen von Hardlinks ist kein Kopieren von Daten erforderlich.

In der Dokumentation sind noch weitere Szenarien zu sehen, in denen cpebenfalls Dateien entfernt werden müssen:

   -f, --force

         if an existing destination file cannot be opened, remove it and try again (this option is ignored when the -n option is also used)

Im Falle von -fkann ich verstehen, dass es möglicherweise die spezifischen Dateien anzeigen möchte, die es „erzwingen“ muss.

Ich denke, es könnte auch nützlich sein, das Löschen anzuzeigen, falls cpes unterbrochen wird. Andernfalls würden Benutzer wahrscheinlich nicht erkennen, dass eine Datei (als Zwischenschritt) vom Ziel gelöscht worden sein könnte.

Die eigentliche Frage ist, warum beim erneuten Erstellen der Links nicht auch eine Meldung angezeigt wurde, was weniger verwirrend wäre. Ich vermute, dass dies eine Eigenart der -uOption ist.

verwandte Informationen