fix add overwrite race with git-annex add to annex
This is not a complete fix for all such races, only the one where a large file gets changed while adding and gets added to git rather than to the annex. addLink needs to go away, any caller of it is probably subject to the same kind of race. (Also, addLink itself fails to check gitignore when symlinks are not supported.) ingestAdd no longer checks gitignore. (It didn't check it consistently before either, since there were cases where it did not run git add!) When git-annex import calls it, it's already checked gitignore itself earlier. When git-annex add calls it, it's usually on files found by withFilesNotInGit, which handles checking ignores. There was one other case, when git-annex add --batch calls it. In that case, old git-annex behaved rather badly, it would seem to add the file, but git add would later fail, leaving the file as an unstaged annex symlink. That behavior has also been fixed. Sponsored-by: Brett Eisenberg on Patreon
This commit is contained in:
parent
b471438c51
commit
dd6dec4eb1
5 changed files with 47 additions and 16 deletions
|
@ -145,19 +145,19 @@ checkLockedDownWritePerms file displayfile = checkContentWritePerm file >>= retu
|
|||
|
||||
{- Ingests a locked down file into the annex. Updates the work tree and
|
||||
- index. -}
|
||||
ingestAdd :: CheckGitIgnore -> MeterUpdate -> Maybe LockedDown -> Annex (Maybe Key)
|
||||
ingestAdd ci meterupdate ld = ingestAdd' ci meterupdate ld Nothing
|
||||
ingestAdd :: MeterUpdate -> Maybe LockedDown -> Annex (Maybe Key)
|
||||
ingestAdd meterupdate ld = ingestAdd' meterupdate ld Nothing
|
||||
|
||||
ingestAdd' :: CheckGitIgnore -> MeterUpdate -> Maybe LockedDown -> Maybe Key -> Annex (Maybe Key)
|
||||
ingestAdd' _ _ Nothing _ = return Nothing
|
||||
ingestAdd' ci meterupdate ld@(Just (LockedDown cfg source)) mk = do
|
||||
ingestAdd' :: MeterUpdate -> Maybe LockedDown -> Maybe Key -> Annex (Maybe Key)
|
||||
ingestAdd' _ Nothing _ = return Nothing
|
||||
ingestAdd' meterupdate ld@(Just (LockedDown cfg source)) mk = do
|
||||
(mk', mic) <- ingest meterupdate ld mk
|
||||
case mk' of
|
||||
Nothing -> return Nothing
|
||||
Just k -> do
|
||||
let f = keyFilename source
|
||||
if lockingFile cfg
|
||||
then addLink ci f k mic
|
||||
then addSymlink f k mic
|
||||
else do
|
||||
mode <- liftIO $ catchMaybeIO $
|
||||
fileMode <$> R.getFileStatus (contentLocation source)
|
||||
|
@ -322,6 +322,11 @@ makeLink file key mcache = flip catchNonAsync (restoreFile file key) $ do
|
|||
- and is faster (staging the symlink runs hash-object commands each time).
|
||||
- Also, using git add allows it to skip gitignored files, unless forced
|
||||
- to include them.
|
||||
-
|
||||
- FIXME: Using git add opens a race where the file can be changed
|
||||
- before git adds it, causing a large file to be added directly to git.
|
||||
- addSymlink avoids that, but does not check git ignore. Things need to
|
||||
- be converted to use it, first checking git ignore themselves.
|
||||
-}
|
||||
addLink :: CheckGitIgnore -> RawFilePath -> Key -> Maybe InodeCache -> Annex ()
|
||||
addLink ci file key mcache = ifM (coreSymlinks <$> Annex.getGitConfig)
|
||||
|
@ -330,11 +335,14 @@ addLink ci file key mcache = ifM (coreSymlinks <$> Annex.getGitConfig)
|
|||
ps <- gitAddParams ci
|
||||
Annex.Queue.addCommand [] "add" (ps++[Param "--"])
|
||||
[fromRawFilePath file]
|
||||
, do
|
||||
l <- makeLink file key mcache
|
||||
addAnnexLink l file
|
||||
, addSymlink file key mcache
|
||||
)
|
||||
|
||||
addSymlink :: RawFilePath -> Key -> Maybe InodeCache -> Annex ()
|
||||
addSymlink file key mcache = do
|
||||
l <- makeLink file key mcache
|
||||
addAnnexLink l file
|
||||
|
||||
{- Parameters to pass to git add, forcing addition of ignored files.
|
||||
-
|
||||
- Note that, when git add is being run on an ignored file that is already
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue