resolvemerge: Improve cleanup of cruft left in the working tree by a conflicted...
authorJoey Hess <joeyh@joeyh.name>
Mon, 7 Sep 2020 20:50:27 +0000 (16:50 -0400)
committerJoey Hess <joeyh@joeyh.name>
Mon, 7 Sep 2020 20:50:27 +0000 (16:50 -0400)
This commit was sponsored by Jake Vosloo on Patreon.

Annex/AutoMerge.hs
CHANGELOG
doc/bugs/automerge_leaves_cruft_behind.mdwn

index 3b50ed48d3984ab0cec3c71e02f7d41d1ce9cbb6..cbb4a33f134c610f5087671d659feeeff00c989a 100644 (file)
@@ -38,6 +38,7 @@ import Utility.FileMode
 import qualified Data.Set as S
 import qualified Data.Map as M
 import qualified Data.ByteString.Lazy as L
+import qualified Utility.RawFilePath as R
 
 {- Merges from a branch into the current branch (which may not exist yet),
  - with automatic merge conflict resolution.
@@ -315,7 +316,7 @@ cleanConflictCruft resolvedks resolvedfs unstagedmap = do
        inks = maybe False (flip S.member ks)
        matchesresolved is i f
                | S.member f fs || S.member (conflictCruftBase f) fs = anyM id
-                       [ pure (S.member i is)
+                       [ pure $ either (const False) (`S.member` is) i
                        , inks <$> isAnnexLink (toRawFilePath f)
                        , inks <$> liftIO (isPointerFile (toRawFilePath f))
                        ]
@@ -332,7 +333,7 @@ reuseOldFile :: InodeMap -> Key -> FilePath -> FilePath -> Annex Bool
 reuseOldFile srcmap key origfile destfile = do
        is <- map (inodeCacheToKey Strongly)
                <$> Database.Keys.getInodeCaches key
-       liftIO $ go $ mapMaybe (\i -> M.lookup i srcmap) is
+       liftIO $ go $ mapMaybe (\i -> M.lookup (Right i) srcmap) is
   where
        go [] = return False
        go (f:fs)
@@ -352,15 +353,19 @@ commitResolvedMerge commitmode = inRepo $ Git.Branch.commitCommand commitmode
        , Param "git-annex automatic merge conflict fix"
        ]
 
-type InodeMap = M.Map InodeCacheKey FilePath
+type InodeMap = M.Map (Either FilePath InodeCacheKey) FilePath
 
 inodeMap :: Annex ([RawFilePath], IO Bool) -> Annex InodeMap
 inodeMap getfiles = do
        (fs, cleanup) <- getfiles
        fsis <- forM fs $ \f -> do
-               mi <- withTSDelta (liftIO . genInodeCache f)
-               return $ case mi of
-                       Nothing -> Nothing
-                       Just i -> Just (inodeCacheToKey Strongly i, fromRawFilePath f)
+               s <- liftIO $ R.getSymbolicLinkStatus f
+               let f' = fromRawFilePath f
+               if isSymbolicLink s
+                       then pure $ Just (Left f', f')
+                       else withTSDelta (\d -> liftIO $ toInodeCache d f' s)
+                               >>= return . \case
+                                       Just i -> Just (Right (inodeCacheToKey Strongly i), f')
+                                       Nothing -> Nothing
        void $ liftIO cleanup
        return $ M.fromList $ catMaybes fsis
index 1c493bad4ea2e7a200287c8f294c07fba3db5334..26f2b4ea7149a309f88ec651bf81e1270009ef32 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -31,12 +31,12 @@ git-annex (8.20200815) UNRELEASED; urgency=medium
     behavior that git-annex has had for a long time.
   * Retry transfers to exporttree=yes remotes same as for other remotes.
   * import: Retry downloads that fail, same as is done for downloads generally.
-  * resolvemerge: Improve cleanup of files that were deleted by one side of
-    a conflicted merge, and modified by the other side.
   * sync, assistant, merge: When merge.directoryRenames is not set,
     default it it to "false", which works better with automatic merge
     conflict resolution than git's ususual default of "conflict".
     (This is not done when automatic merge conflict resolution is disabled.)
+  * resolvemerge: Improve cleanup of cruft left in the working tree 
+    by a conflicted merge.
 
  -- Joey Hess <id@joeyh.name>  Fri, 14 Aug 2020 14:57:45 -0400
 
index 8f4daa3861c5f16d8c979b4f364fac311ba92e54..53e4e79670e3931afebd6d5f0d566e231ba49201 100644 (file)
@@ -3,4 +3,13 @@ directory and an annexed file leave behind
 files like `foo~refs_remotes_origin_master`, which are not checked into
 git. 
 
-Also happens with merge.directoryRenames=conflict --[[Joey]]
+Also happens with merge.directoryRenames=conflict
+
+Seems to only happen sometimes, unsure why.. Maybe git doesn't always
+write those files, or sometimes something done with git deletes them?
+
+Root cause seems to be that it's making an InodeCache, but that can't
+be done of a broken symlink. So, it's probably a reversion introduced with
+v7 unlocked files or so.
+
+> [[fixed|done]] --[[Joey]]