為什麼 git 儲存庫的「cp -uav」某些檔案顯示「已刪除」?

為什麼 git 儲存庫的「cp -uav」某些檔案顯示「已刪除」?

我曾經cp -uav更新 git 儲存庫的副本,包括未提交的文件。

為什麼說它正在刪除檔案?它看起來像這樣:

$ 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

答案1

我可以按如下方式重現上述訊息:

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

運行cp -ua下面的命令strace將顯示它確實正在刪除 ( unlink) 它所說的檔案。

發生的情況是 中的物件repo/h/.git/objects是 中的物件的硬連結repo/g/.git/objects。 (在我原來的情況下,我正在複製一個包含子存儲庫的存儲庫,這些子存儲庫最初是作為主存儲庫的克隆創建的)。

cp -a意味著cp --preserve,記錄為

--preserve[=ATTR_LIST]

保留指定的屬性(預設:模式、所有權、時間戳記),如果可能的話附加屬性:上下文、連結、xattr、全部

取消連結作為硬連結保留的一部分發生:

。 85 ", 0) = -1 EEXIST(檔案存在)

取消連結(「複製/儲存庫/h/.git/objects/2b/bf350cea1fb4fd036235d7e6c36eb600e68885」)= 0

。 85 ”, 0) = 0

至於為什麼它會產生令我如此困惑的訊息?

這段程式碼中似乎-u( ) 沒有完全實現。--update它主要是效能優化,以避免不必要的重新複製資料。製作硬連結不需要複製任何資料。

我們可以在文件中看到其他cp也必須刪除文件的場景:

   -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)

在這種情況下-f,我可以理解它可能想顯示它必須“強制”的特定文件。

我想,如果被中斷的話,顯示刪除也可能很有用cp。否則,使用者不太可能意識到檔案可能已從目標中刪除(作為中間步驟)。

最終的問題是,為什麼它在重新建立連結時沒有顯示訊息,這樣就不會那麼混亂了。我懷疑這是該-u選項的一個怪癖。

相關內容