fix overwrite race with git-annex add of annex symlink
authorJoey Hess <joeyh@joeyh.name>
Tue, 14 Jun 2022 17:56:17 +0000 (13:56 -0400)
committerJoey Hess <joeyh@joeyh.name>
Tue, 14 Jun 2022 18:00:13 +0000 (14:00 -0400)
In the unlikely case where git-annex add is run on an annex symlink that
is not already added, and while it's processing it, the annex symlink is
overwritten with something else, avoid git-annex overwriting that with
the symlink again.

Sponsored-by: Jack Hill on Patreon
Annex/Ingest.hs
Command/Add.hs

index 7e3cbe25b44ecb4b0b13ae4b9aa2dd50ee3440e8..90b2d6dbef8ee5d66ef26d4bb7442514d6c4d813 100644 (file)
@@ -17,6 +17,7 @@ module Annex.Ingest (
        finishIngestUnlocked,
        cleanOldKeys,
        addLink,
+       addSymlink,
        makeLink,
        addUnlocked,
        CheckGitIgnore(..),
index a453f966901ecc76a5879d3b3f8d392d1c382f03..31c560e4b09529084f3a25628db9fbd0f98b7c3c 100644 (file)
@@ -181,10 +181,19 @@ start o si file addunlockedmatcher = do
                        _ -> add
        fixuplink key = 
                starting "add" (ActionItemTreeFile file) si $
-                       addingExistingLink file key $ do
-                               liftIO $ removeFile (fromRawFilePath file)
-                               addLink (checkGitIgnoreOption o) file key Nothing
-                               next $ cleanup key =<< inAnnex key
+                       addingExistingLink file key $
+                               withOtherTmp $ \tmp -> do
+                                       let tmpf = fromRawFilePath tmp </> fromRawFilePath file
+                                       liftIO $ moveFile (fromRawFilePath file) tmpf
+                                       ifM (isSymbolicLink <$> liftIO (getSymbolicLinkStatus tmpf))
+                                               ( do
+                                                       liftIO $ removeFile tmpf
+                                                       addSymlink file key Nothing
+                                                       next $ cleanup key =<< inAnnex key
+                                               , do
+                                                       liftIO $ moveFile tmpf (fromRawFilePath file)
+                                                       next $ return True
+                                               )
        fixuppointer key =
                starting "add" (ActionItemTreeFile file) si $
                        addingExistingLink file key $ do